[
  {
    "path": ".gitignore",
    "content": "# Vim\n*.swp\n\n# Latoex files\n*.pdf\n*.aux\n*.bib\n*.bbl\n*.blg\n*.ent\n*.log\n*.run.xml\n*.synctex.gz\n\n# Object files\ncdf\ntags\n*.o\n*.ko\n*.obj\n*.elf\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Libraries\n*.lib\n*.a\n*.la\n*.lo\n\n# Shared objects (inc. Windows DLLs)\n*.dll\n*.so\n*.so.*\n*.dylib\n\n# Executables\n*.exe\n*.out\n*.app\n*.i*86\n*.x86_64\n*.hex\n\n# Debug files\n*.dSYM/\n*.pyc\n*__pycache__\n\n# Log files\nlog.txt\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    {one line to give the program's name and a brief idea of what it does.}\n    Copyright (C) {year}  {name of author}\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    {project}  Copyright (C) {year}  {fullname}\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>."
  },
  {
    "path": "README.md",
    "content": "# CDF – crypto differential fuzzing\n\nCDF is a tool to automatically test the correctness and security of cryptographic\nsoftware.  CDF can detect implementation errors, compliance failures,\nside-channel leaks, and so on.\n\nCDF implements a combination of unit tests with \"differential fuzzing\", an\napproach that compares the behavior of different implementations of the same\nprimitives when fed edge cases and values maximizing the code coverage.\n\nUnlike general-purpose fuzzers and testing software, CDF is:\n\n* **Smart**: CDF knows what kind of algorithm it's testing and adapts to the\n  tested functions\n\n* **Fast**: CDF tests only what needs to be tested and parallelizes its tests as\n  much as possible\n\n* **Polyvalent**: CDF isn't specific to any language or API, but supports\n  arbitrary executable programs or scripts\n\n* **Portable**: CDF will run on any Unix or Windows platform, since it is\n  written in Go without any platform-specific dependency\n\nThe purpose of CDF is to provide more efficient testing tool to developers and\nsecurity researchers, being more effective than test vectors and cheaper than\nmanual audit of formal verification.\n\nCDF was first presented at Black Hat USA 2017. You can view the [slides](https://www.blackhat.com/docs/us-17/wednesday/us-17-Aumasson-Automated-Testing-Of-Crypto-Software-Using-Differential-Fuzzing.pdf) of our presentation, which contain general information about the rationale behind and the design of CDF.\n\n# Requirements\n\nCDF is coded in [Go](https://golang.org/), the current version has been\ndeveloped using Go 1.8.  It has no dependencies outside of Go's [standard\nlibrary](https://golang.org/pkg/#stdlib).\n\nHowever, we provide example programs to be tested using CDF, which are\nin C, Python, C++, Java and Go and require specific crypto libraries to be run.\nCurrently required libraries are:\n - [CryptoPP](https://www.cryptopp.com/)\n - [OpenSSL](https://www.openssl.org/)\n - [BouncyCastle](https://www.bouncycastle.org/)\n - [PyCrypto](https://launchpad.net/pycrypto/)\n - [Cryptography.io](https://cryptography.io/)\n\n\n# Build\n\n`make` will build the `cdf` binary.\n\nA bunch of example programs are available under [example](examples/): `make examples-all` will build all the examples, while `make examples-go` will only build the Go examples.\n\n`make test` will run unit tests (of CDF).\n\n# Usage\n\nFor starters you may want to view usage info by running `cdf -h`.\n\nYou may then try an example such as the [`rsaenc`](#rsaenc-rsa-encryption-oaep-or-pkcs-15)\ninterface against the RSA OAEP Go and CryptoPP examples. Viewing CryptoPP as\nour reference, you can test the Go implementation by doing:  \n```\ncdf rsaenc /examples/oaep_rsa2048_go /examples/oaep_rsa2048_cryptopp\n```   \nThis command will perform various tests specific to the `rsaenc` interface. \n\nIn this example, CDF should complain about the maximum public exponent size the Go implementation support: if we\ncheck [its code](https://golang.org/src/crypto/rsa/rsa.go#L42) we can see the\npublic exponent is being stored as a normal integer, whereas in CryptoPP (and\nmost other implementations), it is stored as a big integer.  This\nis however [by design](https://www.imperialviolet.org/2012/03/16/rsae.html) and\nwill likely not be changed. \n\nParameters are defined in [config.json](config.json).\nMost parameters are self-explanatory. You may want to set others private\nkeys for `rsaenc` and `ecdsa` (these interfaces are tested with fixed keys, although some key parameters, such as the exponents, are changed in some of the tests).\n\nThe `seed` parameter lets you change the seed used in CDF's pseudo-random\ngenerators. (Yet, the tested program may be using some PRNG seeded otherwise,\nlike the OAEP examples.) The `concurrency` parameter lets you set the number\nof concurrent goroutine CDF should be spawning when forking the programs. Note\nthat it is best to keep this number below the real number of cores.  The\n`verboseLog` parameter, if set to `true`, will write all programs' inputs and\noutputs, even for the succesful tests, to a file log.txt.\n\n\n# Interfaces\n\nIn order to test your software using CDF, you have to create a program that reads input and writes output in conformance with CDF interfaces, and that internally calls the tested program.\nCDF interfaces are abstractions of a crypto functionality, in order to allow black-box testing of arbitrary implementations.\n\nFor example, if you implemented the ECDSA signature scheme, your program should satisfies the [`ecdsa`\ninterface](#ecdsa-ecdsa-signatures) and as such take as inputs 4 or 5 arguments,\nrespectively in order to sign a message or verify a signature. These arguments are the public X coordinate, the public Y coordinate, the private D big integer and the message you want to sign and then it should output only the big integers R and S each on a newline. Or, to verify a message, it should accept X,Y, the R, the S and the message and then it should only output True or False. The interfaces' specifications are detailled [below](#interfaces).\n\nOur [examples](#examples) of interface implementations will help you create your owns.\n\nError handling is left to the tested program, however to have meaningful errors in CDF it is best to exit on failure, return a error code and print an error message.\n\nThe interface program can be written in any language, it just needs to be an executable file conformant with a CDF interface.\nAn interface program is typically written in the same language as the tested program, but that's not mandatory (it may be a wrapper in another language, for example for Java programs).\n\nCDF currently supports the following interfaces, wherein parameters are encoded as hexadecimal ASCII strings, unless described otherwise:\n\n## dsa\n\nThe dsa interface tests implementations of the [Digital Signature Algorithm](https://en.wikipedia.org/wiki/Digital_Signature_Algorithm) (DSA). It must support the signature and verification operations:\n\n|Operation    |Input          |Output         |\n|-------------|---------------|---------------|\n|Signature    |`p q g y x m`  | `r s`         |\n|Verification |`p q g y r s m`| `truth value` |\n\nHere p, q, g are DSA parameters, y is a public key, x is a private key, m is a message, r and s form the signature, which must returned separated by a newline. The truth value, either “true” or “false”, is represented as a string.\n\nThe dsa interface supports an optional test: the`-h` allows to bypass the hashing process and directly\nprovide the hash value to be signed. This allows CDF to perform more tests, such as checking for overflows or hash truncation. \n\n## ecdsa\n\nThe ecdsa interface tests implementations of the [Elliptic Curve Digital Signature Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) (ECDSA). It must support the signature and verification operations:\n\n|Operation      |Input |Output|\n|-------------|---------------|---------------|\n|Signature    |`x y d m`      | `r s`         |\n|Verification |`x y r s m`    | `truth value` |\n\nHere x and y are a public ECDSA key coordinates, d is a private key, m is a message, and r and s form the signature, which must be returned separated by a newline. The truth value, either “true” or “false”, is represented by a string.\n\nThe flag `-h` serves the same purpose as with dsa.\n\nPlease note that our current design assumes a fixed curve, defined in the tested program.\n\nTo obtain reproducible results with those tests and leverage all of CDF detection's abilities, you have to either seed you random generator with a fixed seed or use a deterministic ECDSA variant, otherwise CDF can't detect problems such as same tags issues automatically.\n\n## enc\n\nThe enc interface tests symmetric encryption and decryption operations, typically when performed with a block cipher (stream ciphers can be tested with the prf interface). It must support encryption and decryption:\n\n|Operation|Input |Output|\n|-------------|---------------|---------------|\n|Encryption   |`k m`          | `c`           |\n|Decryption   |`k c`          | `r`           |\n\nHere k is a key, m is a message, c is a ciphertext c and r is a recovered plaintext.\n\n## prf\n\nThe prf interface tests keyed hashing (pseudorandom functions, MACs), as well as stream ciphers:\n\n|Operation|Input |Output|\n|-------------|---------------|---------------|\n|Computation  |`k m`          | `h`           |\n\nHere k is a key, m is a message (or nonce in case of a stream cipher), and h is the result of the PRF computation. Our interface assumes fixed key size and variable input lengths. If a specific key is to be specified, it is the responsibility of the tested program to ignore the key input or the xof interface may be a better choice.\n\n## rsaenc\n\nThe rsaenc tests [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) encryption and decryption, both [OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding) (PKCS 2.1) and PKCS 1.5:\n\n|Operation|Input |Output|\n|-------------|---------------|---------------|\n|Encryption   |`n e m`        | `c`           |\n|Decryption   |`p q e d c`    | `r`           |\n\nHere n is a modulus, e is a public exponent (for compatibility with certain libraries, e is also needed for decryption), m is a message m, p and q are n's factor (such that p > q, since libraries commonly require it), d is a private exponent, and r is a recovered plaintext.\n\n## xof\n\nThe xof interface tests hash functions, extendable-output functions (XOFs), deterministic random bit generators (DRBGs):\n\n|Operation|Input |Output|\n|-------------|---------------|---------------|\n|Computation  |`m`            | `h`           |\n\nHere m is the message and h is the result h.\n\n# Authors\n\nCDF is based on initial ideas by [JP Aumasson](https://github.com/veorq), first disclosed at [WarCon 2016](http://warcon.pl/2016/), and most of the code was written by [Yolan Romailler](https://github.com/anomalroil).\n\n# Intellectual property\n\nCDF is copyright (c) 2016-2017 Nagravision SA, all rights reserved.\n\nCDF is released under GPLv3.\n\n"
  },
  {
    "path": "cdf-lib/dsa.go",
    "content": "package cdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// TestDsa implements the tests relying on the cdf interface for DSA signature and verification scheme\nfunc TestDsa() error {\n\tLogInfo.Print(\"testing dsa\")\n\n\tfailed := false\n\t// Testing Message length\n\tif err := testDsaMsgLen(); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing messages lengths:\", err)\n\t} else {\n\t\tLogSuccess.Println(\"message lengths tested without error.\")\n\t}\n\n\tif *TestHashes { // test only if the -h flag is supported\n\t\tif err := testDsaHashLen(); err != nil {\n\t\t\tfailed = true\n\t\t\tLogError.Println(\"while testing hash lengths:\", err)\n\t\t} else {\n\t\t\tLogSuccess.Println(\"hash lengths tested without error.\")\n\t\t}\n\t}\n\n\t// Testing special cases\n\tif err := testDsaCases(); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing special cases:\", err)\n\t} else {\n\t\tLogSuccess.Println(\"special cases tested without error.\")\n\t}\n\n\tif limit := *TestTimings; limit > 0 {\n\t\tdudectTest(limit, Prog1, doOneComputationForDsa, prepareInputsForDsa)\n\t\tdudectTest(limit, Prog2, doOneComputationForDsa, prepareInputsForDsa)\n\t}\n\n\tif failed {\n\t\tfmt.Print(\"\\n\")\n\t\treturn errors.New(\"one of more tests failed\")\n\t}\n\n\treturn nil\n}\n\n// testDsaMsgLen is simply calling the testDsaConsistency function on\n//  the full range from MinMsgLen to MaxMsgLen, on a randomly generated message\n//  (relying on the seed set in Config.json)\nfunc testDsaMsgLen() (mainErr error) {\n\tTermPrepareFor(1)\n\t// generate random chars in the hex range to try and sign those\n\tmsg := randomHex(Config.MaxMsgLen)\n\n\tLogInfo.Println(\"testing different message's lengths, from \", Config.MinMsgLen, \"to\", Config.MaxMsgLen, \"bytes\")\n\targsP1 := []string{Config.DsaP, Config.DsaQ, Config.DsaG, Config.DsaY, Config.DsaX}\n\targsP2 := []string{Config.DsaP, Config.DsaQ, Config.DsaG, Config.DsaY}\n\tmainErr = testDsaConsistency(msg, argsP1, argsP2, 0)\n\treturn\n}\n\n// testDsaHashLen attempt to test the Dsa process using different hash\n// lengths, notably bigger hash than the group size. This test will be more\n// useful in the deterministic Dsa case, since we can compare its output against\n// the other one to catch no-same tags cases (i.e hash lengths' handling problems\n// leading to wrong truncation of the hash, typically)\nfunc testDsaHashLen() error {\n\tTermPrepareFor(1)\n\tvar mainErr MultiError\n\thasSame := false\n\n\tmsg := randomHex(Config.MaxMsgLen)\n\n\tLogInfo.Println(\"testing different hash's lengths over \")\n\ttoTest := make(map[string]int)\n\tTermPrepareFor(3)\n\t// we should add a setting maybe to have the hash range to test?\n\tfor i := 1; i < Config.MaxMsgLen; i++ {\n\t\tid := \"dsa#buf#\" + strconv.Itoa(i)\n\t\tTermDisplay(3, \"%d / %d \\n\", i+1, Config.MaxMsgLen)\n\n\t\targsP2 := []string{\"-h\", msg[:i*2], Config.DsaP, Config.DsaQ, Config.DsaG, Config.DsaY}\n\t\targsP1 := append(argsP2, Config.DsaX)\n\t\tif err := testDsaConsistency(msg, argsP1, argsP2, 1); err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tout, err := runProg(Prog1, id, append(argsP1, msg))\n\t\tif err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Then we check if the tag is the same as a previous one, since it\n\t\t// should never be the case.\n\t\t// Note that this is more useful in the deterministic DSA case than\n\t\t// in general.\n\t\tif toTest[out] > 0 {\n\t\t\thasSame = true\n\t\t\tmainErr = append(mainErr, fmt.Errorf(\"Same tag as with buff %d with len %d on job %s. \",\n\t\t\t\ttoTest[out], i, id))\n\t\t}\n\t\ttoTest[out] = i\n\t}\n\tif len(mainErr) > 0 {\n\t\tif hasSame {\n\t\t\tmainErr = append(mainErr, fmt.Errorf(\"Note that same tags are expected if you are using DSA deterministic as per RFC6979. If you are not, then this is a problem.\"))\n\t\t}\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\n// testDsaConsistency just tests the DSA signature on different message\n// lengths for the given msg, starting from MinMsgLen and for at most maxIter\n// iterations or reaches the value MaxMsgLen set in the Config.json file\nfunc testDsaConsistency(msg string, argsP1, argsP2 []string, maxIter int) error {\n\tLogInfo.Println(\"testing dsa consistency\")\n\tnbIter := maxIter + Config.MinMsgLen\n\tif nbIter >= Config.MaxMsgLen || maxIter <= 0 {\n\t\tnbIter = Config.MaxMsgLen + 1\n\t}\n\tif len(msg) < nbIter {\n\t\tlog.Fatalln(\"The message provided is not big enough to be processed\")\n\t}\n\n\t// Initializing a common, unbuffered, channel which gives tasks to\n\t// the worker goroutines.\n\tmsgs := make(chan string)\n\terrs := make(chan error, nbIter)\n\t// Spawn some worker goroutines\n\tvar wg sync.WaitGroup\n\tfor j := uint(0); j < Config.Concurrency; j++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tfor m := range msgs {\n\t\t\t\tid := \"dsa#\" + strconv.Itoa(len(m))\n\t\t\t\t// We cannot use argsP1, we have to create a copy,\n\t\t\t\t// to keep argsP1 unchanged\n\t\t\t\targsP1T := append(argsP1, m)\n\n\t\t\t\t// We run the first program:\n\t\t\t\tout1 := runOrExitOnErr(Prog1, id, argsP1T...)\n\n\t\t\t\tout1Arr := strings.Split(out1, \"\\n\")\n\t\t\t\t// it is necessary to trim again after splitting to remove the CR\n\t\t\t\trOut := strings.TrimSpace(out1Arr[0])\n\t\t\t\tsOut := strings.TrimSpace(out1Arr[1])\n\n\t\t\t\targsP2T := append(argsP2, rOut, sOut, m)\n\t\t\t\t// we run the second program:\n\t\t\t\toutStr2 := runOrExitOnErr(Prog2, id, argsP2T...)\n\n\t\t\t\tif trueStr != outStr2 {\n\t\t\t\t\tfmt.Print(\"\\n\")\n\t\t\t\t\tLogWarning.Printf(\"verification failed on length %d\", len(m))\n\t\t\t\t\tfmt.Print(\"\\n\")\n\t\t\t\t\tLogError.Println(strings.Join(append(\n\t\t\t\t\t\t[]string{\"failed to run on length \", strconv.Itoa(len(m)),\n\t\t\t\t\t\t\t\" \", Prog2}, argsP2T...), \" \"))\n\t\t\t\t\tLogError.Println(append([]string{\"After running:\", Prog1},\n\t\t\t\t\t\targsP1T...))\n\t\t\t\t\tfmt.Print(\"\\n\\n\")\n\t\t\t\t\terrs <- fmt.Errorf(\"verification error on length %d\", len(m))\n\t\t\t\t}\n\t\t\t}\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\t// There we could argue that the MinMsgLen should always be 1 byte.\n\t// We ignore the Config.MsgIncrement since we are testing each byte-length\n\tfor i := Config.MinMsgLen; i < nbIter; i++ {\n\t\tTermPrintInline(1, \"%d / %d\", i-Config.MinMsgLen+1, nbIter-Config.MinMsgLen)\n\t\t// we populate our channel:\n\t\tmsgs <- msg[:i*2]\n\t}\n\n\tclose(msgs)\n\t// let us wait for our workers to finish\n\twg.Wait()\n\n\tif len(errs) > 0 {\n\t\t// Initializing the return value\n\t\tvar mainErr MultiError\n\t\tfirstErr := true\n\t\tfor len(errs) > 0 {\n\t\t\te := <-errs\n\t\t\tif firstErr {\n\t\t\t\tfirstErr = false\n\t\t\t\t// This is not guaranteed to be the 1st one, but almost\n\t\t\t\tLogInfo.Println(\"First error:\", e)\n\t\t\t}\n\t\t\tmainErr = append(mainErr, e)\n\t\t}\n\t\tTermPrepareFor(1)\n\t\treturn mainErr\n\t}\n\tTermPrepareFor(1)\n\treturn nil\n}\n\n// testDSACases is responsible for running the different tests for edge cases\n// for DSA. We currently test against 0 inputs, against 1 inputs and other\n// degenerated cases. Note that this function is simply a bundle of functions\n// which could have been directly added to the main TestDsa one.\nfunc testDsaCases() error {\n\tTermPrepareFor(1)\n\tvar mainErr MultiError\n\t// firstly we'll test both program against the 0 values\n\tif err := testDsaZeros(Prog1); err != nil {\n\t\t//LogWarning.Println(err)\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tif err := testDsaZeros(Prog2); err != nil {\n\t\t//LogWarning.Println(err)\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tTermPrepareFor(1)\n\tif err := testDsaOnes(Prog1); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tif err := testDsaOnes(Prog2); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tTermPrepareFor(1)\n\t// next, we test the verification against the (0, s) and the (r, 0) signatures\n\tif err := testDsaZeroSign(Prog1); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tif err := testDsaZeroSign(Prog2); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tTermPrepareFor(1)\n\n\tif err := testDsaZeroHash(Prog1); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tif err := testDsaZeroHash(Prog2); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tTermPrepareFor(1)\n\tif len(mainErr) > 0 {\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\n// testDsaOnes is a test to sign using the 01 values as a public parameters\n// as well as the 01 integer as a private key. This should not be accepted\n// by the tested programs, since it means they do not perform correct domain\n// parameters checks on their input. Typically it can lead to signature\n// independent of the actual message, with r=01.\nfunc testDsaOnes(prog string) error {\n\tLogInfo.Printf(\"testing %s against the 01 parameters.\\n\", prog)\n\tvar mainErr MultiError\n\n\t// we take the MinMsgLen since we don't need a big value, we just need any value\n\tmsg := randomHex(Config.MinMsgLen)\n\n\targsP := []string{Config.DsaP, Config.DsaQ, Config.DsaG, Config.DsaY, Config.DsaX, msg}\n\tvar tmp string\n\tfor i := 0; i < 3; i++ {\n\t\tid := \"dsa#pts#01-\" + fmt.Sprint(i) + \"_\" + prog\n\t\ttmp, argsP[i] = argsP[i], \"01\"\n\t\tout, err := runProg(prog, id, argsP)\n\t\targsP[i] = tmp\n\t\tif err != nil {\n\t\t\tif strings.Contains(err.Error(), \"STOP\") {\n\t\t\t\tmainErr = append(mainErr, err)\n\t\t\t\tLogWarning.Println(prog, \"timed out using 01 as argument \", i+1, \"it may indicate an infinite loop.\")\n\t\t\t} else {\n\t\t\t\tLogToFile.Println(\"As expected,\", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\t\t\tLogSuccess.Println(prog, \"refused to sign using 01 at arg \", i+1)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tLogWarning.Println(prog, \"signed using 01 without error at \", i+1)\n\t\tmainErr = append(mainErr, fmt.Errorf(\"%s let us sign using 01, without error at %d:\\n%s\",\n\t\t\tprog, i+1, out))\n\t}\n\n\tif len(mainErr) > 0 {\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\n// testDsaZeros is a simple trial to sign using the 0 values as a public key as well\n// well as the 00 integer as a private key. This can lead to infinite loops, which\n// would then trigger the timeout in runProg. This means that the tested program\n// does not perform proper parameters checks on its inputs.\nfunc testDsaZeros(prog string) error {\n\tLogInfo.Printf(\"testing %s against the 00 parameters.\\n\", prog)\n\tvar mainErr MultiError\n\n\t// we take the MinMsgLen since we don't need a big value, we just need any value\n\tmsg := randomHex(Config.MinMsgLen)\n\n\targsP := []string{Config.DsaP, Config.DsaQ, Config.DsaG, Config.DsaY, Config.DsaX, msg}\n\tvar tmp string\n\tfor i := 0; i < 5; i++ {\n\t\tid := \"dsa#pts#0-\" + fmt.Sprint(i) + \"_\" + prog\n\t\tif i == 3 { // we don't care about Y when testing the signature process\n\t\t\ti++\n\t\t}\n\t\ttmp, argsP[i] = argsP[i], \"00\"\n\t\tout, err := runProg(prog, id, argsP)\n\t\targsP[i] = tmp\n\t\tif err != nil {\n\t\t\tif strings.Contains(err.Error(), \"STOP\") {\n\t\t\t\tmainErr = append(mainErr, err)\n\t\t\t\tLogWarning.Println(prog, \" timed out using 00 as argument \", i+1, \"it may indicate an infinite loop.\")\n\t\t\t} else {\n\t\t\t\tLogToFile.Println(\"As expected,\", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\t\t\tLogSuccess.Println(prog, \" refused to sign using 00 at arg \", i+1)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tLogWarning.Println(prog, \" signed using 00 without error at \", i+1)\n\t\tmainErr = append(mainErr, fmt.Errorf(\"%s let us sign using 00, without error at %d\", prog, i+1))\n\t}\n\n\tif len(mainErr) > 0 {\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\n// pair is simply a struct to allow to write the following test in a nicer way.\ntype pair struct {\n\ta string\n\tb string\n}\n\n// testDsaZeroSign is a test to verify invalid signatures, typically the 00\n// 01 and q values should be rejected as not in the proper range for r and s.\n// Failure to do so can lead to always true signatures, independently of the\n// message, which is a security concern if it is easily triggered.\nfunc testDsaZeroSign(prog string) error {\n\tLogInfo.Printf(\"testing %s against the null signatures.\\n\", prog)\n\tid := \"dsa#rs#0-0_\" + prog\n\targsP := []string{Config.DsaP, Config.DsaQ, Config.DsaG, Config.DsaY, \"00\", \"00\", \"434343\"}\n\tlist := []pair{pair{\"00\", \"00\"}, pair{\"01\", \"00\"}, pair{\"00\", \"01\"},\n\t\tpair{\"01\", Config.DsaQ}} // This may trigger a faulty true answer\n\n\tfor _, p := range list {\n\t\targsP[4] = p.a\n\t\targsP[5] = p.b\n\t\tout, err := runProg(prog, id, argsP)\n\t\tif err != nil {\n\t\t\tLogToFile.Println(\"As expected, \", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\t\tLogSuccess.Println(prog, \"rejected r=\", p.a, \", s=\", p.b, \" with an error.\")\n\t\t\tcontinue\n\t\t}\n\t\tif out == \"true\" {\n\t\t\treturn fmt.Errorf(\"%s validated a 0 signature\", prog)\n\t\t}\n\t\tLogInfo.Println(prog, \"rejected r=\", p.a, \", s=\", p.b, \" without error.\")\n\t}\n\n\treturn nil\n}\n\n// testDsaZeroHash is a simple trial to verify using a wrong 00 hash and\n//  using 01 as x, r and s to fool the standard DSA verification into validation\n//  Note that the point (0,0) note that this should never validate, it's not even\n//  on the curve in most possible cases (the y coordinate being free, it may be).\nfunc testDsaZeroHash(prog string) error {\n\tLogInfo.Printf(\"testing %s against the 00 hash.\\n\", prog)\n\t// The point 0,0 shouldn't be accepted as a valid point, so let us try with it:\n\tid := \"dsa#hash#00_\" + prog\n\n\targsP := []string{\"-h\", \"00\", \"01\", \"42\", \"01\", \"01\", \"434343\"}\n\tout, err := runProg(prog, id, argsP)\n\tif err != nil {\n\t\tLogToFile.Println(\"As expected,\", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\tLogSuccess.Println(prog, \"didn't accept this degenerated case, or you did not implement the -h flag.\")\n\t\treturn nil\n\t}\n\tif out == trueStr {\n\t\tLogError.Println(prog, \"accepted the degenerated -h 00 case.\")\n\t\treturn fmt.Errorf(\"%s accepted the degenerated -h 00 case\", prog)\n\t}\n\treturn fmt.Errorf(\"%s refused the degenerated -h 00 case without error\", prog)\n}\n\n// doOneComputationForDsa allows to use the dudect test with this interface.\nfunc doOneComputationForDsa(prog string) func(string) {\n\treturn func(data string) {\n\t\trecovered, err := runProg(prog, \"dudect-\"+prog,\n\t\t\t[]string{Config.DsaP, Config.DsaQ, Config.DsaG, Config.DsaY, Config.DsaX, data})\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"Error:%v \\n leading to: %s\", err, recovered))\n\t\t}\n\t}\n}\n\n// prepareInputsForDsa generates inputs to test timings leak, for DSA this test\n// simply test two message against each other and could benefit from more interesting.\nfunc prepareInputsForDsa() (inputData []string, classes []int) {\n\tinputData = make([]string, numberMeasurements)\n\tclasses = make([]int, numberMeasurements)\n\trn := rand.New(rand.NewSource(time.Now().UnixNano()))\n\t// we generate two different message and we simply try with them:\n\tdata := randomHex(20)\n\tdata2 := randomHex(20)\n\tfor i := 0; i < numberMeasurements; i++ {\n\t\tclasses[i] = rn.Intn(2)\n\t\tif classes[i] == 0 {\n\t\t\tinputData[i] = data\n\t\t} else {\n\t\t\tinputData[i] = data2\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "cdf-lib/dsa_test.go",
    "content": "package cdf\n\nimport (\n\t\"crypto/dsa\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"hash\"\n\t\"log\"\n\t\"math/big\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestTestDSA(t *testing.T) {\n\tinitForTesting(\"DSA\")\n\tConfig.Timeout = 1\n\tt.Run(\"testDsaMsgLen\", func(*testing.T) {\n\t\terr := testDsaMsgLen()\n\t\tif err != nil {\n\t\t\tt.Error(\"Expected nil, got \", err)\n\t\t}\n\t})\n\tt.Run(\"testDsaCases\", func(*testing.T) {\n\t\terr := testDsaCases()\n\t\t// as of Go 1.7.4, the DSA function had two bugs we detect:\n\t\t/*expErr := MultiError{fmt.Errorf(\" accepts 00 input for the keys\"),\n\t\t\t\t\t\tfmt.Errorf(\" accepts 00 input for the keys\")}\n\t\tand it signs using 1 as a generator too.*/\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"The testDsaCases returned without error! We expect it to fail as of Go version 1.8.\")\n\t\t}\n\t\t// as of Go 1.8, it does not fall in an infinite loop anymore since they corrected the bug we reported.\n\t\tif !strings.Contains(err.Error(), \"(2 errors)\") &&\n\t\t\tstrings.Count(err.Error(), \"0000000000000000000000000000000000000001\") == 2 {\n\t\t\tt.Errorf(\"Expected 2 signatures with r=01, got\\n%v\", err)\n\t\t}\n\t})\n\tif execCounter != 28 {\n\t\tt.Error(\"Expected 28 executions, got \", execCounter)\n\t}\n}\n\nfunc ExampleDSA(args []string) {\n\t// The hash used\n\tvar h hash.Hash\n\th = sha256.New()\n\n\tvar signing bool\n\n\targs = args[1:]\n\tfor a := range args {\n\t\tif len(args[a])%2 != 0 {\n\t\t\tlog.Println(\"one argument has an odd size\")\n\t\t\tos.Exit(2)\n\t\t}\n\t}\n\n\tswitch {\n\tcase len(args) == 7:\n\t\tsigning = false\n\tcase len(args) == 6:\n\t\tsigning = true\n\tdefault:\n\t\tlog.Fatal(\"Please provide P, Q, G, Y, X, Msg or P, Q, G, Y, R, S, Msg as arguments in order to respectively sign Msg or verify a signature for Msg.\")\n\t}\n\n\t// Key instanciation\n\tprivatekey := new(dsa.PrivateKey)\n\tpubkey := new(dsa.PublicKey)\n\n\tpubkey.P = fromBase16(args[0])\n\tpubkey.Q = fromBase16(args[1])\n\tpubkey.G = fromBase16(args[2])\n\tpubkey.Y = fromBase16(args[3])\n\t// we need the byte length of the subgroup to comply to FIPS 186-3 sec. 4.6\n\t//  recommended truncation.\n\thlen := (pubkey.Q.BitLen() + 7) / 8\n\n\t// msg is always in latest position\n\t// we are decoding from hex to have truly random messages\n\tmsg, err := hex.DecodeString(args[(len(args) - 1)])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tr := big.NewInt(0)\n\ts := big.NewInt(0)\n\n\t// We handle the hashing of the data:\n\th.Write(msg)\n\tvar signhash []byte\n\tsignhash = h.Sum(nil)\n\n\tif signing {\n\t\t// private key instanciation:\n\t\tprivatekey.PublicKey = *pubkey\n\t\tprivatekey.X = fromBase16(args[4])\n\n\t\t// If signhash is longer than the byte-length of the subgroup, it should\n\t\t//  be truncated to that length as per FIPS 186-3 sec. 4.6, but Sign does\n\t\t//  not handle this directly. It returns the signature as a pair of big integers.\n\t\tr, s, serr := dsa.Sign(rand.Reader, privatekey, signhash[:hlen])\n\t\tif serr != nil {\n\t\t\tfmt.Println(serr)\n\t\t\tos.Exit(1)\n\t\t}\n\n\t\t// We first output R, then S with a newline in between as required by\n\t\t//  the ECDSA interface\n\t\tanswerR := leftPadText(r.Text(16), 20)\n\t\tanswerS := leftPadText(s.Text(16), 20)\n\t\tfmt.Printf(\"%s\\n%s\\n\", answerR, answerS)\n\t} else {\n\t\t// if we are not signing, we are verifying :\n\t\tr = fromBase16(args[4])\n\t\ts = fromBase16(args[5])\n\t\tverifystatus := dsa.Verify(pubkey, signhash[:hlen], r, s)\n\t\tfmt.Println(verifystatus)\n\t}\n}\n\n// leftPadText will ensure the string are in hexadecimal form and satisfy with the\n//  DSA signature length of 160bits.\nfunc leftPadText(text string, size int) string {\n\tn := len(text)\n\tsize = 2 * size\n\tif n > size {\n\t\tn = size\n\t}\n\treturn strings.Repeat(\"0\", size-n) + text\n}\n"
  },
  {
    "path": "cdf-lib/dudect.go",
    "content": "// All credit goes to Oscar Reparaz, Josep Balasch and Ingrid Verbauwhede for dudect's ideas and design\n\npackage cdf\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"math\"\n\t\"time\"\n)\n\ntype tCtx struct {\n\tmean [2]float64\n\tm2   [2]float64\n\tn    [2]float64\n}\n\nvar (\n\tnumberMeasurements = 3000\n\tenoughMeasurements = float64(3000) // may be handled by the Go benchmark package later\n)\n\nconst tThresholdBananas = 500 // test failed, with overwhelming probability\nconst tThresholdModerate = 5  // here we could also take 4.5 e.g.\n\nconst numberPercentiles = 100\nconst numberTests = 1 + numberPercentiles + 1 // we perform 1\n\nvar dudectStop bool\nvar enough int\nvar percentiles [numberPercentiles]int64\nvar tests [numberTests]tCtx\n\n// preparePercentiles computes the percentiles to use for the tests later\nfunc preparePercentiles(ticks []int64) {\n\tfor i := 0; i < numberPercentiles; i++ {\n\t\tpercentiles[i] = percentile(\n\t\t\tticks, 1-(math.Pow(0.5, float64(10*(i+1))/float64(numberPercentiles))))\n\t}\n}\n\n// measure times the execution of the provided doOneComputation on the\n//  provided inputDatas\nfunc measure(inputDatas []string, doOneComputation func(string)) (execTimes []int64) {\n\tticks := make([]int64, numberMeasurements+1)\n\tfor i := 0; i < numberMeasurements; i++ {\n\t\tticks[i] = time.Now().UnixNano()\n\t\tdoOneComputation(inputDatas[i])\n\t}\n\n\tticks[numberMeasurements] = time.Now().UnixNano()\n\texecTimes = make([]int64, numberMeasurements)\n\tfor i := 0; i < numberMeasurements; i++ {\n\t\texecTimes[i] = ticks[i+1] - ticks[i]\n\t}\n\treturn\n}\n\n// updateStatistics will udpate each t-test we are storing, ie. the test on\n//  all data, the tests on each percentiles, and the second order test.\nfunc updateStatistics(execTimes []int64, classes []int) {\n\n\tfor i := 0; i < numberMeasurements; i++ {\n\t\tdifference := execTimes[i]\n\t\tif difference < 0 {\n\t\t\tcontinue // the cpu cycle counter overflowed\n\t\t}\n\n\t\t// do a t-test on the execution time\n\t\ttPush(&tests[0], float64(difference), classes[i])\n\n\t\t// do a t-test on cropped execution times, for several cropping thresholds.\n\t\tfor cropIndex := 0; cropIndex < numberPercentiles; cropIndex++ {\n\t\t\tif difference < percentiles[cropIndex] {\n\t\t\t\ttPush(&tests[cropIndex+1], float64(difference), classes[i])\n\t\t\t}\n\t\t}\n\n\t\t// do a second-order test (only if we have more than 10000 measurements).\n\t\t// Centered product pre-processing.\n\t\tif tests[0].n[0] > 10000 {\n\t\t\tcentered := float64(difference) - tests[0].mean[classes[i]]\n\t\t\ttPush(&tests[1+numberPercentiles], centered*centered, classes[i])\n\t\t}\n\t}\n}\n\n// tPush will add the value x to the t context in the provided class and update\n//  its context values\nfunc tPush(ctx *tCtx, x float64, class int) {\n\tif !(class == 0 || class == 1) {\n\t\tlog.Fatalln(\"Error, wrong class in tPush\")\n\t}\n\tctx.n[class]++\n\t// Welford method for computing online variance\n\t// in a numerically stable way.\n\t// see Knuth Vol 2\n\tvar delta float64\n\tdelta = x - ctx.mean[class]\n\t// so we have a/n +(x-a/n)/(n+1) = ((n+1)a + nx-a)/(n(n+1)) = (a+x)/(n+1)\n\tctx.mean[class] += delta / ctx.n[class]\n\tctx.m2[class] += delta * (x - ctx.mean[class])\n\t// the algorithm is finalized in tCompute\n}\n\n// tCompute performs the computation to give the t-value used by our t-test\nfunc tCompute(ctx *tCtx) float64 {\n\tvars := [2]float64{0.0, 0.0}\n\tvar den, tValue, num float64\n\n\t// we divide by n-1 since to finalize the variance computation.\n\tvars[0] = ctx.m2[0] / (ctx.n[0] - 1)\n\tvars[1] = ctx.m2[1] / (ctx.n[1] - 1)\n\tnum = (ctx.mean[0] - ctx.mean[1])\n\tden = math.Sqrt(vars[0]/ctx.n[0] + vars[1]/ctx.n[1])\n\ttValue = num / den\n\n\treturn tValue\n}\n\n// maxTest returns the index of the test with the greateast t-value\nfunc maxTest() int {\n\tret := 0\n\tvar max float64\n\tmax = 0.0\n\tfor i := 0; i < numberTests; i++ {\n\t\tif tests[i].n[0] > enoughMeasurements {\n\t\t\tvar x float64\n\t\t\tx = math.Abs(tCompute(&tests[i]))\n\t\t\tif max < x {\n\t\t\t\tmax = x\n\t\t\t\tret = i\n\t\t\t}\n\t\t}\n\t}\n\treturn ret\n}\n\n// report is in charge of printing the data related to the dudect test.\nfunc report() string {\n\n\tvar res string\n\n\tmt := maxTest()\n\tmaxT := math.Abs(tCompute(&tests[mt]))\n\tnumberTracesMaxT := tests[mt].n[0] + tests[mt].n[1]\n\tmaxTau := maxT / math.Sqrt(numberTracesMaxT)\n\n\tif numberTracesMaxT < enoughMeasurements {\n\t\treturn fmt.Sprintf(\"not enough measurements (%.0f still to go).\\n\",\n\t\t\tenoughMeasurements-numberTracesMaxT)\n\t}\n\n\t/*\n\t* maxT: the t statistic value\n\t* maxTau: a t value normalized by sqrt(number of measurements).\n\t*          this way we can compare maxTau taken with different\n\t*          number of measurements. This is sort of \"distance\n\t*          between distributions\", independent of number of\n\t*          measurements.\n\t* (5/tau)^2: how many measurements we would need to barely\n\t*            detect the leak, if present. \"barely detect the\n\t*            leak\" = have a t value greater than 5.\n\t */\n\tres = fmt.Sprintf(\"meas: %7.2f M, max t(%d): %+7.2f, max tau: %.2e, (5/tau)^2: %.2e. m.time (ms):%7.2f\",\n\t\t(numberTracesMaxT / 1e6),\n\t\tmt, maxT,\n\t\tmaxTau,\n\t\tfloat64(5*5)/(maxTau*maxTau),\n\t\ttests[0].mean[0]/float64(1e6))\n\n\tif maxT > tThresholdBananas {\n\t\tLogWarning.Printf(\" Definitely not constant time.\\n\")\n\t\tdudectStop = true\n\t\treturn res\n\t}\n\tif maxT > tThresholdModerate {\n\t\tLogWarning.Printf(\" Probably not constant time.\\n\")\n\t\tenough++\n\t\tif enough > 5 {\n\t\t\t// let us stop before reaching the limit if we have 5 consecutive hints\n\t\t\tLogWarning.Printf(\" Stopping for now. You may want to investigate this further.\\n\")\n\t\t\tdudectStop = true\n\t\t}\n\t\treturn res\n\t} else {\n\t\tLogInfo.Printf(\" For the moment, maybe constant time.\\n\")\n\t\tenough = 0\n\t\treturn res\n\t}\n}\n\n// dudectTest is a function which will allow one to perform a constant time\n//  test on the provided doOneComputation function using the data provided\n//  by prepare_input and which will tell, using a t-test whether it seems to\n//  be timing discrepancies between the two class of inputs or not.\nfunc dudectTest(limit int, progName string, doOneComputation func(string) func(string), prepareInputs func() (inputData []string, classes []int)) {\n\tLogInfo.Println(\"dudect constant time test starting for\", progName)\n\tTermView.Println(\"Preparing input...\")\n\tTermPrepareFor(1)\n\tvar countD int\n\n\t// we need to reset our global variables:\n\tdudectStop = false\n\tpercentiles = [numberPercentiles]int64{}\n\ttests = [numberTests]tCtx{}\n\tfor !dudectStop {\n\t\tcountD++\n\t\tinputData, classes := prepareInputs()\n\t\texecTimes := measure(inputData, doOneComputation(progName))\n\n\t\t// on the very first run, let's compute the rough esitmate of the percentiles:\n\t\tif percentiles[numberPercentiles-1] == 0 {\n\t\t\tpreparePercentiles(execTimes)\n\t\t}\n\t\tupdateStatistics(execTimes, classes)\n\t\tTermPrintInline(2, \"%d / %d : %s\", countD, limit,\n\t\t\treport())\n\n\t\tif countD >= limit {\n\t\t\tdudectStop = true\n\t\t}\n\t}\n\tTermPrepareFor(2)\n\n}\n"
  },
  {
    "path": "cdf-lib/ecdsa.go",
    "content": "package cdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// TestEcdsa implements the cdf interface for ECDSA signature and verification scheme\nfunc TestEcdsa() error {\n\tLogInfo.Print(\"testing ecdsa\")\n\n\tfailed := false\n\t// Testing Message length\n\tif err := testEcdsaMsgLen(); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing messages lengths:\", err)\n\t} else {\n\t\tLogSuccess.Println(\"message lengths tested without error.\")\n\t}\n\n\t// Testing hash length\n\tif *TestHashes { // test only if the -h flag is supported\n\t\tif err := testEcdsaHashLen(); err != nil {\n\t\t\tfailed = true\n\t\t\tLogError.Println(\"while testing hash lengths:\", err)\n\t\t} else {\n\t\t\tLogSuccess.Println(\"hash lengths tested without error.\")\n\t\t}\n\t}\n\n\t// Testing specific point\n\tif err := testEcdsaPoints(); err != nil {\n\t\tfailed = true\n\t\t//LogError.Println(\"while testing specific edge cases:\", err)\n\t}\n\n\tif failed {\n\t\tfmt.Print(\"\\n\")\n\t\treturn errors.New(\"one of more tests failed\")\n\t}\n\n\treturn nil\n}\n\n// testEcdsaMsgLen is simply calling the testEcdsaConsistency function on\n//  the full range from MinMsgLen to MaxMsgLen, on a randomly generated message\n//  (relying on the seed set in Config.json)\nfunc testEcdsaMsgLen() (mainErr error) {\n\tTermPrepareFor(1)\n\t// generate random chars in the hex range to try and sign those\n\tmsg := randomHex(Config.MaxMsgLen)\n\n\tLogInfo.Println(\"testing different message's lengths, from \", Config.MinMsgLen, \"to\", Config.MaxMsgLen, \"bytes\")\n\targsP1 := []string{Config.EcdsaX, Config.EcdsaY, Config.EcdsaD}\n\targsP2 := []string{Config.EcdsaX, Config.EcdsaY}\n\tmainErr = testEcdsaConsistency(msg, argsP1, argsP2, 0)\n\treturn\n}\n\n// testEcdsaHashLen attempt to test the Ecdsa process using different hash\n//  lengths, notably bigger hash than the group size. This test will be more\n//  useful in the deterministic Ecdsa case, since we can compare its output against\n//  the other one to catch no-same tags cases (i.e hash lengths' handling problems\n//  leading to wrong truncation of the hash, typically)\nfunc testEcdsaHashLen() error {\n\tvar first int\n\tTermPrepareFor(1)\n\tvar mainErr MultiError\n\thasSame := false\n\n\tmsg := randomHex(Config.MaxMsgLen)\n\n\tLogInfo.Println(\"testing different hash's lengths\")\n\ttoTest := make(map[string]int)\n\tTermPrepareFor(3)\n\t// we should add a setting maybe to have the hash range to test?\n\ttemp := Config.MinMsgLen\n\tfor i := 1; i < Config.MaxMsgLen/2; i++ {\n\t\tid := \"ecdsa#buf#\" + strconv.Itoa(i)\n\t\tTermDisplay(3, \"%d / %d \\n\", i+1, Config.MaxMsgLen/2)\n\n\t\tConfig.MinMsgLen = i * 2\n\t\targsP2 := []string{\"-h\", msg[:i*2], Config.EcdsaX, Config.EcdsaY}\n\t\targsP1 := append(argsP2, Config.EcdsaD)\n\t\tLogToFile.Println(\"About to run testEcdsaConsistency for HashLen test\")\n\t\tif err := testEcdsaConsistency(msg[:i*2], argsP1, argsP2, 1); err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t\tcontinue\n\t\t}\n\t\tLogToFile.Println(\"Finished to run testEcdsaConsistency:\", mainErr)\n\n\t\tout, err := runProg(Prog1, id, append(argsP1, msg[:i*2]))\n\t\tif err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Then we check if the tag is the same as a previous one, since it\n\t\t//  should never be the case.\n\t\t// Note that this is more useful in the deterministic ECDSA case than\n\t\t//  in general.\n\t\tif toTest[out] > 0 {\n\t\t\thasSame = true\n\t\t\tmainErr = append(mainErr, fmt.Errorf(\"Same tag as with buff %d with len %d on job %s. \",\n\t\t\t\ttoTest[out], i, id))\n\t\t\tif first == 0 {\n\t\t\t\tfirst = i\n\t\t\t}\n\t\t}\n\t\ttoTest[out] = i\n\t}\n\tConfig.MinMsgLen = temp\n\tif len(mainErr) > 0 {\n\t\tif hasSame {\n\t\t\tmainErr = append(mainErr, fmt.Errorf(\"Note that same tags are expected if you are using ECDSA deterministic as per RFC6979. If you are not, then this is a problem. First problem encountered with size %d\", first))\n\t\t}\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\n// testEcdsaConsistency just tests the ECDSA signature on different message\n//  lengths for the given msg, starting from MinMsgLen and for at most maxIter\n//  iterations or reaches the value MaxMsgLen set in the Config.json file\nfunc testEcdsaConsistency(msg string, argsP1, argsP2 []string, maxIter int) (mainErr error) {\n\tLogInfo.Println(\"testing ecdsa consistency\")\n\tnbIter := maxIter\n\tif nbIter+Config.MinMsgLen >= Config.MaxMsgLen || maxIter <= 0 {\n\t\tnbIter = (Config.MaxMsgLen-Config.MinMsgLen)/2 + 1\n\t}\n\tif len(msg)/2 < nbIter || len(msg) < Config.MinMsgLen {\n\t\tlog.Fatalln(\"The message provided is not big enough to be processed\")\n\t}\n\n\t// Initializing a common, unbuffered, channel which gives tasks to\n\t//  the worker goroutines.\n\tmsgs := make(chan string)\n\terrs := make(chan error, nbIter)\n\t// Spawn some worker goroutines\n\tvar wg sync.WaitGroup\n\tfor j := uint(0); j < Config.Concurrency; j++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tfor m := range msgs {\n\t\t\t\tid := \"ecdsa#\" + strconv.Itoa(len(m))\n\t\t\t\t// We cannot use argsP1, we have to create a copy,\n\t\t\t\t//  to keep argsP1 unchanged\n\t\t\t\targsP1T := append(argsP1, m)\n\n\t\t\t\t// We run the first program:\n\t\t\t\tout1 := runOrExitOnErr(Prog1, id, argsP1T...)\n\n\t\t\t\tout1Arr := strings.Split(out1, \"\\n\")\n\n\t\t\t\t//fmt.Println(\"\\nGot:\", out1)\n\t\t\t\t// it is necessary to trim again after splitting to remove the CR\n\t\t\t\trOut := strings.TrimSpace(out1Arr[0])\n\t\t\t\tsOut := strings.TrimSpace(out1Arr[1])\n\n\t\t\t\targsP2T := append(argsP2, rOut, sOut, m)\n\t\t\t\t// we run the second program:\n\t\t\t\toutStr2 := runOrExitOnErr(Prog2, id, argsP2T...)\n\n\t\t\t\tif trueStr != outStr2 {\n\t\t\t\t\tfmt.Print(\"\\n\")\n\t\t\t\t\tLogWarning.Printf(\"verification failed on length %d\", len(m))\n\t\t\t\t\tfmt.Print(\"\\n\")\n\t\t\t\t\tLogError.Println(strings.Join(append(\n\t\t\t\t\t\t[]string{\"failed to run on length \", strconv.Itoa(len(m)),\n\t\t\t\t\t\t\t\" \", Prog2}, argsP2T...), \" \"))\n\t\t\t\t\tLogError.Println(append([]string{\"After running:\", Prog1},\n\t\t\t\t\t\targsP1T...))\n\t\t\t\t\tLogWarning.Println(argsP2T[:len(argsP1T)-1])\n\t\t\t\t\tTermPrepareFor(4)\n\t\t\t\t\terrs <- fmt.Errorf(\"verification error on job %s and length %d\", id, len(m))\n\t\t\t\t}\n\t\t\t}\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\t// There we could argue that the MinMsgLen should always be 1 byte.\n\t// We ignore the Config.MsgIncrement since we are testing each byte-length\n\tfor i := Config.MinMsgLen; i < nbIter*2+Config.MinMsgLen; i += 2 {\n\t\tTermPrintInline(1, \"%d / %d\", (i-Config.MinMsgLen)/2+1, nbIter)\n\t\t// we populate our channel:\n\t\tmsgs <- msg[:i]\n\t}\n\tclose(msgs)\n\t// let us wait for our workers to finish\n\twg.Wait()\n\n\tif len(errs) > 0 {\n\t\t// Initializing the return value\n\t\tvar mainErr MultiError\n\t\tfirstErr := true\n\t\tfor len(errs) > 0 {\n\t\t\te := <-errs\n\t\t\tif firstErr {\n\t\t\t\tfirstErr = false\n\t\t\t\t// This is not guaranteed to be the 1st one, but almost\n\t\t\t\tLogInfo.Println(\"First error:\", e)\n\t\t\t}\n\t\t\tmainErr = append(mainErr, e)\n\t\t}\n\t\tTermPrepareFor(1)\n\t\treturn mainErr\n\t}\n\tTermPrepareFor(1)\n\treturn nil\n}\n\nfunc testEcdsaPoints() error {\n\tTermPrepareFor(1)\n\tvar mainErr MultiError\n\t// firstly we'll test both program against the 0,0 coordinate:\n\tif err := testEcdsaZeroPoint(Prog1); err != nil {\n\t\t//LogWarning.Println(err)\n\t\tmainErr = append(mainErr,\n\t\t\tfmt.Errorf(\"%s accepts the (0,0) coordinate and 0 as private integer:\\n%v\", Prog1, err))\n\t}\n\n\tif err := testEcdsaZeroPoint(Prog2); err != nil {\n\t\t//LogWarning.Println(err)\n\t\tmainErr = append(mainErr,\n\t\t\tfmt.Errorf(\"%s accepts the (0,0) coordinate and 0 as private integer:\\n%v\", Prog2, err))\n\t}\n\n\tTermPrepareFor(1)\n\t// next, we test the verification against the 0, s and the r, 0 signatures\n\tif err := testEcdsaZeroSign(Prog1); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tif err := testEcdsaZeroSign(Prog2); err != nil {\n\t\tmainErr = append(mainErr, err)\n\t}\n\n\tTermPrepareFor(1)\n\n\tif *TestHashes {\n\t\tif err := testEcdsaZeroHash(Prog1); err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t}\n\n\t\tif err := testEcdsaZeroHash(Prog2); err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t}\n\t\tTermPrepareFor(1)\n\n\t\tif err := testInfiniteLoop(Prog1); err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t}\n\n\t\tif err := testInfiniteLoop(Prog2); err != nil {\n\t\t\tmainErr = append(mainErr, err)\n\t\t}\n\t}\n\n\tTermPrepareFor(1)\n\tif len(mainErr) > 0 {\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\n// testEcdsaZeroPoint is a simple trial to sign using the 0,0 coordinate as a key\n//  and the 0 integer as a private key. Note that the point (0,0) is never on a curve\n//  in short Weierstrass form with a non-zero b parameter.\nfunc testEcdsaZeroPoint(prog string) error {\n\tLogInfo.Printf(\"testing %s against the 0,0 coordinate.\\n\", prog)\n\t// The point 0,0 shouldn't be accepted as a valid point, so let us try with it:\n\tid := \"ecdsa#pts#0-0_\" + prog\n\tmsg := randomHex(Config.MinMsgLen)\n\n\targsP := []string{\"00\", \"00\", \"00\", msg}\n\tout, err := runProg(prog, id, argsP)\n\tif err != nil {\n\t\tLogToFile.Println(\"As expected,\", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\tLogSuccess.Println(prog, \" refused to sign using (0,0) and 0 as private key.\")\n\t\treturn nil\n\t}\n\tLogWarning.Println(prog, \" signed using (0,0) and 0 as private key without error.\")\n\treturn fmt.Errorf(\"\\tit returned:\\n%s,\\n\\ton message %s\", out, msg)\n}\n\nfunc testEcdsaZeroSign(prog string) error {\n\tLogInfo.Printf(\"testing %s against the null signatures.\\n\", prog)\n\tid := \"ecdsa#rs#0-0_\" + prog\n\targsP := []string{Config.EcdsaX, Config.EcdsaY, \"00\", \"00\", \"434343\"}\n\tlist := []string{\"00\", \"01\"}\n\n\tfor _, a := range list {\n\t\tfor _, b := range list {\n\t\t\tif a == \"01\" && b == \"01\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\targsP[2] = a\n\t\t\targsP[3] = b\n\t\t\tout, err := runProg(prog, id, argsP)\n\t\t\tif err != nil {\n\t\t\t\tLogToFile.Println(\"As expected, \", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\t\t\tLogSuccess.Println(prog, \"rejected r=\", a, \", s=\", b, \" with an error.\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif out == trueStr {\n\t\t\t\treturn fmt.Errorf(\"%s validated the invalid signature:\\nr=%s,\\ns=%s\", prog, a, b)\n\t\t\t}\n\t\t\tLogInfo.Println(prog, \"rejected r=\", a, \", s=\", b, \" without error.\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// testEcdsaZeroHash is a simple trial to verify using a wrong 00 hash and\n//  using otherwise valid values as x, y, r and s to fool the standard ECDSA\n//  verification into validation\nfunc testEcdsaZeroHash(prog string) error {\n\tLogInfo.Printf(\"testing %s against the 00 hash.\\n\", prog)\n\t// The point 0,0 shouldn't be accepted as a valid point, so let us try with it:\n\tid := \"ecdsa#hash#00_\" + prog\n\n\targsP := []string{\"-h\", \"00\", Config.EcdsaX, Config.EcdsaY, Config.EcdsaX, Config.EcdsaX, \"DEADC0DE\"}\n\tout, err := runProg(prog, id, argsP)\n\tif err != nil {\n\t\tLogToFile.Println(\"As expected,\", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\tLogSuccess.Println(prog, \"didn't accept this degenerated case.\")\n\t\treturn nil\n\t}\n\tif out == trueStr {\n\t\tLogError.Println(prog, \"accepted the degenerated -h 00 case.\")\n\t\treturn fmt.Errorf(\"%s accepted the degenerated -h 00 case\", prog)\n\t}\n\treturn fmt.Errorf(\"%s refused the degenerated -h 00 case without error\", prog)\n}\n\n// testInfiniteLoop is a simple trial to verify using a wrong 00 hash and\n//  using 00 as secret value that the implementation does not fall into an\n//  infinite loop. Note that 00 is not amongst the range of the acceptable\n//  secret values.\nfunc testInfiniteLoop(prog string) error {\n\tLogInfo.Printf(\"testing %s against the invalid inf loop.\\n\", prog)\n\t// The point 0,0 shouldn't be accepted as a valid point, so let us try with it:\n\tid := \"ecdsa#infloop_\" + prog\n\n\targsP := []string{\"-h\", \"00\", Config.EcdsaX, Config.EcdsaY, \"00\", \"DEADC0DE\"}\n\tout, err := runProg(prog, id, argsP)\n\tif err != nil && strings.Contains(err.Error(), \"STOP\") {\n\t\tLogError.Println(prog, \"failed and run into an infinite loop.\")\n\t\treturn fmt.Errorf(\"%s runned into a degenerate infinite loop: %v\", prog, err)\n\t} else if err != nil {\n\t\tLogToFile.Println(\"As expected,\", id, \"failed:\", out, \"\\nGot error:\", err)\n\t\tLogSuccess.Println(prog, \"did not run into an infinite loop.\")\n\t\treturn nil\n\t}\n\tLogToFile.Println(\"Unexpected,\", id, \"did not fail and output:\", out, \"\\non input:\", prog, argsP)\n\tLogWarning.Println(prog, \"didn't run into an infinite loop, but did not fail when running:\\n\", prog, argsP)\n\treturn nil\n}\n"
  },
  {
    "path": "cdf-lib/ecdsa_test.go",
    "content": "package cdf\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"flag\"\n\t\"fmt\"\n\t\"hash\"\n\t\"math/big\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestTestECDSA(t *testing.T) {\n\tinitForTesting(\"ECDSA\")\n\tConfig.Timeout = 1\n\tt.Run(\"testEcdsaMsgLen\", func(*testing.T) {\n\t\terr := testEcdsaMsgLen()\n\t\tif err != nil {\n\t\t\tt.Error(\"Expected nil, got \", err)\n\t\t}\n\t})\n\tt.Run(\"testEcdsaPoints\", func(*testing.T) {\n\t\terr := testEcdsaPoints()\n\t\t// as of Go 1.7.4, the ECDSA function has a bug we detect:\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"The testEcdsaPoints returned without error! We expect it to fail with 2 errors.\")\n\t\t}\n\t\tif !strings.Contains(err.Error(), \"(2 errors)\") &&\n\t\t\tstrings.Count(err.Error(), \"accepts the (0,0)\") != 2 {\n\t\t\tt.Errorf(\"Expected 2 errors, got\\n%v\", err)\n\t\t}\n\t})\n\tif execCounter != 12 {\n\t\tt.Error(\"Expected 12 executions, got \", execCounter)\n\t}\n}\n\nfunc ExampleECDSA(args []string) {\n\tLogToFile.Println(\"Starting ExampleECDSA\")\n\t// In this example, the args[] begins with an empty value when doing tests\n\tflag.Parse()\n\t// The curve used and the hash used\n\tpubkeyCurve := elliptic.P256()\n\tvar h hash.Hash\n\th = sha256.New()\n\n\tvar signing bool\n\n\tLogToFile.Println(\"Args:\", flag.Args())\n\n\tswitch {\n\tcase len(flag.Args()) == 6:\n\t\tsigning = false\n\tcase len(flag.Args()) == 5:\n\t\tsigning = true\n\tdefault:\n\t\tLogToFile.Fatal(\"Please provide X, Y, Sign or X, Y, D, Msg as arguments\")\n\t}\n\t// Key instanciation\n\tprivatekey := new(ecdsa.PrivateKey)\n\tpubkey := new(ecdsa.PublicKey)\n\n\tpubkey.Curve = pubkeyCurve\n\tpubkey.X = fromBase16(flag.Arg(1))\n\tpubkey.Y = fromBase16(flag.Arg(2))\n\n\t// msg is always in latest position\n\t// we are decoding from hex to have truly random messages\n\tmsg, err := hex.DecodeString(flag.Arg(len(flag.Args()) - 1))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tr := big.NewInt(0)\n\ts := big.NewInt(0)\n\n\th.Write(msg)\n\tvar signhash []byte\n\tsignhash = h.Sum(nil)\n\n\tif signing {\n\t\t// private key instanciation:\n\t\tprivatekey.PublicKey = *pubkey\n\t\tprivatekey.D = fromBase16(flag.Arg(3))\n\n\t\t// If signhash is longer than the bit-length of the private key's curve\n\t\t// order, signhash will be truncated to that length. It returns the\n\t\t// signature as a pair of big integers.\n\t\tr, s, serr := ecdsa.Sign(rand.Reader, privatekey, signhash)\n\t\tif serr != nil {\n\t\t\tLogToFile.Fatalln(serr)\n\t\t}\n\n\t\t// we first output R, then S with a newline in between as required by\n\t\t// the ECDSA interface. TODO: check if it needs leftpadding or not.\n\t\tfmt.Printf(\"%s\\n%s\\n\", r.Text(16), s.Text(16))\n\t\tLogToFile.Printf(\"%s\\n%s\\n\", r.Text(16), s.Text(16))\n\t} else {\n\t\t// if we are not signing, we are verifying :\n\t\tr = fromBase16(flag.Arg(3))\n\t\ts = fromBase16(flag.Arg(4))\n\t\tverifystatus := ecdsa.Verify(pubkey, signhash, r, s)\n\t\tfmt.Println(verifystatus)\n\t\tLogToFile.Println(verifystatus)\n\t}\n\tLogToFile.Println(\"Finished ExampleECDSA\")\n}\n"
  },
  {
    "path": "cdf-lib/enc.go",
    "content": "package cdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\tmrand \"math/rand\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n)\n\n// TestEnc implements the CDF interface for symmetric encryption and decryption\n// schemes.\nfunc TestEnc() error {\n\tLogInfo.Print(\"testing enc\")\n\n\tfailed := false\n\n\t// to warn if the used Config won't cover the whole range\n\tif (Config.MaxKeyLen-Config.MinKeyLen)%Config.IncrementKey != 0 {\n\t\tLogWarning.Println(\"It seems like the incrementKey and the maxKeyLen values don't fit well together\")\n\t}\n\tif (Config.MaxMsgLen-Config.MinMsgLen)%Config.IncrementMsg != 0 {\n\t\tLogWarning.Println(\"It seems like the incrementMsg and the maxMsgLen values don't fit well together\")\n\t}\n\n\tmsg := randomHex(Config.MaxMsgLen)\n\tkey := randomHex(Config.MaxKeyLen)\n\n\t// key length to use in msg test\n\tkeyAvgNibbles := 2 * Config.MinKeyLen\n\t// msg length to use in key test\n\tmsgAvgNibbles := 2 * ((Config.MaxMsgLen + Config.MinMsgLen) / 2)\n\n\t// Let us call the message length test\n\terr := testMessLen(key[:keyAvgNibbles], msg)\n\tif err != nil {\n\t\tfailed = true\n\t}\n\n\t// Let us call the key length test\n\terr = testKeyLen(key, msg[:msgAvgNibbles])\n\tif err != nil {\n\t\tfailed = true\n\t}\n\n\tif limit := *TestTimings; limit > 0 {\n\t\tdudectTest(limit, Prog1, doOneComputationForEnc, prepareInutsForEnc)\n\t\tdudectTest(limit, Prog2, doOneComputationForEnc, prepareInutsForEnc)\n\t}\n\tif failed {\n\t\tfmt.Print(\"\\n\")\n\t\treturn errors.New(\"one of more tests failed\")\n\t}\n\n\treturn nil\n}\n\n// testKeyLen tests the programs with different key lengths\nfunc testKeyLen(key string, msg string) (mainErr error) {\n\tTermPrepareFor(1)\n\tLogInfo.Println(\"testing key lengths\")\n\n\tif len(key) < 2*Config.MaxKeyLen {\n\t\tLogError.Println(\"the provided key and MaxKeyLen setting are not compatible\")\n\t\treturn fmt.Errorf(\"key length and settings mismatch\")\n\t}\n\treturn testProgs(msg, chooseKeys, loopKeyLen(key))\n}\n\n// testMessLen tests the programs with different message lengths\nfunc testMessLen(key string, msg string) (mainErr error) {\n\tTermPrepareFor(1)\n\tLogInfo.Println(\"testing message lengths\")\n\treturn testProgs(key, chooseMsg, loopMessLen(msg))\n}\n\n// loopMessLen is the loop wich is to be used for the testProgs function in\n//  the message length case\nfunc loopMessLen(msg string) func(chan string) {\n\treturn func(msgs chan string) {\n\t\tTermPrepareFor(1)\n\t\tfor i := Config.MinMsgLen; i <= Config.MaxMsgLen; i += Config.IncrementMsg {\n\t\t\tTermPrintInline(1, \"%d / %d\", i, Config.MaxMsgLen)\n\t\t\t// get the first i bytes, ie first i*2 nibbles\n\t\t\tmsgs <- msg[:(i * 2)]\n\t\t}\n\t}\n}\n\n// loopKeyLen is the loop wich is to be used for the testProgs function in\n//  the key length case\nfunc loopKeyLen(key string) func(chan string) {\n\treturn func(keys chan string) {\n\t\tTermPrepareFor(1)\n\t\tfor i := Config.MinKeyLen; i <= Config.MaxKeyLen; i += Config.IncrementKey {\n\t\t\tTermPrintInline(1, \"%d / %d\", i, Config.MaxKeyLen)\n\t\t\t// get the first i bytes, ie first i*2 nibbles\n\t\t\tkeys <- key[:(i * 2)]\n\t\t}\n\t}\n}\n\n// chooseKey fixes the key and the message to the provided arguments\nfunc chooseKeys(fixed, iterated string) (k string, m string) {\n\tm = fixed\n\tk = iterated\n\treturn\n}\n\n// chooseMsg fixes the key and the message to the provided arguments\nfunc chooseMsg(fixed, iterated string) (k string, m string) {\n\tm = iterated\n\tk = fixed\n\treturn\n}\n\n// testProgs is the basic test in charge of checking the programs Prog1 and\n//  Prog2 are respectively encrypting and decrypting correctly with the key\n//  and msg arguments permuted as per chooseArgs, the loop function to provide\n//  the jobs must be provided. Concurrency is supported, as setted in config.json.\nfunc testProgs(fixed string, chooseArgs func(string, string) (string, string), loopOver func(chan string)) (mainErr error) {\n\tnbIter := Config.MaxMsgLen\n\tif Config.MaxKeyLen > nbIter {\n\t\tnbIter = Config.MaxKeyLen\n\t}\n\n\t// Initializing a common, unbuffered, channel which gives tasks to the worker goroutines\n\tjobs := make(chan string)\n\terrs := make(chan error, nbIter)\n\n\tvar wg sync.WaitGroup\n\t// spawn some worker goroutines according to the Concurrency setting in Config.json\n\tfor j := uint(0); j < Config.Concurrency; j++ {\n\t\twg.Add(1) //to be sure to finish all jobs\n\t\tgo func() {\n\t\t\tfor j := range jobs {\n\t\t\t\t// here we firstly permute the arguments to match our case\n\t\t\t\tk, m := chooseArgs(fixed, j)\n\t\t\t\t// we define a job id for logging purpose\n\t\t\t\tid := \"enc#\" + strconv.Itoa(len(m)) + \"#\" + strconv.Itoa(len(k))\n\t\t\t\tcipher := runOrExitOnErr(Prog1, id, k, m)\n\t\t\t\toutStr2 := runOrExitOnErr(Prog2, id, k, cipher)\n\n\t\t\t\tif m != outStr2 {\n\t\t\t\t\tfmt.Print(\"\\n\")\n\t\t\t\t\tLogWarning.Printf(\"decryption mismatch on job %s\\nInputs :%s %s\\n\"+\n\t\t\t\t\t\t\"Outputs\\t1: %s\\n\\t2: %s\\n\",\n\t\t\t\t\t\tid, k, m,\n\t\t\t\t\t\tcipher, outStr2)\n\t\t\t\t\terrs <- fmt.Errorf(\"decryption mismatch on job %s\", id)\n\t\t\t\t}\n\t\t\t}\n\t\t\twg.Done() // report the job as finished\n\t\t}()\n\t}\n\n\t// we call the loop function to iterate over the right objects\n\tloopOver(jobs)\n\n\t//we close our channel since it's unbuffered\n\tclose(jobs)\n\t// let us wait for our workers to finish their jobs\n\twg.Wait()\n\n\tif len(errs) > 0 {\n\t\t// Initializing the return value\n\t\tvar mainErr MultiError\n\t\tfirstErr := true\n\t\tfor len(errs) > 0 {\n\t\t\te := <-errs\n\t\t\tif firstErr {\n\t\t\t\tfirstErr = false\n\t\t\t\tTermPrepareFor(1)\n\t\t\t\t// This is not guaranteed to be the 1st one, but almost\n\t\t\t\tLogInfo.Println(\"First error:\", e)\n\t\t\t}\n\t\t\tmainErr = append(mainErr, e)\n\t\t}\n\t\tTermPrepareFor(1)\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\nfunc prepareInutsForEnc() (inputData []string, classes []int) {\n\tinputData = make([]string, numberMeasurements)\n\tclasses = make([]int, numberMeasurements)\n\n\t// there we may want to seed it with the seed indicated in the config file\n\t// for now this is not the case to have better results\n\trn := mrand.New(mrand.NewSource(time.Now().UnixNano()))\n\tdata := randomHex(Config.MaxKeyLen + Config.MinMsgLen)\n\t// we change only the key between the two class:\n\t//data2 := strings.Repeat(\"0\", Config.MaxKeyLen) + data[Config.MaxKeyLen:]\n\t// we use the same key and the same message each time\n\tfor i := 0; i < numberMeasurements; i++ {\n\t\tclasses[i] = rn.Intn(2)\n\t\tif classes[i] == 0 {\n\t\t\tinputData[i] = data\n\t\t} else {\n\t\t\tinputData[i] = randomHex(Config.MaxKeyLen + Config.MinMsgLen)\n\t\t}\n\t}\n\treturn\n}\n\nfunc doOneComputationForEnc(prog string) func(data string) {\n\treturn func(data string) {\n\t\tkey := data[:Config.MaxKeyLen]\n\t\tmsg := data[Config.MaxKeyLen:]\n\t\t_, err := runProg(prog, \"dudectTest\", []string{key, msg})\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cdf-lib/enc_test.go",
    "content": "package cdf\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n)\n\nfunc TestTestEnc(t *testing.T) {\n\tinitForTesting(\"ENC\")\n\terr := TestEnc()\n\tif err != nil {\n\t\tt.Error(\"Expected nil, got \", err)\n\t}\n\tif execCounter != 8 {\n\t\tt.Error(\"Expected 8 executions, got \", execCounter)\n\t}\n}\n\nfunc TestTestEncWithTimings(t *testing.T) {\n\tinitForTesting(\"ENC\")\n\t*TestTimings = 1 // it will run 1 dudect pass\n\tenoughMeasurements = float64(200)\n\tnumberMeasurements = 200\n\terr := TestEnc()\n\tif err != nil {\n\t\tt.Error(\"Expected nil, got \", err)\n\t}\n\tif execCounter != 408 {\n\t\tt.Error(\"Expected 408 executions, got \", execCounter)\n\t}\n}\n\nfunc testsForEnc(args []string) {\n\tkey := args[1]\n\tmsg := args[2]\n\n\tif len(key)%2 != 0 || len(msg)%2 != 0 {\n\t\tfmt.Fprintln(os.Stderr, \"Not a string of even length!\")\n\t\t//\t\tos.Exit(2)\n\t}\n\t// output for testing:\n\tfmt.Println(msg)\n}\n"
  },
  {
    "path": "cdf-lib/prf.go",
    "content": "package cdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// TestPrf will test the provided prf function on multiple message length\n// ranging from MinMsgLen to MaxMsgLen as set in the Config.json file\nfunc TestPrf() error {\n\tLogInfo.Print(\"testing prf\")\n\n\tfailed := false\n\n\t// Let us fetch random keys and messages nibbles:\n\tmsg := randomHex(Config.MaxMsgLen)\n\tkey := randomHex(Config.MaxKeyLen)\n\n\t// list of tags\n\ttags := make(map[string]int)\n\n\t// key length to use in msg test\n\tkeyAvgNibbles := 2 * ((Config.MaxKeyLen - Config.MinKeyLen) / 2)\n\t// msg length to use in key test\n\tmsgAvgNibbles := 2 * ((Config.MaxMsgLen - Config.MinMsgLen) / 2)\n\n\tLogInfo.Println(\"testing message lengths\")\n\tTermPrepareFor(1)\n\n\tcurrKey := key[:keyAvgNibbles]\n\tfailedTmp := false\n\t// note that we ignore the incrementMsg parameter, since the *2 is hardcoded here.\n\tfor i := Config.MinMsgLen; i <= Config.MaxMsgLen; i++ {\n\t\tcurrMsg := msg[:(i * 2)]\n\t\tTermPrintInline(1, \"%d / %d\", i, Config.MaxMsgLen)\n\n\t\tfailedTmp = failedTmp || runPrf(currKey, currMsg, tags, i)\n\t}\n\tif !failedTmp {\n\t\tLogSuccess.Println(\"message length: okay\")\n\t}\n\tfmt.Print(\"\\n\")\n\tLogInfo.Println(\"testing key lengths\")\n\tTermPrepareFor(1)\n\n\t// reset tags list\n\ttags = make(map[string]int)\n\n\tcurrMsg := msg[:msgAvgNibbles]\n\tfor i := Config.MinKeyLen; i <= Config.MaxKeyLen; i++ {\n\t\tTermPrintInline(1, \"%d / %d\", i, Config.MaxKeyLen)\n\n\t\tcurrKey := key[:(i * 2)]\n\t\tfailed = failed || runPrf(currKey, currMsg, tags, i)\n\t}\n\tif !failedTmp {\n\t\tLogSuccess.Println(\"key length: okay\")\n\t}\n\tTermPrepareFor(1)\n\n\tif nil != prfPaddingTests() {\n\t\tfailed = true\n\t}\n\n\tif failed {\n\t\tfmt.Print(\"\\n\")\n\t\treturn errors.New(\"one of more tests failed\")\n\t}\n\n\tfmt.Print(\"\\n\")\n\n\treturn nil\n}\n\n// runPrf is a helper method which perform the actual test of the two provided\n// programs. If checks both programs' output for cohension and verify the generated\n// tags for duplicates.\nfunc runPrf(currKey, currMsg string, tags map[string]int, index int) bool {\n\tfailed := false\n\t// get the first i bytes, ie first i*2 nibbles, since the interface is assuming\n\t// hexadecimal in/outputs\n\tid := fmt.Sprintf(\"prf#%d#%d\", len(currKey), len(currMsg))\n\toutStr1 := runOrExitOnErr(Prog1, id, currKey, currMsg)\n\toutStr2 := runOrExitOnErr(Prog2, id, currKey, currMsg)\n\n\tif previous, ok := tags[outStr1]; ok {\n\t\tfmt.Print(\"\\n\")\n\t\tLogWarning.Printf(\"same tag for %d and %d\\n\", previous, index)\n\t\tfailed = true\n\t} else {\n\t\ttags[outStr1] = index\n\t}\n\n\tif outStr1 != outStr2 {\n\t\tfmt.Print(\"\\n\")\n\t\tLogWarning.Printf(\"mismatch on length %d\", index)\n\t\tfailed = true\n\t\t// This is highly unlikely, yet let us cover this case\n\t\tif previous, ok := tags[outStr2]; ok {\n\t\t\tLogWarning.Printf(\"and same tag for %d and %d\", previous, index)\n\t\t\tfailed = true\n\t\t} else {\n\t\t\ttags[outStr2] = index\n\t\t}\n\t}\n\treturn failed\n}\n\nfunc prfPaddingTests() error {\n\tLogInfo.Println(\"Testing right 00 padding\")\n\n\ttags := make(map[string]int)\n\n\tcurrMsg := randomHex(Config.MinMsgLen)\n\tcurrKey := randomHex(Config.MinKeyLen)\n\tfailed := runPrf(currKey, currMsg, tags, 0)\n\tif failed {\n\t\tLogError.Fatalln(\"Something went really wrong\")\n\t}\n\tcurrKey = currKey + \"00\"\n\tfailed = runPrf(currKey, currMsg, tags, 1)\n\tif failed {\n\t\tLogError.Println(\"Left padding with 00 of the key leads to the same output\")\n\t\treturn fmt.Errorf(\"left padding error\")\n\t}\n\n\t/*\n\t\t// TODO: create an additionnal test to test the case with 00 at the end\n\t\t// of a previously used key\n\t\tif i == Config.MaxKeyLen {\n\t\t// this may be an option, but it would be best to refactor the whole\n\t\t//  process to have a function testConsistency() which will then\n\t\t//  process the different tests, keeping tracks of the previous tags,\n\t\t//  and so allowing to add one more easily...\n\t\t\t\t\tcurrKey = key[:(i-1)*2] + \"00\"\n\t\t\t\t}\n\t*/\n\treturn nil\n}\n"
  },
  {
    "path": "cdf-lib/rsaenc.go",
    "content": "package cdf\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/big\"\n\tmrand \"math/rand\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// TestRSAenc implements the cdf interface for RSA-OAEP encryption.\n// This interface assumes that the Prog1 can encrypt being given the public\n// modulus N, the public exponent E both in hex format and then a message : ./Prog1 n e msg\n// It also assumes that Prog2 can decrypt being given the primes P and Q, the\n// public exponent E (since some libs need it to build a private key), the private\n// exponent D, all four in hex format and the cipher text : ./Prog2 p q e d cipher\n// It does not (yet) assume reflexivity, ie: ./Prog2 n e msg does not need to encrypt.\nfunc TestRSAenc() error {\n\tLogInfo.Print(\"testing rsaenc\")\n\n\tfailed := false\n\n\t// Generate random hexadecimal data to try and encrypt those (the tested\n\t// program are supposed to unhexlify this data to obtain Config.MaxMsgLen bytes)\n\tmsg := randomHex(Config.MaxMsgLen)\n\tLogInfo.Println(\"testing different message's lengths\")\n\n\tif err := testRSAencConsistency(msg, Config.RsaN, Config.RsaE, Config.RsaD,\n\t\tConfig.RsaP, Config.RsaQ, Config.MaxMsgLen); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing messages lengths:\", err)\n\t} else {\n\t\tLogSuccess.Println(\"message's lengths test okay\")\n\t}\n\n\tif err := testRSAencPubExponentLen(msg); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing exponent lengths:\", err)\n\t} else {\n\t\tLogSuccess.Println(\"exponent's lengths test okay\")\n\t}\n\n\tif err := testRSAencPubMaxExponentLen(msg); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing max exponent support:\", err)\n\t} else {\n\t\tLogSuccess.Println(\"max exponent's lengths test okay\")\n\t}\n\n\tif err := testRSAencLargerMod(Prog1); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing bigger than modulus support:\\n\", err)\n\t} else {\n\t\tLogSuccess.Println(\"larger than modulus test okay for\", Prog1)\n\t}\n\tif err := testRSAencLargerMod(Prog2); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing bigger than modulus support:\\n\", err)\n\t} else {\n\t\tLogSuccess.Println(\"larger than modulus test okay for\", Prog2)\n\t}\n\n\tif err := testRSAsmallD(); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing D against Wiener's attack:\\n\", err)\n\t} else {\n\t\tLogSuccess.Println(\"private exponent vs Wiener's attack: okay\")\n\t}\n\n\tif limit := *TestTimings; limit > 0 {\n\t\tTermPrepareFor(1)\n\t\tLogInfo.Println(\"Starting timing tests, those may take hours depending on the max number of iterations set.\")\n\t\tdudectTest(limit, Prog1, doOneComputationForRsa, prepareInputsForRsa)\n\t\tdudectTest(limit, Prog2, doOneComputationForRsa, prepareInputsForRsa)\n\t\tfor i := 0; i <= 9; i++ {\n\t\t\tif i == 7 && len(Config.RsaN) != 2048 {\n\t\t\t\tLogInfo.Println(\"Specific tests for keys with a modulus of 1024 bits were skipped.\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdudectTest(limit, Prog1, doOneComputationForRsa, prepareInputsForSpecialRsa(i))\n\t\t\tdudectTest(limit, Prog2, doOneComputationForRsa, prepareInputsForSpecialRsa(i))\n\t\t}\n\t}\n\tif failed {\n\t\tfmt.Print(\"\\n\")\n\t\treturn errors.New(\"one of more tests failed\")\n\t}\n\n\treturn nil\n}\n\n// generateExponents generates a random bitlen-bit prime E and the\n// associated private exponent D, given n and phi(n)\nfunc generateExponents(bitlen int) (finE, finD string) {\n\tif bitlen == 1 {\n\t\tLogError.Fatalln(\"There are no prime of bit length 1\")\n\t}\n\t// We initialize our variables\n\tstart := new(big.Int)\n\tone := new(big.Int).SetUint64(1)\n\ttwo := new(big.Int).SetUint64(2)\n\tmin := new(big.Int).Lsh(one, uint(bitlen-1)) // using the left shift operator\n\tp11 := new(big.Int).Sub(fromBase16(Config.RsaP), one)\n\tp21 := new(big.Int).Sub(fromBase16(Config.RsaQ), one)\n\tPhi := new(big.Int).Mul(p11, p21)\n\tD := new(big.Int)\n\t// It may be better to not use our seeded Prng, but to seed a new one\n\tr := Prng // rand.New(rand.NewSource(time.Now().UnixNano()))\n\n\t// We generate a number between 0 and 2^bitlen while setting one to 2^bitlen\n\tstart.Rand(r, min)\n\t// Ensure we do not start with an even number\n\tif 0 != one.Cmp(new(big.Int).Mod(start, two)) {\n\t\tstart.Add(start, one)\n\t}\n\t// We begin looking for a prime bigger than 2^bitlen + random value :\n\tE := new(big.Int).Add(start, min)\n\terrCounter := 0\n\tfor found := false; !found; {\n\t\t// we use 8 times a Miller-Rabin test, so we have < 1/4^8 prob to have\n\t\t//  a false positive it is not secure, but sufficient for our purpose\n\t\tfound = E.ProbablyPrime(8)\n\n\t\tif found {\n\t\t\t// since it is probabilist, it does not hurt to cover this border\n\t\t\t//  case where the random start was too big\n\t\t\tif E.BitLen() >= bitlen+1 {\n\t\t\t\t//LogInfo.Println(\"e was too big, retrying\", min, start, E)\n\t\t\t\tfound = false\n\t\t\t\tE.Sub(E, min)\n\t\t\t\terrCounter++\n\t\t\t}\n\t\t\t// Ensure our potential E is coprime with Phi to get a valid key\n\t\t\tif 0 != one.Cmp(new(big.Int).GCD(nil, nil, E, Phi)) {\n\t\t\t\tLogToFile.Println(\"e was relatively prime to phi, \\n\\tmin:\",\n\t\t\t\t\tmin, \"\\n\\tstart:\", start, \"\\n\\tE:\", E, \"\\nRetrying.\")\n\t\t\t\tfound = false\n\t\t\t\terrCounter++\n\t\t\t}\n\t\t}\n\t\t// if found is no true, then E is not probably prime, so we can jump to\n\t\t//  the next odd integer\n\t\tif !found {\n\t\t\tE.Add(E, two)\n\t\t}\n\t\t// It is possible to get in a loop, we arbitrarily assume we are stuck\n\t\t//  after 100 errors\n\t\tif errCounter > 100 {\n\t\t\t//\t\t\tfmt.Printf(LINE_UP)\n\t\t\tLogWarning.Printf(\"unable to find a public exponent compatible \"+\n\t\t\t\t\"with bit-length %d\\n\", bitlen)\n\t\t\tLogInfo.Println(\"consider using safer primes e.g. of the form \" +\n\t\t\t\t\"p1=2a+1 and p2=2b+1 for a and b primes \" +\n\t\t\t\t\"if you want to test this length.\")\n\t\t\tLogInfo.Println(\"skipping bit-length:\", bitlen)\n\t\t\tTermPrepareFor(1)\n\t\t\treturn generateExponents(bitlen + 1)\n\t\t}\n\t}\n\t// The result is converted to hex since the interface is feeding the keys\n\t// as hex values\n\tfinE = E.Text(16)\n\t// Calculate D as the inverse of E mod Phi, it exists since we checked E was\n\t// coprime with Phi\n\tD = D.ModInverse(E, Phi)\n\tfinD = D.Text(16)\n\n\treturn finE, finD\n}\n\n// testRSAencPubExponentLen tests exponent length support, bit per bit, starting\n// from 2 bits however it is possible, depending on the selected primes and\n// resulting modulus that there are no primes on a given (small) bitlength that\n// is coprime with the phi(N), should it be the case, a Warning is issued and\n// it skips to a bigger bit-length, this skipping will statistically not lead\n// to any bug, so bordercases are not yet covered.\nfunc testRSAencPubExponentLen(msg string) error {\n\tvar errs MultiError\n\n\tTermPrepareFor(1)\n\tLogInfo.Println(\"testing exponent lengths\")\n\n\tvar N, e, d, P, Q string\n\tN = Config.RsaN\n\tP = Config.RsaP\n\tQ = Config.RsaQ\n\n\t// Starting from 2 since there are no prime of bit length 1, while 3 is\n\t// a prime a bit length 2\n\tTermPrepareFor(3)\n\tfor i := 2; i <= Config.MaxKeyLen; i++ {\n\t\tTermDisplay(3, \"trying with public exponent of bit-length %d / %d\",\n\t\t\ti, Config.MaxKeyLen)\n\t\te, d = generateExponents(i)\n\t\t// note we are doing only 3 tests on msg of size 1,2 and 3 :\n\t\terc := testRSAencConsistency(msg, N, e, d, P, Q, 3)\n\t\tif erc != nil {\n\t\t\tLogWarning.Printf(\"problem with bit-length %d:\\n%s\\n\",\n\t\t\t\ti, erc.Error())\n\t\t\tTermPrepareFor(4)\n\t\t\terrs = append(errs, fmt.Errorf(\"exponents test failed on  bit-length %d\", i))\n\t\t}\n\t}\n\tLogInfo.Println(\"exponent test finished\")\n\tif len(errs) > 0 {\n\t\tfmt.Print(lineUp(3))\n\t\treturn errs\n\t}\n\treturn nil\n}\n\n// testRSAencConsistency tests the encryption/decryption process using Prog1\n// to encrypt and Prog2 to decrypt, for *iter* trials.\nfunc testRSAencConsistency(msg, N, e, d, P, Q string, iter int) error {\n\tLogInfo.Println(\"testing consistency:\")\n\n\t// the general settings for that test\n\tmaxIter := Config.MaxMsgLen * 2         // since the settings are in byte\n\tincrementMsg := Config.IncrementMsg * 2 // since the settings are in byte\n\tif maxIter > iter*incrementMsg {\n\t\tmaxIter = iter * incrementMsg\n\t}\n\n\t// Initializing a common, unbuffered channel which gives tasks to\n\t// the worker goroutines\n\tmsgs := make(chan string)\n\terrs := make(chan error, maxIter)\n\t// spawn some worker goroutines\n\tvar wg sync.WaitGroup\n\tfor j := uint(0); j < Config.Concurrency; j++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tfor m := range msgs { // using range has to be closed later\n\t\t\t\trunID := fmt.Sprintf(\"rsaenc#%d#%d\", iter, len(m))\n\n\t\t\t\targs := []string{N, e, m}\n\t\t\t\t// get the message m from channel msgs and encrypt it\n\t\t\t\tcipher, errc := runProg(Prog1, strconv.Itoa(len(m)), args)\n\t\t\t\tif errc != nil {\n\t\t\t\t\t// Errors which are \"expected\" should be marked with FAIL\n\t\t\t\t\t//  in the tested program\n\t\t\t\t\tif strings.Contains(cipher, \"fail\") {\n\t\t\t\t\t\terrs <- fmt.Errorf(\"FAIL: %v\", errc)\n\t\t\t\t\t\tLogToFile.Println(\"Skipping the rest of job\", runID)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// other errors are not expected by the tested program\n\t\t\t\t\t\t//  and we stop there\n\t\t\t\t\t\tfmt.Println(\"\\nUnexpected error on\", Prog1)\n\t\t\t\t\t\tfmt.Println(\"Got output\", cipher)\n\t\t\t\t\t\tlog.Fatalln(errc)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\trecovered, errc := runProg(Prog2, runID,\n\t\t\t\t\t[]string{P, Q, e, d, cipher})\n\t\t\t\tif errc != nil {\n\t\t\t\t\t// Errors which are \"expected\" should be marked with FAIL\n\t\t\t\t\tif strings.Contains(recovered, \"fail\") {\n\t\t\t\t\t\terrs <- fmt.Errorf(\"FAIL: %v\", errc)\n\t\t\t\t\t\tLogToFile.Printf(\"failed to run Prog2 on job#%s\", runID)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else { // other errors are not expected and we stop there\n\t\t\t\t\t\tLogError.Printf(\"failed to run %s on run %s\\nerror: %v\",\n\t\t\t\t\t\t\tProg2, runID, errc)\n\t\t\t\t\t\tLogInfo.Println(\"after running:\", Prog1, args)\n\t\t\t\t\t\tlog.Fatalln(errc)\n\t\t\t\t\t}\n\t\t\t\t\tfmt.Print(\"\\n\")\n\t\t\t\t}\n\n\t\t\t\t// If the message we fed to the Prog1 does not match the\n\t\t\t\t//  recovered plaintext from Prog2, an error must have occurred:\n\t\t\t\tif m != recovered {\n\t\t\t\t\terrs <- fmt.Errorf(\"decryption mismatch on length %d\", len(m)/2)\n\t\t\t\t\tLogToFile.Printf(\"decryption mismatch on inputs : %s \\n\"+\n\t\t\t\t\t\t\"Got outputs\\t1: %s\\n\\t2: %s\",\n\t\t\t\t\t\tm, cipher, recovered)\n\t\t\t\t}\n\t\t\t}\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\t// Let us now fill our channel with the messages to be processed:\n\tfor i := Config.MinMsgLen * 2; i <= maxIter; i += incrementMsg {\n\t\tTermPrintInline(1, \"%d / %d\", i/incrementMsg, maxIter/incrementMsg)\n\t\tmsgs <- msg[:i]\n\t}\n\n\tfmt.Print(\"\\n\")\n\t// We have to close the channel to inform the receiver that there are\n\t//  no more messages coming.\n\tclose(msgs)\n\t// let us wait for our workers to finish\n\twg.Wait()\n\n\tif len(errs) > 0 {\n\t\t// Initializing the return value\n\t\tvar mainErr MultiError\n\t\tfirstErr := true\n\t\tfor len(errs) > 0 {\n\t\t\te := <-errs\n\t\t\tif firstErr {\n\t\t\t\tfirstErr = false\n\t\t\t\t// This is not guaranteed to be the 1st one, but almost\n\t\t\t\tLogInfo.Println(\"First error:\", e)\n\t\t\t}\n\t\t\tmainErr = append(mainErr, e)\n\t\t}\n\t\tTermPrepareFor(1)\n\t\treturn mainErr\n\t}\n\treturn nil\n}\n\n// testRSAencPubMaxExponentLen will test the maximal size of the exponent\n// the tested program support. Typically it would detect when a library is\n// using an integer instead of a big integer to store the exponent value.\nfunc testRSAencPubMaxExponentLen(msg string) (mainErr error) {\n\tTermPrepareFor(1)\n\tLogInfo.Println(\"testing max exponent lengths\")\n\tfailed := false\n\n\tvar N, e, d, P, Q string\n\tN = Config.RsaN\n\tP = Config.RsaP\n\tQ = Config.RsaQ\n\n\tnTests := 0\n\tfTests := 0\n\n\tvar errs MultiError\n\tmaxExp := 0\n\n\tTermPrepareFor(3)\n\t// the range is currently hard-coded, ideally it should be generated using\n\t// some kind of dichotomic-search like process with an upper limit\n\tfor iter, i := range [...]int{29, 30, 31, 32, 62, 63, 64, 126, 127, 128} {\n\t\te, d = generateExponents(i)\n\t\tTermDisplay(3, \"trying with public exponent of bit-length %d/%d\", i, 128)\n\t\terc := testRSAencConsistency(msg, N, e, d, P, Q, 1)\n\t\tif erc != nil {\n\t\t\tfailed = true\n\t\t\tif maxExp == 0 {\n\t\t\t\tmaxExp = i\n\t\t\t}\n\t\t\terrs = append(errs, fmt.Errorf(\"problem with bit-length %d\", i))\n\t\t\tfTests++\n\t\t}\n\t\tnTests = iter + 1\n\t}\n\tif failed {\n\t\tmainErr = fmt.Errorf(\"%d / %d exponents' tests failed:\\n%v\\n\"+\n\t\t\t\"it seems like the max exponent bit length of one of the programs\"+\n\t\t\t\" is smaller than %d\",\n\t\t\tfTests, nTests, errs,\n\t\t\tmaxExp)\n\t}\n\tLogInfo.Println(\"max supported exponent test finished\")\n\n\treturn mainErr\n}\n\n// testRSAencLargerMod tests the provided program against messages larger than\n// the used modulus, it does so by computing the size of the modulus and\n// generating a bigger message, before tring it and expecting an error. If no\n// error is thrown, then it'll return an error, otherwise it returns nil.\n// (TODO:We may argue later whether the throwned error should be outputed or not.\n// It is sowieso logged by the runProg function.)\nfunc testRSAencLargerMod(prog string) error {\n\tTermPrepareFor(1)\n\tLogInfo.Println(\"testing larger than modulus against\", prog)\n\tid := \"rsaenc#large_\" + prog\n\n\tvar N, e string\n\tN = Config.RsaN\n\te = Config.RsaE\n\tmsg := randomHex((fromBase16(N).BitLen()+7)/8 + 8)\n\n\targsP := []string{N, e, msg}\n\t_, err := runProg(prog, id, argsP)\n\tif err == nil {\n\t\treturn fmt.Errorf(\"%s accepted a message larged than the modulus\", prog)\n\t}\n\treturn nil\n}\n\n// testRSAsmallD is a side-check against the provided key, so it doesn't mean\n// much, unless you are using real keys. Wiener's attack works when d is small,\n// so let us check if it may work with the current key. (It may also not.)\nfunc testRSAsmallD() error {\n\tTermPrepareFor(1)\n\tLogInfo.Println(\"testing current key against Wiener's attack precondition\")\n\n\tN := fromBase16(Config.RsaN)\n\tD := fromBase16(Config.RsaD)\n\ttemp := big.NewInt(0).Div(bigSqrt(bigSqrt(N)), big.NewInt(3))\n\n\tif D.Cmp(temp) == -1 {\n\t\treturn fmt.Errorf(\"private exponent too small, may be vulnerable to Wiener's attack\")\n\t}\n\treturn nil\n}\n\n// doOneComputationForRsa provides the functions we can pass to the timing tests\n// to perform rsa on the desired program.\nfunc doOneComputationForRsa(prog string) func(string) {\n\treturn func(data string) {\n\t\trecovered, err := runProg(prog, \"dudect-\"+prog,\n\t\t\t[]string{Config.RsaP, Config.RsaQ, Config.RsaE, Config.RsaD, data})\n\t\tif err == nil { // odds are too odd for the decryption to be successful, yet it avoids any compiler optimisation since we use recovered in it.\n\t\t\tpanic(fmt.Errorf(\"decryption successful: %s\", recovered))\n\t\t}\n\t}\n}\n\n// prepareInputs generates inputs to test timings leak, it is a bit optimized\n// for OAEP but not too much.\nfunc prepareInputsForRsa() (inputData []string, classes []int) {\n\tinputData = make([]string, numberMeasurements)\n\tclasses = make([]int, numberMeasurements)\n\trn := mrand.New(mrand.NewSource(time.Now().UnixNano()))\n\n\t// we initialize the key and the big integers we need :\n\tN := fromBase16(Config.RsaN)\n\tk := uint((N.BitLen() + 7) / 8)                    // byte len\n\tlowerB := new(big.Int).Lsh(big.NewInt(1), 8*(k-1)) // one byte less\n\tupperB := new(big.Int).Sub(N, lowerB)\n\tee, err := strconv.ParseInt(Config.RsaE, 16, 8)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tpubK := &rsa.PublicKey{N: N, E: int(ee)}\n\tfor i := 0; i < numberMeasurements; i++ {\n\t\tclasses[i] = rn.Intn(2)\n\t\tvar tmp *big.Int\n\t\tif classes[i] == 0 { // we don't want a 00 MSB\n\t\t\t// we generate a big int of 255 bytes\n\t\t\ttmp = new(big.Int).Rand(rn, upperB)\n\t\t\ttmp.Add(tmp, lowerB) // ensure us to be have 256 bytes\n\t\t} else { // we want a 00 MSB:\n\t\t\ttmp = new(big.Int).Rand(rn, lowerB)\n\t\t}\n\t\t// we craft the cipher, since we know the key:\n\t\t// we encrypt to be sure of its size and format when decrypted: it'll be ee\n\t\tdata := encryptRSA(new(big.Int), pubK, tmp)\n\n\t\tinputData[i] = hex.EncodeToString(data)\n\t}\n\treturn\n}\n\n// prepareInputsForSpecialRsa generates inputs to test timings leak, it is a bit optimized\n// for OAEP but not too much. It also use known inputs that may cause stange behavior.\n// Those special inputs are thought for 1024-bit modulus using 65537 as public exponent.\n// Those are coming from the RSA Case Study by Jaffe & al\nfunc prepareInputsForSpecialRsa(special int) func() ([]string, []int) {\n\tLogInfo.Printf(\"Testing case %d\", special)\n\treturn func() (inputData []string, classes []int) {\n\t\tinputData = make([]string, numberMeasurements)\n\t\tclasses = make([]int, numberMeasurements)\n\t\trn := mrand.New(mrand.NewSource(time.Now().UnixNano()))\n\n\t\t// we initialize the key and the big integers we need :\n\t\tN := fromBase16(Config.RsaN)\n\t\tee, err := strconv.ParseInt(Config.RsaE, 16, 8)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tpubK := &rsa.PublicKey{N: N, E: int(ee)}\n\t\t// we craft the cipher, since we know the key:\n\t\t// we encrypt to be sure of its size and format when decrypted: it'll be ee\n\t\tdata0, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubK, []byte(\"Test\"), []byte(\"\"))\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tvar data []byte\n\n\t\tone := big.NewInt(1)\n\t\tP := fromBase16(Config.RsaP)\n\t\tk := (N.BitLen() + 7) / 8 // byte len\n\t\t// let us take a few of the special test cases for RSA (1024 bits) from \"Efficient side­channel\ttesting\tfor\tpublic key algorithms: RSA case study\" by J.Jaffe & P.Rohatgi, 2009.\n\t\tswitch special {\n\t\tcase 0:\n\t\t\tdata = []byte{0}\n\t\t\t// we need to be sure to match the right ciphertext length of k bytes,\n\t\t\t//  otherwise the test is meaningless.\n\t\t\tdata = leftPad(data, k)\n\t\tcase 1:\n\t\t\tdata = []byte{1}\n\t\t\tdata = leftPad(data, k)\n\t\tcase 2:\n\t\t\tdata = []byte{2}\n\t\t\tdata = leftPad(data, k)\n\t\tcase 3:\n\t\t\tdata = []byte{3}\n\t\t\tdata = leftPad(data, k)\n\t\tcase 4:\n\t\t\tdata = new(big.Int).Sub(N, big.NewInt(1)).Bytes()\n\t\t\tdata = leftPad(data, k)\n\t\tcase 5:\n\t\t\tdata = new(big.Int).Sub(N, big.NewInt(2)).Bytes()\n\t\t\tdata = leftPad(data, k)\n\t\tcase 6:\n\t\t\tdata = new(big.Int).Sub(N, big.NewInt(3)).Bytes()\n\t\t\tdata = leftPad(data, k)\n\t\t\t// from now on, the tests are though for 1024 bits keys\n\t\tcase 7: // in barrett reduction, an intermediate is zero\n\t\t\tnum := new(big.Int).Div(new(big.Int).Lsh(one, 700), P)\n\t\t\tmult := new(big.Int).Mul(num, new(big.Int).Lsh(one, 528))\n\t\t\tdenom := new(big.Int).Div(new(big.Int).Lsh(one, 1024), P)\n\t\t\tnum.Mul(num, mult)\n\t\t\tdata = new(big.Int).Div(num, denom).Bytes()\n\t\t\tdata = leftPad(data, k)\n\t\tcase 8: // in barrett reduction, an intermediate has high hamming weight\n\t\t\tnum := new(big.Int).Lsh(one, 1000)\n\t\t\tdenom := new(big.Int).Div(new(big.Int).Lsh(one, 1024), P)\n\t\t\tnum.Sub(num, one)\n\t\t\tdata = new(big.Int).Div(num, denom).Bytes()\n\t\t\tdata = leftPad(data, k)\n\t\tcase 9: // in barrett reduction, an intermediate is small and low hamming weight\n\t\t\tnum := new(big.Int).Lsh(one, 600)\n\t\t\tdenom := new(big.Int).Div(new(big.Int).Lsh(one, 1024), P)\n\t\t\tdata = new(big.Int).Div(num, denom).Bytes()\n\t\t\tdata = leftPad(data, k)\n\t\tdefault:\n\t\t\tlog.Fatalln(\"An unexpected index was provided to the special case RSA input preparation function\")\n\t\t}\n\t\tfor i := 0; i < numberMeasurements; i++ {\n\t\t\tclasses[i] = rn.Intn(2)\n\t\t\tif classes[i] == 1 { // we want a special case\n\t\t\t\tinputData[i] = hex.EncodeToString(data)\n\t\t\t} else { // we use the constant ciphertext generated above\n\t\t\t\tinputData[i] = hex.EncodeToString(data0)\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "cdf-lib/rsasign.go",
    "content": "package cdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// TestRSAsign implements the cdf interface for RSA based signature schemes.\n// This interface assumes that the Prog1 can sign being given the primes P\n// and Q, the public exponent E (since some libs need it to build a private\n// key), the private exponent D, all four in hex format and the message:\n// ./Prog1 p q e d msg\n// It also assumes that Prog2 can verify the signature being given the public\n// modulus N and the public exponent E, as well as the signature S\n// all given in hex format and the message : ./Prog2 n e s msg\n// It does not (for now) assume reflexivity.\nfunc TestRSAsign() error {\n\tLogInfo.Print(\"testing rsasign\")\n\n\tfailed := false\n\n\t// Generate random hexadecimal data to try and sign those (the tested\n\t// program are supposed to unhexlify this data to obtain bytes)\n\tmsg := randomHex(Config.MaxMsgLen)\n\tLogInfo.Println(\"testing different message's lengths\")\n\n\tif err := testRsaSignConsistency(msg, Config.RsaN, Config.RsaE, Config.RsaD,\n\t\tConfig.RsaP, Config.RsaQ, Config.MaxMsgLen); err != nil {\n\t\tfailed = true\n\t\tLogError.Println(\"while testing messages lengths:\", err)\n\t} else {\n\t\tLogSuccess.Println(\"message's lengths test okay\")\n\t}\n\n\tif failed {\n\t\tfmt.Print(\"\\n\")\n\t\treturn errors.New(\"one of more tests failed\")\n\t}\n\n\treturn nil\n}\n\n// testRsaSignConsistency tests the sign/verify process using Prog1\n// to sign and Prog2 to verify, for *iter* trials.\nfunc testRsaSignConsistency(msg, N, e, d, P, Q string, iter int) error {\n\tLogInfo.Println(\"testing consistency:\")\n\n\tvar errs MultiError\n\n\t// Initializing a common, unbuffered channel which gives tasks to\n\t// the worker goroutines\n\tmsgs := make(chan string)\n\t// spawn some worker goroutines\n\tvar wg sync.WaitGroup\n\tfor j := uint(0); j < Config.Concurrency; j++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tfor m := range msgs { // using range has to be closed later\n\t\t\t\trunID := fmt.Sprintf(\"rsasign#%d#%d\", iter, len(m))\n\n\t\t\t\targs := []string{P, Q, e, d, m}\n\t\t\t\t// get the message m from channel msgs and sign it\n\t\t\t\tsignature, errc := runProg(Prog1, strconv.Itoa(len(m)), args)\n\t\t\t\tif errc != nil {\n\t\t\t\t\t// Errors which are \"expected\" should be marked with FAIL\n\t\t\t\t\t// in the tested program\n\t\t\t\t\tif strings.Contains(signature, \"fail\") {\n\t\t\t\t\t\terrs = append(errs, fmt.Errorf(\"FAIL: %v\", errc))\n\t\t\t\t\t\tLogToFile.Println(\"Skipping the rest of job\", runID)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// other errors are not expected by the tested program\n\t\t\t\t\t\t// and we stop there\n\t\t\t\t\t\tfmt.Println(\"\\nUnexpected error on\", Prog1)\n\t\t\t\t\t\tfmt.Println(\"Got output\", signature)\n\t\t\t\t\t\tlog.Fatalln(errc)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tresult, errc := runProg(Prog2, runID,\n\t\t\t\t\t[]string{N, e, signature, m})\n\t\t\t\tif errc != nil {\n\t\t\t\t\t// Errors which are \"expected\" should be marked with FAIL\n\t\t\t\t\tif strings.Contains(result, \"fail\") {\n\t\t\t\t\t\terrs = append(errs, fmt.Errorf(\"FAIL: %v\", errc))\n\t\t\t\t\t\tLogToFile.Printf(\"failed to run Prog2 on job#%s\", runID)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else { // other errors are not expected and we stop there\n\t\t\t\t\t\tLogError.Printf(\"failed to run %s on run %s\\nerror: %v\",\n\t\t\t\t\t\t\tProg2, runID, errc)\n\t\t\t\t\t\tLogInfo.Println(\"after running:\", Prog1, args)\n\t\t\t\t\t\tlog.Fatalln(errc)\n\t\t\t\t\t}\n\t\t\t\t\tfmt.Print(\"\\n\")\n\t\t\t\t}\n\n\t\t\t\t// If the message we fed to the Prog1 is not valid wrt its sign\n\t\t\t\t//   according to Prog2, an error must have occurred:\n\t\t\t\tif result != trueStr {\n\t\t\t\t\terrs = append(errs,\n\t\t\t\t\t\tfmt.Errorf(\"verification failed on length %d\", len(m)/2))\n\t\t\t\t\tLogToFile.Printf(\"error on inputs : %s \\n\"+\n\t\t\t\t\t\t\"Got outputs\\t1: %s\\n\\t2: %s\",\n\t\t\t\t\t\tm, signature, result)\n\t\t\t\t}\n\t\t\t}\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\tmaxIter := Config.MaxMsgLen * 2         // since the settings are in byte\n\tincrementMsg := Config.IncrementMsg * 2 // since the settings are in byte\n\tif maxIter > iter*incrementMsg {\n\t\tmaxIter = iter * incrementMsg\n\t}\n\t// Let us now fill our channel with the messages to be processed:\n\tfor i := Config.MinMsgLen * 2; i <= maxIter; i += incrementMsg {\n\t\tTermPrintInline(1, \"%d / %d\", i/incrementMsg, maxIter/incrementMsg)\n\t\tmsgs <- msg[:i]\n\t}\n\n\tfmt.Print(\"\\n\")\n\t// We have to close the channel to inform the receiver that there are\n\t//  no more messages coming.\n\tclose(msgs)\n\t// let us wait for our workers to finish\n\twg.Wait()\n\n\tif len(errs) > 0 {\n\t\treturn errs\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cdf-lib/termview.go",
    "content": "package cdf\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Escape sequences for terminal rendering.\nvar (\n\tesc         = \"\\033[\"\n\tcl          = esc + \"2K\"\n\tclearScreen = esc + \"2J\"\n\tresetCursor = esc + \"0;0H\"\n\tclearLine   = esc + \"1G\" + cl\n\tTermView    = log.New(os.Stdout, \"\", 0)\n)\n\n// lineUp will return the escape sequence to move up by n lines in the terminal\n//  and clear the line\nfunc lineUp(n int) string {\n\treturn esc + strconv.Itoa(n) + \"F\" + clearLine\n}\n\n// lineDown will return the escape sequence to move down by n lines in the\n//  terminal and clear the line\nfunc lineDown(n int) string {\n\treturn esc + strconv.Itoa(n) + \"E\" + clearLine\n}\n\n// TermClear is a function which allow to clear the terminal to prepare\n// displaying the data\nfunc TermClear() {\n\tTermView.Print(clearScreen + resetCursor)\n}\n\n// TermPrepareFor is a function which allow to allocate the lines we will be\n// using later. Its purpose is to make the terminal display we use compatible\n// with the default logging functions.\nfunc TermPrepareFor(size int) {\n\tTermView.Print(strings.Repeat(\"\\n\", size))\n}\n\n// TermDisplay moves the cursor up and then displays the specified content as\n// well as writing to the log file if it is enabled\nfunc TermDisplay(size int, format string, a ...interface{}) {\n\tTermView.Printf(lineUp(size)+format, a...)\n\tLogToFile.Printf(format, a...)\n}\n\n// TermPrintInline prints inline the provided string, with string formatting\nfunc TermPrintInline(size int, format string, a ...interface{}) {\n\tTermView.Printf(lineUp(size)+clearLine+format, a...)\n\tLogToFile.Printf(format, a...)\n}\n"
  },
  {
    "path": "cdf-lib/utils.go",
    "content": "package cdf\n\nimport (\n\t\"bytes\"\n\t\"crypto/rsa\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"math/big\"\n\t\"math/rand\"\n\t\"os\"\n\t\"os/exec\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Here are our constants\nconst (\n\thexChars = \"abcdef0123456789\"\n\ttrueStr  = \"true\"\n)\n\n// Those are the different global variables used by CDF\nvar (\n\tForceVerbose *bool       // enables verbose logging\n\tLogInfo      *log.Logger // info on cdf execution\n\tLogSuccess   *log.Logger // all test cases past\n\tLogWarning   *log.Logger // when a test fails\n\tLogError     *log.Logger // when something's wrong and unexpected\n\tLogToFile    *log.Logger // write it to the log file to avoid verbose output\n\tPrng         *rand.Rand  // non-crypto Prng to randomize tests\n\tInterf       string      // interface\n\tProg1        string      // the path to the first executable\n\tProg2        string      // the path to the second executable in interfaces where two are needed\n\tTestHashes   *bool       // specify if the -h flag is supported by both program\n\tTestTimings  *int        // specify how many, if any, timing tests should be run\n)\n\n// Config contains the global cdf Configuration variables:\n// Seed is the Prng seed\n// *MsgLen for xof, prf, enc, rsaenc: the different lengths of the tested messages\n// *KeyLen for prf, enc: length of key; for rsaenc: length of tested public exponents\n// increment* is the number of bytes of increment between two loops in some interfaces\n// Rsa* for oaep/pkcs encryption: the primes P,Q, the modulus N, the public exponent E and the private one D. Must be given as hex strings in big endian representation\n// Ecdsa*: the X and Y public coordinates to use and the private big integer D, all to be given as hex strings in big endian representation\n// Concurrency: the maximum number of concurrent go routine which should be running an exec call to the tested program at the same time\n// VerboseLog: a boolean specifying whether all inputs/outputs are to be written to a log file or not. Can help with debugging\nvar Config struct {\n\tSeed         int64  `json:\"seed\"`\n\tMinMsgLen    int    `json:\"minMsgLen\"`\n\tMaxMsgLen    int    `json:\"maxMsgLen\"`\n\tIncrementMsg int    `json:\"incrementMsg\"`\n\tMinKeyLen    int    `json:\"minKeyLen\"`\n\tMaxKeyLen    int    `json:\"maxKeyLen\"`\n\tIncrementKey int    `json:\"incrementKey\"`\n\tRsaP         string `json:\"rsaP\"`\n\tRsaQ         string `json:\"rsaQ\"`\n\tRsaN         string `json:\"rsaN\"`\n\tRsaE         string `json:\"rsaE\"`\n\tRsaD         string `json:\"rsaD\"`\n\tEcdsaX       string `json:\"ecdsaX\"`\n\tEcdsaY       string `json:\"ecdsaY\"`\n\tEcdsaD       string `json:\"ecdsaD\"`\n\tDsaP         string `json:\"dsaP\"`\n\tDsaQ         string `json:\"dsaQ\"`\n\tDsaG         string `json:\"dsaG\"`\n\tDsaY         string `json:\"dsaY\"`\n\tDsaX         string `json:\"dsaX\"`\n\tTimeout      int    `json:\"timeout\"`\n\tConcurrency  uint   `json:\"concurrency\"`\n\tVerboseLog   bool   `json:\"verboseLog\"`\n}\n\n// MultiError allows to store multiple errors\n// like those we get from our external tests\ntype MultiError []error\n\n// (MultiError) Error implements the error interface for our MultiError type\nfunc (m MultiError) Error() string {\n\ts, n := \"\", 0\n\tfor _, e := range m {\n\t\tif e != nil {\n\t\t\ts += \"\\n\" + e.Error()\n\t\t\tn++\n\t\t}\n\t}\n\tswitch n {\n\tcase 0:\n\t\treturn \"(0 error)\"\n\tcase 1:\n\t\treturn fmt.Sprintf(\"(1 error)%s\", s)\n\t}\n\treturn fmt.Sprintf(\"(%d errors)%s\", n, s)\n}\n\n// InitLog allows one to initialise the logging system to output data to the specified file.\nfunc InitLog(logFile *os.File) {\n\tif logFile != nil {\n\t\tmultiO := io.MultiWriter(logFile, os.Stdout)\n\t\tmultiE := io.MultiWriter(logFile, os.Stderr)\n\n\t\t// Configure loggers\n\t\tLogInfo = log.New(multiO, \"\\x1b[0;36mINFO:\\x1b[0m \", 0)\n\t\tLogSuccess = log.New(multiO, \"\\x1b[0;32mSUCCESS:\\x1b[0m \", 0)\n\t\tLogWarning = log.New(multiO, \"\\x1b[0;35mWARNING:\\x1b[0m \", log.Lshortfile)\n\t\tLogError = log.New(multiE, \"\\x1b[0;31mERROR:\\x1b[0m \", log.Lshortfile)\n\t\tLogToFile = log.New(logFile, \"\", log.Ldate|log.Ltime|log.Lshortfile)\n\n\t\tlog.SetOutput(multiO)\n\t\tLogToFile.Println(\"Intiliazing logs : done\")\n\t} else {\n\t\tLogInfo = log.New(ioutil.Discard, \"\\x1b[0;36mINFO:\\x1b[0m \", 0)\n\t\tLogSuccess = log.New(ioutil.Discard, \"\\x1b[0;32mSUCCESS:\\x1b[0m \", 0)\n\t\tLogWarning = log.New(ioutil.Discard, \"\\x1b[0;35mWARNING:\\x1b[0m \", log.Lshortfile)\n\t\tLogError = log.New(ioutil.Discard, \"\\x1b[0;31mERROR:\\x1b[0m \", log.Lshortfile)\n\t\tLogToFile = log.New(ioutil.Discard, \"\", log.Ldate|log.Ltime|log.Lshortfile)\n\t\tlog.SetOutput(ioutil.Discard)\n\t\tTermView.SetOutput(ioutil.Discard)\n\t}\n}\n\n// randomHex generate len*2 random hex char to have len random bytes\nfunc randomHex(len int) string {\n\tcharNibbles := make([]byte, len*2)\n\tfor i := 0; i < len*2; i++ {\n\t\tcharNibbles[i] = hexChars[Prng.Uint32()%16]\n\t}\n\n\treturn string(charNibbles)\n}\n\n// fromBase16 is a helper method to use the prime in hex form, inspired from crypto/rsa/rsa_test.go\nfunc fromBase16(base16 string) *big.Int {\n\ti, ok := new(big.Int).SetString(base16, 16)\n\tif !ok {\n\t\tlog.Fatalln(\"trying to convert from base16 a bad number: \" + base16)\n\t}\n\treturn i\n}\n\n// DisableLogFile reset the different log to output only on Stdout/Stderr and\n// disable the verbose LogToFile, with a mere 100ns overhead (according to\n// https://gist.github.com/Avinash-Bhat/48c4f06b0cc840d9fd6c)\nfunc DisableLogFile() {\n\t// we disable the LogToFile completely\n\tLogToFile.SetFlags(0)\n\tLogToFile.SetOutput(ioutil.Discard)\n\t// we reset the other logs to output on the Std outputs\n\tLogError.SetOutput(os.Stderr)\n\tLogWarning.SetOutput(os.Stdout)\n\tLogSuccess.SetOutput(os.Stdout)\n\tLogInfo.SetOutput(os.Stdout)\n\tlog.SetOutput(os.Stdout)\n}\n\n// this is a trick from https://github.com/golang/go/blob/master/src/os/exec/exec_test.go#L32-L44\n// which allows us to mimick the exec package in test files!\nvar execCommand = exec.Command\n\n// runProg is a helper function allowing to run the program with specific arguments\nfunc runProg(prog, runID string, args []string) (string, error) {\n\n\tLogToFile.Println(strings.Join(append([]string{\"Batch#\", runID,\n\t\t\"Attempting :\", prog}, args...), \" \"))\n\tvar cmd *exec.Cmd\n\tcmd = execCommand(prog, args...)\n\n\t// we link Stdout and Stderr to alternative bytes.Buffer to control the outputs\n\tvar out, outerr bytes.Buffer\n\tcmd.Stdout = &out\n\tcmd.Stderr = &outerr\n\terr := cmd.Start()\n\tif err != nil {\n\t\tLogError.Fatalln(\"Could not start exec Cmd:\", err)\n\t}\n\t//out, err := cmd.CombinedOutput()\n\ttimer := time.AfterFunc(time.Duration(Config.Timeout)*time.Second, func() { cmd.Process.Kill() })\n\terr = cmd.Wait()\n\tif err != nil {\n\t\tLogToFile.Println(\"Error on batch#\", runID, \"with\", prog)\n\t\tLogToFile.Println(\"Program returned:\", out.String()+outerr.String())\n\t} else {\n\t\tLogToFile.Println(\"Batch#\", runID, prog,\n\t\t\t\"runned successfully, it returned: \", out.String())\n\t}\n\tif !timer.Stop() {\n\t\treturn \"\", fmt.Errorf(\"Cmd timed out! STOP\")\n\t}\n\n\treturn strings.ToLower(strings.TrimSpace(out.String() + outerr.String())), err\n}\n\n// runOrExitOnErr invokes runProg and if we encounter an error\n// exits by invoking log.Fatal with the error.\nfunc runOrExitOnErr(prog, id string, args ...string) string {\n\toutStr, err := runProg(prog, id, args)\n\tif err != nil {\n\t\tfmt.Printf(\"\\nExit on: %s\\n\", outStr)\n\t\tLogError.Println(append([]string{\"Failed after running:\",\n\t\t\tprog}, args...))\n\t\tlog.Fatalln(err)\n\t}\n\treturn outStr\n}\n\n// bigSqrt is computing the integer square-root of x, for x a big integer\nfunc bigSqrt(x *big.Int) (kx *big.Int) {\n\tswitch x.Sign() {\n\tcase -1:\n\t\tpanic(-1)\n\tcase 0:\n\t\treturn big.NewInt(0)\n\t}\n\n\tvar px, xk1 big.Int\n\tkx = big.NewInt(0)\n\tkx.SetBit(kx, x.BitLen()/2+1, 1)\n\tfor {\n\t\t// we applied the iterative formula found on Wikipedia\n\t\txk1.Rsh(xk1.Add(kx, xk1.Div(x, kx)), 1)\n\t\tif xk1.Cmp(kx) == 0 || xk1.Cmp(&px) == 0 {\n\t\t\tbreak\n\t\t}\n\t\tpx.Set(kx)\n\t\tkx.Set(&xk1)\n\t}\n\treturn\n}\n\n// Int64ToSort let us fullfill the Sort interface for slices of int64\ntype Int64ToSort []int64\n\nfunc (s Int64ToSort) Len() int           { return len(s) }\nfunc (s Int64ToSort) Less(i, j int) bool { return s[i] < s[j] }\nfunc (s Int64ToSort) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\n// for dudect\nfunc percentile(x []int64, perc float64) int64 {\n\tval := int(perc * float64(len(x)))\n\tif len(x) <= val || 0 >= val {\n\t\tlog.Fatalln(\"Error, percentile should be smaller than 1 and bigger than 0. Got:\\n\", val, len(x), perc)\n\t}\n\tsort.Sort(Int64ToSort(x))\n\treturn x[val]\n}\n\n// encryptRSA\nfunc encryptRSA(c *big.Int, pub *rsa.PublicKey, m *big.Int) []byte {\n\te := big.NewInt(int64(pub.E))\n\tc.Exp(m, e, pub.N)\n\treturn c.Bytes()\n}\n\n// leftPad returns a new slice of length size. The contents of input are right\n// aligned in the new slice and its left part is zero initialised as per Go spec.\nfunc leftPad(input []byte, size int) (out []byte) {\n\tn := len(input)\n\tif n > size {\n\t\tn = size\n\t}\n\tout = make([]byte, size)\n\n\tcopy(out[len(out)-n:], input)\n\treturn\n}\n"
  },
  {
    "path": "cdf-lib/utils_test.go",
    "content": "package cdf\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"math/rand\"\n\t\"os\"\n\t\"os/exec\"\n\t\"testing\"\n)\n\nvar execCounter int\n\nfunc TestHelperProcess(t *testing.T) {\n\tif os.Getenv(\"GO_WANT_HELPER_PROCESS\") == \"\" {\n\t\treturn\n\t}\n\tdefer os.Exit(0)\n\tlogFile, err := os.OpenFile(\"/tmp/test_logs.txt\", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to open test_logs.txt file:\", err)\n\t}\n\tdefer logFile.Close()\n\tLogToFile = log.New(logFile, \"\", log.Ldate|log.Ltime|log.Lshortfile)\n\targs := os.Args\n\tfor len(args) > 0 {\n\t\tif args[0] == \"--\" {\n\t\t\targs = args[1:]\n\t\t\tbreak\n\t\t}\n\t\targs = args[1:]\n\t}\n\tif len(args) == 0 {\n\t\tfmt.Fprintf(os.Stderr, \"No command\\n\")\n\t\tos.Exit(2)\n\t}\n\n\tswitch os.Getenv(\"GO_WANT_HELPER_PROCESS\") {\n\tcase \"ENC\":\n\t\ttestsForEnc(args)\n\tcase \"ECDSA\":\n\t\tExampleECDSA(args)\n\tcase \"DSA\":\n\t\tExampleDSA(args)\n\tdefault:\n\t\treturn\n\t}\n\tLogToFile = log.New(ioutil.Discard, \"\", log.Ldate|log.Ltime|log.Lshortfile)\n}\n\n// fakeExecCommand is a trick from the test of the os/exec package to be able to test it.\nfunc fakeExecCommand(currentTest string) func(command string, args ...string) *exec.Cmd {\n\treturn func(command string, args ...string) *exec.Cmd {\n\t\texecCounter++\n\t\tcs := []string{\"-test.run=TestHelperProcess\", \"--\", command}\n\t\tcs = append(cs, args...)\n\t\tcmd := exec.Command(os.Args[0], cs...)\n\t\t// Let us tell the TestHelperProcess that we are running it from fakeExecCommand:\n\t\tcmd.Env = []string{fmt.Sprintf(\"GO_WANT_HELPER_PROCESS=%s\", currentTest)}\n\t\treturn cmd\n\t}\n}\n\nfunc initForTesting(currentTest string) {\n\t// disabling log:\n\tInitLog(nil)\n\t// disabling exec:\n\texecCommand = fakeExecCommand(currentTest)\n\texecCounter = 0\n\t// setting some default test parameters:\n\tConfig.MinKeyLen = 1\n\tConfig.MaxKeyLen = 2\n\tConfig.MinMsgLen = 1\n\tConfig.MaxMsgLen = 2\n\tConfig.IncrementKey = 1\n\tConfig.IncrementMsg = 1\n\n\tConfig.Seed = 0\n\t// a random RSA key\n\tConfig.RsaP = \"D29BB20DAE71CA8EA2988DBC5629CA4C830A7F39D031DC45D064F6F8463ACA73E59F999FA1DC5F01199B2EB949EAA08D8277337027C77317B159B96975A86B57\"\n\tConfig.RsaQ = \"D09CCF3050C82108220DA39DEBA7446758D0061CC046C52C52370A81C7358571E8F1494F49D82B7CB31293FE0E0F15B8200B1EADD1364A5CE60A97ABF3D41D33\"\n\tConfig.RsaN = \"AB9F81FF42B280FE2F2F6A9D167C27247A450241D082B955F7F444789687B805D6F06811B6D09B9B661670F1E4B205753E9167A072F0B8442848F291E0D139D2403F2E1C6F23380C03058D99176CF8A6C7AAAAAF5822FA2B82E9A29888A39FDBA9B3B13DEB47DB15A3731F825454636729DCC6A655C4563C6F1B33CFFDC23D55\"\n\tConfig.RsaE = \"10001\"\n\tConfig.RsaD = \"60AD8C17754504F12B3774C165072F2D974B04887AA309306A6B499EFC7D1BA6FE7B92C457CD8FBAAC797BCA67DFF8BF212DDBC840B765B5CF53B88180B99BEDEE66F23EA3A03297E138EAC7E2A0DFDB1E07B4E21C27D3AF2996D16A5050897C9FA32DC0C6ABFFBC6919E8B9D80A6478FCBC71E4D70E70C632B82D64995DE309\"\n\n\t// ECDSA key for P256\n\tConfig.EcdsaX = \"3bac7e95a003264cc075a2ba8d4e949862acd755d49094ad8d28bd0d56299dc6\"\n\tConfig.EcdsaY = \"5c6a5b3810181d82f5eb1be32c9cd8d6c387fcb06fed530d749e3997eb22bd8c\"\n\tConfig.EcdsaD = \"8964e19c5ae38669db3047f6b460863f5dc6c4510d3427e33545caf9527aafcf\"\n\n\t// DSA key\n\tConfig.DsaP = \"A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF\"\n\tConfig.DsaQ = \"E1D3391245933D68A0714ED34BBCB7A1F422B9C1\"\n\tConfig.DsaG = \"634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA\"\n\tConfig.DsaY = \"32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2\"\n\tConfig.DsaX = \"5078D4D29795CBE76D3AACFE48C9AF0BCDBEE91A\"\n\n\t// General settings\n\tConfig.Timeout = 5\n\tConfig.Concurrency = 3\n\tConfig.VerboseLog = false\n\n\t// let us set the PRNG using the seed:\n\tPrng = rand.New(rand.NewSource(Config.Seed))\n\n\t// Finally we setup the flags:\n\tTestTimings = new(int)\n\tTestHashes = new(bool)\n}\n"
  },
  {
    "path": "cdf-lib/xof.go",
    "content": "package cdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// TestXof will generate a random message and test the range from MinMsgLen to\n// MaxMsgLen with IncrementMsg bytes increment. It checks for duplicate results\n// and compare both implementation against each other. Its return value is\n// an error or nil on success.\nfunc TestXof() error {\n\tLogInfo.Print(\"testing xof\")\n\n\tfailed := false\n\n\tmsg := randomHex(Config.MaxMsgLen)\n\n\t// list of hashes\n\thashes := make(map[string]int)\n\n\tLogInfo.Println(\"testing message lengths\")\n\n\tfor i := Config.MinMsgLen; i <= Config.MaxMsgLen; i += Config.IncrementMsg {\n\n\t\tTermPrintInline(1, \"%d / %d\", i, Config.MaxMsgLen)\n\t\tid := fmt.Sprintf(\"xof#msglen#%d\", i)\n\t\t// get the first i bytes, ie first i*2 nibbles\n\t\toutStr1 := runOrExitOnErr(Prog1, id, msg[:(i*2)])\n\t\toutStr2 := runOrExitOnErr(Prog2, id, msg[:(i*2)])\n\n\t\tif length, ok := hashes[outStr1]; ok {\n\t\t\tfmt.Print(\"\\n\")\n\t\t\tLogWarning.Printf(\"same hash for %d and %d\", length, i)\n\t\t\tfailed = true\n\t\t} else {\n\t\t\thashes[outStr1] = i\n\t\t}\n\n\t\tif outStr1 != outStr2 {\n\t\t\tfmt.Print(\"\\n\")\n\t\t\tLogWarning.Printf(\"mismatch on length %d\\nGot:\\n\\t%s\\n\\t%s\", i, outStr1, outStr2)\n\t\t\tfailed = true\n\t\t\tif length, ok := hashes[outStr2]; ok {\n\t\t\t\tLogWarning.Printf(\"same hash for %d and %d\", length, i)\n\t\t\t\tfailed = true\n\t\t\t} else {\n\t\t\t\thashes[outStr2] = i\n\t\t\t}\n\t\t}\n\t}\n\n\tif failed {\n\t\tfmt.Print(\"\\n\")\n\t\treturn errors.New(\"one of more tests failed\")\n\t}\n\n\tfmt.Print(\"\\n\")\n\treturn nil\n}\n"
  },
  {
    "path": "config.json",
    "content": "{\n    \"seed\": 5\n    , \"minMsgLen\": 2\n    , \"maxMsgLen\": 214\n    , \"incrementMsg\": 2\n    , \"minKeyLen\": 16\n    , \"maxKeyLen\": 32\n    , \"incrementKey\": 8\n    , \"rsaP\":\"e999d9abbcf3ae2e3261957863bea74f4182cf27e22e4faff461c96ef19a65bf8e85aca934e18a745e64f7f2be9e150f562dda16e52e0504e4ab53f70c12ebec2ccf4e4c628356c4ebdab3398dfef6274b4c3f5b14531e4499acd0d59c5da3a03991cf8debb05799d9156ee807c6d3088e0d01d98ab45800d1b0e94712f38575\"\n    , \"rsaQ\":\"ec244a18729e63a990ddcd414d0066af68c31343bd6ac03a189baa98783436d19c455fd494f5ab10ccd9ab9d18550eed6c2929ac0465165349c175a81eaa24da2c47de1a2dbe88eb4434e7b68b32b89fc2aec6433046713a048d54b5b86766333d540b965c5bac6e4a971d7b804a5f39c8f7aae6f301468857d15fdf3d4c4fdb\"\n    , \"rsaN\":\"d77af1e9b6464e634834e85e48969f5d649eb89fa16566a54daa95135b4b3ad8be44bf8c0c1454575059627c34ddd460b4424080e87c0c816550e54f9f68b6a1daeeab2d4b6da896544a3630e044f30d640830a9ab01c5ca2d77840d534a51147b6aba70a07b3a75f76962052f2769989dc4abd6ee12eb19dc62273bddf483793cd0af625f54db606fb205e2ffa3ed8d2300b0fc6b3e63b061fa7c7d487c960f58edfce17b0ee8c14693b3a1ace8412c09ae77592b572e2bff4fffa4e40805574704f16ab1aa7e66ed3d67e76a101dae09f504c1c607c1345ab17d7c16884cf80ebff2f3702d6d81472ed378f8137c2dda5a5556c81aa5c8c31ed1a9dc3e4617\"\n    , \"rsaE\":\"11\"\n    , \"rsaD\":\"1c76beff6efefbd2fe2d8f80f64d7d6802b94ad91d826e40a26ec5c190f26cb1a23f812107ac07f883159511331a657fb25cc391290370e037a759bbca06f6929b33de9a75398c5cc62e42dd81c0b84783d5c135d9d3526643d38d59350227c569dcf57d92b0607d7c5b1061e81c747453306f77896374ead8afb4de6e29480da8b1df30a2b59a39aeb04c8118f3b2cc47f4bf1581245e8cdb687dd0b15c768de4ce74d2c86ab16f3cf08d9d6f7b8619cb9a7a8790377d55d6600f9714836db6ad90379d35d10e5c4cc552d1ad28be125bef5b081fe449246c612299dbc64f24ccfde6158d5bdc43c8748b5f08b82db1bc478ce408c538b398a68293e2f035\"\n    , \"ecdsaX\":\"3bac7e95a003264cc075a2ba8d4e949862acd755d49094ad8d28bd0d56299dc6\"\n    , \"ecdsaY\":\"5c6a5b3810181d82f5eb1be32c9cd8d6c387fcb06fed530d749e3997eb22bd8c\"\n    , \"ecdsaD\":\"8964e19c5ae38669db3047f6b460863f5dc6c4510d3427e33545caf9527aafcf\"\n    , \"dsaP\" : \"A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF\"\n    , \"dsaQ\" : \"E1D3391245933D68A0714ED34BBCB7A1F422B9C1\"\n    , \"dsaG\" : \"634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA\"\n    , \"dsaY\" : \"32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2\"\n    , \"dsaX\" : \"5078D4D29795CBE76D3AACFE48C9AF0BCDBEE91A\"\n    , \"concurrency\":5\n    , \"timeout\":5\n    , \"verboseLog\": false\n}\n"
  },
  {
    "path": "config.json.enc",
    "content": "{\n    \"seed\": 42\n    , \"minMsgLen\": 1\n    , \"maxMsgLen\": 512\n    , \"incrementMsg\": 1\n    , \"minKeyLen\": 1\n    , \"maxKeyLen\": 64\n    , \"incrementKey\": 1\n    , \"rsaP\":\"e999d9abbcf3ae2e3261957863bea74f4182cf27e22e4faff461c96ef19a65bf8e85aca934e18a745e64f7f2be9e150f562dda16e52e0504e4ab53f70c12ebec2ccf4e4c628356c4ebdab3398dfef6274b4c3f5b14531e4499acd0d59c5da3a03991cf8debb05799d9156ee807c6d3088e0d01d98ab45800d1b0e94712f38575\"\n    , \"rsaQ\":\"ec244a18729e63a990ddcd414d0066af68c31343bd6ac03a189baa98783436d19c455fd494f5ab10ccd9ab9d18550eed6c2929ac0465165349c175a81eaa24da2c47de1a2dbe88eb4434e7b68b32b89fc2aec6433046713a048d54b5b86766333d540b965c5bac6e4a971d7b804a5f39c8f7aae6f301468857d15fdf3d4c4fdb\"\n    , \"rsaN\":\"d77af1e9b6464e634834e85e48969f5d649eb89fa16566a54daa95135b4b3ad8be44bf8c0c1454575059627c34ddd460b4424080e87c0c816550e54f9f68b6a1daeeab2d4b6da896544a3630e044f30d640830a9ab01c5ca2d77840d534a51147b6aba70a07b3a75f76962052f2769989dc4abd6ee12eb19dc62273bddf483793cd0af625f54db606fb205e2ffa3ed8d2300b0fc6b3e63b061fa7c7d487c960f58edfce17b0ee8c14693b3a1ace8412c09ae77592b572e2bff4fffa4e40805574704f16ab1aa7e66ed3d67e76a101dae09f504c1c607c1345ab17d7c16884cf80ebff2f3702d6d81472ed378f8137c2dda5a5556c81aa5c8c31ed1a9dc3e4617\"\n    , \"rsaE\":\"11\"\n    , \"rsaD\":\"1c76beff6efefbd2fe2d8f80f64d7d6802b94ad91d826e40a26ec5c190f26cb1a23f812107ac07f883159511331a657fb25cc391290370e037a759bbca06f6929b33de9a75398c5cc62e42dd81c0b84783d5c135d9d3526643d38d59350227c569dcf57d92b0607d7c5b1061e81c747453306f77896374ead8afb4de6e29480da8b1df30a2b59a39aeb04c8118f3b2cc47f4bf1581245e8cdb687dd0b15c768de4ce74d2c86ab16f3cf08d9d6f7b8619cb9a7a8790377d55d6600f9714836db6ad90379d35d10e5c4cc552d1ad28be125bef5b081fe449246c612299dbc64f24ccfde6158d5bdc43c8748b5f08b82db1bc478ce408c538b398a68293e2f035\"\n    , \"ecdsaX\":\"3bac7e95a003264cc075a2ba8d4e949862acd755d49094ad8d28bd0d56299dc6\"\n    , \"ecdsaY\":\"5c6a5b3810181d82f5eb1be32c9cd8d6c387fcb06fed530d749e3997eb22bd8c\"\n    , \"ecdsaD\":\"8964e19c5ae38669db3047f6b460863f5dc6c4510d3427e33545caf9527aafcf\"\n    , \"concurrency\":5\n    , \"timeout\":5\n    , \"verboseLog\": true\n}\n"
  },
  {
    "path": "config.json.oaep",
    "content": "{\n    \"seed\": 5\n    , \"minMsgLen\": 2\n    , \"maxMsgLen\": 214\n    , \"incrementMsg\": 2\n    , \"minKeyLen\": 16\n    , \"maxKeyLen\": 32\n    , \"incrementKey\": 8\n    , \"rsaP\":\"e999d9abbcf3ae2e3261957863bea74f4182cf27e22e4faff461c96ef19a65bf8e85aca934e18a745e64f7f2be9e150f562dda16e52e0504e4ab53f70c12ebec2ccf4e4c628356c4ebdab3398dfef6274b4c3f5b14531e4499acd0d59c5da3a03991cf8debb05799d9156ee807c6d3088e0d01d98ab45800d1b0e94712f38575\"\n    , \"rsaQ\":\"ec244a18729e63a990ddcd414d0066af68c31343bd6ac03a189baa98783436d19c455fd494f5ab10ccd9ab9d18550eed6c2929ac0465165349c175a81eaa24da2c47de1a2dbe88eb4434e7b68b32b89fc2aec6433046713a048d54b5b86766333d540b965c5bac6e4a971d7b804a5f39c8f7aae6f301468857d15fdf3d4c4fdb\"\n    , \"rsaN\":\"d77af1e9b6464e634834e85e48969f5d649eb89fa16566a54daa95135b4b3ad8be44bf8c0c1454575059627c34ddd460b4424080e87c0c816550e54f9f68b6a1daeeab2d4b6da896544a3630e044f30d640830a9ab01c5ca2d77840d534a51147b6aba70a07b3a75f76962052f2769989dc4abd6ee12eb19dc62273bddf483793cd0af625f54db606fb205e2ffa3ed8d2300b0fc6b3e63b061fa7c7d487c960f58edfce17b0ee8c14693b3a1ace8412c09ae77592b572e2bff4fffa4e40805574704f16ab1aa7e66ed3d67e76a101dae09f504c1c607c1345ab17d7c16884cf80ebff2f3702d6d81472ed378f8137c2dda5a5556c81aa5c8c31ed1a9dc3e4617\"\n    , \"rsaE\":\"11\"\n    , \"rsaD\":\"1c76beff6efefbd2fe2d8f80f64d7d6802b94ad91d826e40a26ec5c190f26cb1a23f812107ac07f883159511331a657fb25cc391290370e037a759bbca06f6929b33de9a75398c5cc62e42dd81c0b84783d5c135d9d3526643d38d59350227c569dcf57d92b0607d7c5b1061e81c747453306f77896374ead8afb4de6e29480da8b1df30a2b59a39aeb04c8118f3b2cc47f4bf1581245e8cdb687dd0b15c768de4ce74d2c86ab16f3cf08d9d6f7b8619cb9a7a8790377d55d6600f9714836db6ad90379d35d10e5c4cc552d1ad28be125bef5b081fe449246c612299dbc64f24ccfde6158d5bdc43c8748b5f08b82db1bc478ce408c538b398a68293e2f035\"\n    , \"ecdsaX\":\"3bac7e95a003264cc075a2ba8d4e949862acd755d49094ad8d28bd0d56299dc6\"\n    , \"ecdsaY\":\"5c6a5b3810181d82f5eb1be32c9cd8d6c387fcb06fed530d749e3997eb22bd8c\"\n    , \"ecdsaD\":\"8964e19c5ae38669db3047f6b460863f5dc6c4510d3427e33545caf9527aafcf\"\n    , \"concurrency\":5\n    , \"verboseLog\": false\n}\n"
  },
  {
    "path": "config.json.prf",
    "content": "{\n    \"seed\": 42\n    , \"minMsgLen\": 1\n    , \"maxMsgLen\": 512\n    , \"incrementMsg\": 1\n    , \"minKeyLen\": 1\n    , \"maxKeyLen\": 64\n    , \"incrementKey\": 1\n    , \"rsaP\":\"e999d9abbcf3ae2e3261957863bea74f4182cf27e22e4faff461c96ef19a65bf8e85aca934e18a745e64f7f2be9e150f562dda16e52e0504e4ab53f70c12ebec2ccf4e4c628356c4ebdab3398dfef6274b4c3f5b14531e4499acd0d59c5da3a03991cf8debb05799d9156ee807c6d3088e0d01d98ab45800d1b0e94712f38575\"\n    , \"rsaQ\":\"ec244a18729e63a990ddcd414d0066af68c31343bd6ac03a189baa98783436d19c455fd494f5ab10ccd9ab9d18550eed6c2929ac0465165349c175a81eaa24da2c47de1a2dbe88eb4434e7b68b32b89fc2aec6433046713a048d54b5b86766333d540b965c5bac6e4a971d7b804a5f39c8f7aae6f301468857d15fdf3d4c4fdb\"\n    , \"rsaN\":\"d77af1e9b6464e634834e85e48969f5d649eb89fa16566a54daa95135b4b3ad8be44bf8c0c1454575059627c34ddd460b4424080e87c0c816550e54f9f68b6a1daeeab2d4b6da896544a3630e044f30d640830a9ab01c5ca2d77840d534a51147b6aba70a07b3a75f76962052f2769989dc4abd6ee12eb19dc62273bddf483793cd0af625f54db606fb205e2ffa3ed8d2300b0fc6b3e63b061fa7c7d487c960f58edfce17b0ee8c14693b3a1ace8412c09ae77592b572e2bff4fffa4e40805574704f16ab1aa7e66ed3d67e76a101dae09f504c1c607c1345ab17d7c16884cf80ebff2f3702d6d81472ed378f8137c2dda5a5556c81aa5c8c31ed1a9dc3e4617\"\n    , \"rsaE\":\"11\"\n    , \"rsaD\":\"1c76beff6efefbd2fe2d8f80f64d7d6802b94ad91d826e40a26ec5c190f26cb1a23f812107ac07f883159511331a657fb25cc391290370e037a759bbca06f6929b33de9a75398c5cc62e42dd81c0b84783d5c135d9d3526643d38d59350227c569dcf57d92b0607d7c5b1061e81c747453306f77896374ead8afb4de6e29480da8b1df30a2b59a39aeb04c8118f3b2cc47f4bf1581245e8cdb687dd0b15c768de4ce74d2c86ab16f3cf08d9d6f7b8619cb9a7a8790377d55d6600f9714836db6ad90379d35d10e5c4cc552d1ad28be125bef5b081fe449246c612299dbc64f24ccfde6158d5bdc43c8748b5f08b82db1bc478ce408c538b398a68293e2f035\"\n    , \"ecdsaX\":\"3bac7e95a003264cc075a2ba8d4e949862acd755d49094ad8d28bd0d56299dc6\"\n    , \"ecdsaY\":\"5c6a5b3810181d82f5eb1be32c9cd8d6c387fcb06fed530d749e3997eb22bd8c\"\n    , \"ecdsaD\":\"8964e19c5ae38669db3047f6b460863f5dc6c4510d3427e33545caf9527aafcf\"\n    , \"concurrency\":5\n    , \"verboseLog\": false\n}\n"
  },
  {
    "path": "examples/.gitignore",
    "content": "*\n!*.c\n!*.cpp\n!*.go\n!*.java\n!*.py\n!.gitignore\n"
  },
  {
    "path": "examples/blake2new.py",
    "content": "# encoding: utf-8\n\nimport struct, binascii, copy\nfrom ctypes import *\n\nMASK8BITS = 0xff\nMASK16BITS = 0xffff\nMASK32BITS = 0xffffffff\nMASK48BITS = 0xffffffffffff\nMASK64BITS = 0xffffffffffffffff\n\n#---------------------------------------------------------------\n\n\nclass BLAKE2(object):\n    \"\"\" BLAKE2 is a base class for BLAKE2b and BLAKE2s \"\"\"\n\n    sigma = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],\n             [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],\n             [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],\n             [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],\n             [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],\n             [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],\n             [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],\n             [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],\n             [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],\n             [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],\n             [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],\n             [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3]\n            ]  # only 1st 10 rows are used by BLAKE2s\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def __init__(self, digest_size=0, **args):\n        print(\"\"\"\n          ***********************************************\n          * You just instantiated a base class.  Please *\n          * instantiate either BLAKE2b or BLAKE2s.      *\n          ***********************************************\n        \"\"\")\n        raise Exception('base class instantiation')\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def _init(self, key=b''):\n\n        assert len(key) <= self.KEYBYTES\n\n        # load parameters\n        P = self.PARAMS()\n        P.F.digest_size = self.digest_size\n        P.F.key_length = len(key)\n        P.F.fanout = self.fanout\n        P.F.depth = self.depth\n        P.F.leaf_size = self.leaf_size\n        P.F.node_offset_lo = self.node_offset & MASK32BITS\n        P.F.node_offset_hi = self.node_offset >> 32\n        P.F.node_depth = self.node_depth\n        P.F.inner_size = self.inner_size\n        # P.F.reserved is not defined in BLAKE2s so we cannot init it \n        # to zeros for both BLAKE2s and BLAKE2b here.  Fortunately ctypes \n        # initializes to zeros so we don't have to.  :-))\n        #        P.F.reserved         = chr(0) * 14\n        P.F.salt = (self.salt + (chr(0).encode()) *\n                    (self.SALTBYTES - len(self.salt)))\n        P.F.person = (self.person + (chr(0).encode()) *\n                      (self.PERSONALBYTES - len(self.person)))\n\n        self.h = [self.IV[i] ^ P.W[i] for i in range(8)]\n\n        self.totbytes = 0\n        self.t = [0] * 2\n        self.f = [0] * 2\n        self.buflen = 0\n        self.buf = b''\n        self.finalized = False\n        self.block_size = self.BLOCKBYTES\n\n        if key:\n            block = key + (chr(0).encode()) * (self.BLOCKBYTES - len(key))\n            self.update(block)\n\n        if self.data:\n            self.update(self.data)\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def _compress(self, block):\n\n        # Dereference these for [very small] speed improvement.\n        # Perhaps more than anything, this makes the code \n        # easier to read.\n        MASKBITS = self.MASKBITS\n        WORDBITS = self.WORDBITS\n        WORDBYTES = self.WORDBYTES\n        IV = self.IV\n        sigma = self.sigma\n        ROT1 = self.ROT1\n        ROT2 = self.ROT2\n        ROT3 = self.ROT3\n        ROT4 = self.ROT4\n        WB_ROT1 = WORDBITS - ROT1\n        WB_ROT2 = WORDBITS - ROT2\n        WB_ROT3 = WORDBITS - ROT3\n        WB_ROT4 = WORDBITS - ROT4\n\n        # convert block (bytes) into 16 LE words\n        m = struct.unpack_from('<16%s' % self.WORDFMT, bytes(block))\n\n        v = [0] * 16\n        v[0:8] = self.h\n        v[8:12] = IV[:4]\n        v[12] = self.t[0] ^ IV[4]\n        v[13] = self.t[1] ^ IV[5]\n        v[14] = self.f[0] ^ IV[6]\n        v[15] = self.f[1] ^ IV[7]\n\n        # Within the confines of the Python language, this is a \n        # highly optimized version of G().  It differs some from \n        # the formal specification and reference implementation.\n        def G(a, b, c, d):\n            # dereference v[] for another small speed improvement\n            va = v[a]\n            vb = v[b]\n            vc = v[c]\n            vd = v[d]\n            va = (va + vb + msri2) & MASKBITS\n            w = vd ^ va\n            vd = (w >> ROT1) | (w << (WB_ROT1)) & MASKBITS\n            vc = (vc + vd) & MASKBITS\n            w = vb ^ vc\n            vb = (w >> ROT2) | (w << (WB_ROT2)) & MASKBITS\n            va = (va + vb + msri21) & MASKBITS\n            w = vd ^ va\n            vd = (w >> ROT3) | (w << (WB_ROT3)) & MASKBITS\n            vc = (vc + vd) & MASKBITS\n            w = vb ^ vc\n            vb = (w >> ROT4) | (w << (WB_ROT4)) & MASKBITS\n            # re-reference v[]\n            v[a] = va\n            v[b] = vb\n            v[c] = vc\n            v[d] = vd\n\n        # time to ChaCha\n        for r in range(self.ROUNDS):\n            # resolve as much as possible outside G() and \n            # don't pass as argument, let scope do its job.  \n            # Result is a 50% speed increase, but sadly, \n            # \"slow\" divided by 1.5 is still \"slow\".  :-/\n            sr = sigma[r]\n            msri2 = m[sr[0]]\n            msri21 = m[sr[1]]\n            G(0, 4, 8, 12)\n            msri2 = m[sr[2]]\n            msri21 = m[sr[3]]\n            G(1, 5, 9, 13)\n            msri2 = m[sr[4]]\n            msri21 = m[sr[5]]\n            G(2, 6, 10, 14)\n            msri2 = m[sr[6]]\n            msri21 = m[sr[7]]\n            G(3, 7, 11, 15)\n            msri2 = m[sr[8]]\n            msri21 = m[sr[9]]\n            G(0, 5, 10, 15)\n            msri2 = m[sr[10]]\n            msri21 = m[sr[11]]\n            G(1, 6, 11, 12)\n            msri2 = m[sr[12]]\n            msri21 = m[sr[13]]\n            G(2, 7, 8, 13)\n            msri2 = m[sr[14]]\n            msri21 = m[sr[15]]\n            G(3, 4, 9, 14)\n\n        self.h = [self.h[i] ^ v[i] ^ v[i + 8] for i in range(8)]\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def update(self, data):\n\n        assert self.finalized == False\n\n        BLOCKBYTES = self.BLOCKBYTES\n\n        datalen = len(data)\n        dataptr = 0\n        while True:\n            if len(self.buf) >= BLOCKBYTES:\n                self._increment_counter(BLOCKBYTES)\n                self._compress(self.buf[:BLOCKBYTES])\n                self.buf = self.buf[BLOCKBYTES:]\n            if dataptr < datalen:\n                self.buf += data[dataptr:dataptr + BLOCKBYTES]\n                dataptr += BLOCKBYTES\n            else:\n                break\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def final(self):\n        # is there any residue remaining to be processed?\n        if not self.finalized and len(self.buf):\n            self._increment_counter(len(self.buf))\n            self._set_lastblock()\n            # add padding\n            self.buf += (chr(0).encode()) * (self.BLOCKBYTES - len(self.buf))\n            # final compress\n            self._compress(self.buf)\n            self.buf = b''  # nothing more (no residue)\n            # convert 8 LE words into digest (bytestring)\n        self.digest_ = struct.pack('<8%s' % self.WORDFMT, *tuple(self.h))\n        self.finalized = True\n        return self.digest_[:self.digest_size]\n\n    digest = final\n\n    def hexdigest(self):\n        return binascii.hexlify(self.final()).decode()\n\n# - - - - - - - - - - - - - - - - - - - - - - - - - - -\n# f0 = 0 if NOT last block, 0xffffffff... if last block\n# f1 = 0 if sequential mode or (tree mode and NOT last \n#      node), 0xffffffff... if tree mode AND last node\n\n    def _set_lastblock(self):\n        if self.last_node:\n            self.f[1] = self.MASKBITS\n        self.f[0] = self.MASKBITS\n\n    def _increment_counter(self, numbytes):\n        self.totbytes += numbytes\n        self.t[0] = self.totbytes & self.MASKBITS\n        self.t[1] = self.totbytes >> self.WORDBITS\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n    # common utility functions\n\n    def copy(self):\n        return copy.deepcopy(self)\n\n\n#---------------------------------------------------------------\n\n\nclass BLAKE2b(BLAKE2):\n\n    WORDBITS = 64\n    WORDBYTES = 8\n    MASKBITS = MASK64BITS\n    WORDFMT = 'Q'  # used in _compress() and final()\n\n    ROUNDS = 12\n    BLOCKBYTES = 128\n    OUTBYTES = 64\n    KEYBYTES = 64\n    SALTBYTES = 16  # see also hardcoded value in ParamFields64\n    PERSONALBYTES = 16  # see also hardcoded value in ParamFields64\n\n    IV = [\n        0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,\n        0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,\n        0x1f83d9abfb41bd6b, 0x5be0cd19137e2179\n    ]\n\n    ROT1 = 32\n    ROT2 = 24\n    ROT3 = 16\n    ROT4 = 63\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def __init__(self,\n                 data=b'',\n                 digest_size=64,\n                 key=b'',\n                 salt=b'',\n                 person=b'',\n                 fanout=1,\n                 depth=1,\n                 leaf_size=0,\n                 node_offset=0,\n                 node_depth=0,\n                 inner_size=0,\n                 last_node=False):\n\n        assert 1 <= digest_size <= self.OUTBYTES\n        assert len(key) <= self.KEYBYTES\n        assert len(salt) <= self.SALTBYTES\n        assert len(person) <= self.PERSONALBYTES\n        assert 0 <= fanout <= MASK8BITS\n        assert 0 <= depth <= MASK8BITS\n        assert 0 <= leaf_size <= MASK32BITS\n        assert 0 <= node_offset <= MASK64BITS\n        assert 0 <= node_depth <= MASK8BITS\n        assert 0 <= inner_size <= MASK8BITS\n\n        # - - - - - - - - - - - - - - - - - - - - - - - - -\n        # use ctypes LittleEndianStructure and Union as a \n        # convenient way to organize complex structs, convert \n        # to little endian, and access by words\n        class ParamFields64(LittleEndianStructure):\n            _fields_ = [\n                (\"digest_size\", c_ubyte),\n                (\"key_length\", c_ubyte),\n                (\"fanout\", c_ubyte),\n                (\"depth\", c_ubyte),\n                (\"leaf_size\", c_uint32),\n                (\"node_offset_lo\", c_uint32),\n                (\"node_offset_hi\", c_uint32),\n                (\"node_depth\", c_ubyte),\n                (\"inner_size\", c_ubyte),\n                (\"reserved\", c_char * 14),\n                (\"salt\", c_char * 16),\n                (\"person\", c_char * 16),\n            ]\n\n        class Params64(Union):\n            _fields_ = [\n                (\"F\", ParamFields64),\n                (\"W\", c_uint64 * 8),\n            ]\n\n        # this next makes PARAMS a 'proper' instance variable\n        self.PARAMS = Params64\n\n        # key is passed as an argument; all other variables are \n        # defined as instance variables\n        self.digest_size = digest_size\n        self.data = data\n        self.salt = salt\n        self.person = person\n        self.fanout = fanout\n        self.depth = depth\n        self.leaf_size = leaf_size\n        self.node_offset = node_offset\n        self.node_depth = node_depth\n        self.inner_size = inner_size\n        self.last_node = last_node\n\n        # now call init routine common to BLAKE2b and BLAKE2s\n        self._init(key=key)\n\n\n#---------------------------------------------------------------\n\n\nclass BLAKE2s(BLAKE2):\n\n    WORDBITS = 32\n    WORDBYTES = 4\n    MASKBITS = MASK32BITS\n    WORDFMT = 'L'  # used in _compress() and final()\n\n    ROUNDS = 10\n    BLOCKBYTES = 64\n    OUTBYTES = 32\n    KEYBYTES = 32\n    SALTBYTES = 8\n    PERSONALBYTES = 8\n\n    IV = [\n        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,\n        0x1f83d9ab, 0x5be0cd19\n    ]\n\n    ROT1 = 16\n    ROT2 = 12\n    ROT3 = 8\n    ROT4 = 7\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def __init__(self,\n                 data=b'',\n                 digest_size=32,\n                 key=b'',\n                 salt=b'',\n                 person=b'',\n                 fanout=1,\n                 depth=1,\n                 leaf_size=0,\n                 node_offset=0,\n                 node_depth=0,\n                 inner_size=0,\n                 last_node=False):\n\n        assert 1 <= digest_size <= self.OUTBYTES\n        assert len(key) <= self.KEYBYTES\n        assert len(salt) <= self.SALTBYTES\n        assert len(person) <= self.PERSONALBYTES\n        assert 0 <= fanout <= MASK8BITS\n        assert 0 <= depth <= MASK8BITS\n        assert 0 <= leaf_size <= MASK32BITS\n        assert 0 <= node_offset <= MASK48BITS\n        assert 0 <= node_depth <= MASK8BITS\n        assert 0 <= inner_size <= MASK8BITS\n\n        # there is a circular class relationship having \n        # to do with defining the values of SALTBYTES and \n        # PERSONALBYTES.  By creating an empty class and \n        # loading its contents individually, we get access \n        # to the parent block's scope and have to define the \n        # field's values only once.  ...but this can look \n        # confusing.  Perhaps it is better to define the \n        # values 16 and 8 twice and annotate the second \n        # occurance. It's not like the values will be \n        # changing often.  Which is better?  BLAKE2b is \n        # defined twice and BLAKE2s uses the empty class \n        # approach.\n\n        class ParamFields32(LittleEndianStructure):\n            pass\n\n        ParamFields32.SALTBYTES = self.SALTBYTES\n        ParamFields32.PERSONALBYTES = self.PERSONALBYTES\n        ParamFields32._fields_ = [\n            (\"digest_size\", c_ubyte),\n            (\"key_length\", c_ubyte),\n            (\"fanout\", c_ubyte),\n            (\"depth\", c_ubyte),\n            (\"leaf_size\", c_uint32),\n            (\"node_offset_lo\", c_uint32),\n            (\"node_offset_hi\", c_uint16),\n            (\"node_depth\", c_ubyte),\n            (\"inner_size\", c_ubyte),\n            (\"salt\", c_char * self.SALTBYTES),\n            (\"person\", c_char * self.PERSONALBYTES),\n        ]\n\n        class Params32(Union):\n            _fields_ = [\n                (\"F\", ParamFields32),\n                (\"W\", c_uint32 * 8),\n            ]\n\n        # this next makes PARAMS union a 'proper' instance variable\n        self.PARAMS = Params32\n\n        # key is passed as an argument; all other variables are \n        # defined as instance variables\n        self.digest_size = digest_size\n        self.data = data\n        self.salt = salt\n        self.person = person\n        self.fanout = fanout\n        self.depth = depth\n        self.leaf_size = leaf_size\n        self.node_offset = node_offset\n        self.node_depth = node_depth\n        self.inner_size = inner_size\n        self.last_node = last_node\n\n        # now call init routine common to BLAKE2b and BLAKE2s\n        self._init(key=key)\n\n\n#---------------------------------------------------------------\n#---------------------------------------------------------------\n#---------------------------------------------------------------\n"
  },
  {
    "path": "examples/blake2ref.py",
    "content": "# encoding: utf-8\n\nimport struct, binascii, copy\nfrom ctypes import *\n\nMASK8BITS = 0xff\nMASK16BITS = 0xffff\nMASK32BITS = 0xffffffff\nMASK48BITS = 0xffffffffffff\nMASK64BITS = 0xffffffffffffffff\n\n#---------------------------------------------------------------\n\n\nclass BLAKE2(object):\n    \"\"\" BLAKE2 is a base class for BLAKE2b and BLAKE2s \"\"\"\n\n    sigma = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],\n             [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],\n             [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],\n             [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],\n             [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],\n             [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],\n             [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],\n             [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],\n             [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],\n             [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],\n             [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],\n             [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3]\n            ]  # only 1st 10 rows are used by BLAKE2s\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def __init__(self, digest_size=0, **args):\n        print(\"\"\"\n          ***********************************************\n          * You just instantiated a base class.  Please *\n          * instantiate either BLAKE2b or BLAKE2s.      *\n          ***********************************************\n        \"\"\")\n        raise Exception('base class instantiation')\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def _init(self, key=b''):\n\n        assert len(key) <= self.KEYBYTES\n\n        # load parameters\n        P = self.PARAMS()\n        P.F.digest_size = self.digest_size\n        P.F.key_length = len(key)\n        P.F.fanout = self.fanout\n        P.F.depth = self.depth\n        P.F.leaf_size = self.leaf_size\n        P.F.node_offset_lo = self.node_offset & MASK32BITS\n        P.F.node_offset_hi = self.node_offset >> 32\n        P.F.node_depth = self.node_depth\n        P.F.inner_size = self.inner_size\n        # P.F.reserved is not defined in BLAKE2s so we cannot init it \n        # to zeros for both BLAKE2s and BLAKE2b here.  Fortunately ctypes \n        # initializes to zeros so we don't have to.  :-))\n        #        P.F.reserved         = chr(0) * 14\n        P.F.salt = (self.salt + (chr(0).encode()) *\n                    (self.SALTBYTES - len(self.salt)))\n        P.F.person = (self.person + (chr(0).encode()) *\n                      (self.PERSONALBYTES - len(self.person)))\n\n        self.h = [self.IV[i] ^ P.W[i] for i in range(8)]\n\n        self.totbytes = 0\n        self.t = [0] * 2\n        self.f = [0] * 2\n        self.buflen = 0\n        self.buf = b''\n        self.finalized = False\n        self.block_size = self.BLOCKBYTES\n\n        if key:\n            block = key + (chr(0).encode()) * (self.BLOCKBYTES - len(key))\n            self.update(block)\n\n        if self.data:\n            self.update(self.data)\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def _compress(self, block):\n\n        # Dereference these for [very small] speed improvement.\n        # Perhaps more than anything, this makes the code \n        # easier to read.\n        MASKBITS = self.MASKBITS\n        WORDBITS = self.WORDBITS\n        WORDBYTES = self.WORDBYTES\n        IV = self.IV\n        sigma = self.sigma\n        ROT1 = self.ROT1\n        ROT2 = self.ROT2\n        ROT3 = self.ROT3\n        ROT4 = self.ROT4\n        WB_ROT1 = WORDBITS - ROT1\n        WB_ROT2 = WORDBITS - ROT2\n        WB_ROT3 = WORDBITS - ROT3\n        WB_ROT4 = WORDBITS - ROT4\n\n        # convert block (bytes) into 16 LE words\n        m = struct.unpack_from('<16%s' % self.WORDFMT, bytes(block))\n\n        v = [0] * 16\n        v[0:8] = self.h\n        v[8:12] = IV[:4]\n        v[12] = self.t[0] ^ IV[4]\n        v[13] = self.t[1] ^ IV[5]\n        v[14] = self.f[0] ^ IV[6]\n        v[15] = self.f[1] ^ IV[7]\n\n        # Within the confines of the Python language, this is a \n        # highly optimized version of G().  It differs some from \n        # the formal specification and reference implementation.\n        def G(a, b, c, d):\n            # dereference v[] for another small speed improvement\n            va = v[a]\n            vb = v[b]\n            vc = v[c]\n            vd = v[d]\n            va = (va + vb + msri2) & MASKBITS\n            w = vd ^ va\n            vd = (w >> ROT1) | (w << (WB_ROT1)) & MASKBITS\n            vc = (vc + vd) & MASKBITS\n            w = vb ^ vc\n            vb = (w >> ROT2) | (w << (WB_ROT2)) & MASKBITS\n            va = (va + vb + msri21) & MASKBITS\n            w = vd ^ va\n            vd = (w >> ROT3) | (w << (WB_ROT3)) & MASKBITS\n            vc = (vc + vd) & MASKBITS\n            w = vb ^ vc\n            vb = (w >> ROT4) | (w << (WB_ROT4)) & MASKBITS\n            # re-reference v[]\n            v[a] = va\n            v[b] = vb\n            v[c] = vc\n            v[d] = vd\n\n        # time to ChaCha\n        for r in range(self.ROUNDS):\n            # resolve as much as possible outside G() and \n            # don't pass as argument, let scope do its job.  \n            # Result is a 50% speed increase, but sadly, \n            # \"slow\" divided by 1.5 is still \"slow\".  :-/\n            sr = sigma[r]\n            msri2 = m[sr[0]]\n            msri21 = m[sr[1]]\n            G(0, 4, 8, 12)\n            msri2 = m[sr[2]]\n            msri21 = m[sr[3]]\n            G(1, 5, 9, 13)\n            msri2 = m[sr[4]]\n            msri21 = m[sr[5]]\n            G(2, 6, 10, 14)\n            msri2 = m[sr[6]]\n            msri21 = m[sr[7]]\n            G(3, 7, 11, 15)\n            msri2 = m[sr[8]]\n            msri21 = m[sr[9]]\n            G(0, 5, 10, 15)\n            msri2 = m[sr[10]]\n            msri21 = m[sr[11]]\n            G(1, 6, 11, 12)\n            msri2 = m[sr[12]]\n            msri21 = m[sr[13]]\n            G(2, 7, 8, 13)\n            msri2 = m[sr[14]]\n            msri21 = m[sr[15]]\n            G(3, 4, 9, 14)\n\n        self.h = [self.h[i] ^ v[i] ^ v[i + 8] for i in range(8)]\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def update(self, data):\n\n        assert self.finalized == False\n\n        BLOCKBYTES = self.BLOCKBYTES\n\n        datalen = len(data)\n        dataptr = 0\n        while True:\n            if len(self.buf) > BLOCKBYTES:\n                self._increment_counter(BLOCKBYTES)\n                self._compress(self.buf[:BLOCKBYTES])\n                self.buf = self.buf[BLOCKBYTES:]\n            if dataptr < datalen:\n                self.buf += data[dataptr:dataptr + BLOCKBYTES]\n                dataptr += BLOCKBYTES\n            else:\n                break\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def final(self):\n        # is there any residue remaining to be processed?\n        if not self.finalized and len(self.buf):\n            self._increment_counter(len(self.buf))\n            self._set_lastblock()\n            # add padding\n            self.buf += (chr(0).encode()) * (self.BLOCKBYTES - len(self.buf))\n            # final compress\n            self._compress(self.buf)\n            self.buf = b''  # nothing more (no residue)\n            # convert 8 LE words into digest (bytestring)\n        self.digest_ = struct.pack('<8%s' % self.WORDFMT, *tuple(self.h))\n        self.finalized = True\n        return self.digest_[:self.digest_size]\n\n    digest = final\n\n    def hexdigest(self):\n        return binascii.hexlify(self.final()).decode()\n\n# - - - - - - - - - - - - - - - - - - - - - - - - - - -\n# f0 = 0 if NOT last block, 0xffffffff... if last block\n# f1 = 0 if sequential mode or (tree mode and NOT last \n#      node), 0xffffffff... if tree mode AND last node\n\n    def _set_lastblock(self):\n        if self.last_node:\n            self.f[1] = self.MASKBITS\n        self.f[0] = self.MASKBITS\n\n    def _increment_counter(self, numbytes):\n        self.totbytes += numbytes\n        self.t[0] = self.totbytes & self.MASKBITS\n        self.t[1] = self.totbytes >> self.WORDBITS\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n    # common utility functions\n\n    def copy(self):\n        return copy.deepcopy(self)\n\n\n#---------------------------------------------------------------\n\n\nclass BLAKE2b(BLAKE2):\n\n    WORDBITS = 64\n    WORDBYTES = 8\n    MASKBITS = MASK64BITS\n    WORDFMT = 'Q'  # used in _compress() and final()\n\n    ROUNDS = 12\n    BLOCKBYTES = 128\n    OUTBYTES = 64\n    KEYBYTES = 64\n    SALTBYTES = 16  # see also hardcoded value in ParamFields64\n    PERSONALBYTES = 16  # see also hardcoded value in ParamFields64\n\n    IV = [\n        0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,\n        0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,\n        0x1f83d9abfb41bd6b, 0x5be0cd19137e2179\n    ]\n\n    ROT1 = 32\n    ROT2 = 24\n    ROT3 = 16\n    ROT4 = 63\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def __init__(self,\n                 data=b'',\n                 digest_size=64,\n                 key=b'',\n                 salt=b'',\n                 person=b'',\n                 fanout=1,\n                 depth=1,\n                 leaf_size=0,\n                 node_offset=0,\n                 node_depth=0,\n                 inner_size=0,\n                 last_node=False):\n\n        assert 1 <= digest_size <= self.OUTBYTES\n        assert len(key) <= self.KEYBYTES\n        assert len(salt) <= self.SALTBYTES\n        assert len(person) <= self.PERSONALBYTES\n        assert 0 <= fanout <= MASK8BITS\n        assert 0 <= depth <= MASK8BITS\n        assert 0 <= leaf_size <= MASK32BITS\n        assert 0 <= node_offset <= MASK64BITS\n        assert 0 <= node_depth <= MASK8BITS\n        assert 0 <= inner_size <= MASK8BITS\n\n        # - - - - - - - - - - - - - - - - - - - - - - - - -\n        # use ctypes LittleEndianStructure and Union as a \n        # convenient way to organize complex structs, convert \n        # to little endian, and access by words\n        class ParamFields64(LittleEndianStructure):\n            _fields_ = [\n                (\"digest_size\", c_ubyte),\n                (\"key_length\", c_ubyte),\n                (\"fanout\", c_ubyte),\n                (\"depth\", c_ubyte),\n                (\"leaf_size\", c_uint32),\n                (\"node_offset_lo\", c_uint32),\n                (\"node_offset_hi\", c_uint32),\n                (\"node_depth\", c_ubyte),\n                (\"inner_size\", c_ubyte),\n                (\"reserved\", c_char * 14),\n                (\"salt\", c_char * 16),\n                (\"person\", c_char * 16),\n            ]\n\n        class Params64(Union):\n            _fields_ = [\n                (\"F\", ParamFields64),\n                (\"W\", c_uint64 * 8),\n            ]\n\n        # this next makes PARAMS a 'proper' instance variable\n        self.PARAMS = Params64\n\n        # key is passed as an argument; all other variables are \n        # defined as instance variables\n        self.digest_size = digest_size\n        self.data = data\n        self.salt = salt\n        self.person = person\n        self.fanout = fanout\n        self.depth = depth\n        self.leaf_size = leaf_size\n        self.node_offset = node_offset\n        self.node_depth = node_depth\n        self.inner_size = inner_size\n        self.last_node = last_node\n\n        # now call init routine common to BLAKE2b and BLAKE2s\n        self._init(key=key)\n\n\n#---------------------------------------------------------------\n\n\nclass BLAKE2s(BLAKE2):\n\n    WORDBITS = 32\n    WORDBYTES = 4\n    MASKBITS = MASK32BITS\n    WORDFMT = 'L'  # used in _compress() and final()\n\n    ROUNDS = 10\n    BLOCKBYTES = 64\n    OUTBYTES = 32\n    KEYBYTES = 32\n    SALTBYTES = 8\n    PERSONALBYTES = 8\n\n    IV = [\n        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,\n        0x1f83d9ab, 0x5be0cd19\n    ]\n\n    ROT1 = 16\n    ROT2 = 12\n    ROT3 = 8\n    ROT4 = 7\n\n    # - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n    def __init__(self,\n                 data=b'',\n                 digest_size=32,\n                 key=b'',\n                 salt=b'',\n                 person=b'',\n                 fanout=1,\n                 depth=1,\n                 leaf_size=0,\n                 node_offset=0,\n                 node_depth=0,\n                 inner_size=0,\n                 last_node=False):\n\n        assert 1 <= digest_size <= self.OUTBYTES\n        assert len(key) <= self.KEYBYTES\n        assert len(salt) <= self.SALTBYTES\n        assert len(person) <= self.PERSONALBYTES\n        assert 0 <= fanout <= MASK8BITS\n        assert 0 <= depth <= MASK8BITS\n        assert 0 <= leaf_size <= MASK32BITS\n        assert 0 <= node_offset <= MASK48BITS\n        assert 0 <= node_depth <= MASK8BITS\n        assert 0 <= inner_size <= MASK8BITS\n\n        # there is a circular class relationship having \n        # to do with defining the values of SALTBYTES and \n        # PERSONALBYTES.  By creating an empty class and \n        # loading its contents individually, we get access \n        # to the parent block's scope and have to define the \n        # field's values only once.  ...but this can look \n        # confusing.  Perhaps it is better to define the \n        # values 16 and 8 twice and annotate the second \n        # occurance. It's not like the values will be \n        # changing often.  Which is better?  BLAKE2b is \n        # defined twice and BLAKE2s uses the empty class \n        # approach.\n\n        class ParamFields32(LittleEndianStructure):\n            pass\n\n        ParamFields32.SALTBYTES = self.SALTBYTES\n        ParamFields32.PERSONALBYTES = self.PERSONALBYTES\n        ParamFields32._fields_ = [\n            (\"digest_size\", c_ubyte),\n            (\"key_length\", c_ubyte),\n            (\"fanout\", c_ubyte),\n            (\"depth\", c_ubyte),\n            (\"leaf_size\", c_uint32),\n            (\"node_offset_lo\", c_uint32),\n            (\"node_offset_hi\", c_uint16),\n            (\"node_depth\", c_ubyte),\n            (\"inner_size\", c_ubyte),\n            (\"salt\", c_char * self.SALTBYTES),\n            (\"person\", c_char * self.PERSONALBYTES),\n        ]\n\n        class Params32(Union):\n            _fields_ = [\n                (\"F\", ParamFields32),\n                (\"W\", c_uint32 * 8),\n            ]\n\n        # this next makes PARAMS union a 'proper' instance variable\n        self.PARAMS = Params32\n\n        # key is passed as an argument; all other variables are \n        # defined as instance variables\n        self.digest_size = digest_size\n        self.data = data\n        self.salt = salt\n        self.person = person\n        self.fanout = fanout\n        self.depth = depth\n        self.leaf_size = leaf_size\n        self.node_offset = node_offset\n        self.node_depth = node_depth\n        self.inner_size = inner_size\n        self.last_node = last_node\n\n        # now call init routine common to BLAKE2b and BLAKE2s\n        self._init(key=key)\n\n\n#---------------------------------------------------------------\n#---------------------------------------------------------------\n#---------------------------------------------------------------\n"
  },
  {
    "path": "examples/dsa_sha256_cryptopp.cpp",
    "content": "#include <cryptopp/cryptlib.h>\n#include <cryptopp/dsa.h>\n#include <cryptopp/files.h>\n#include <cryptopp/filters.h>\n#include <cryptopp/hex.h>\n#include <cryptopp/osrng.h>\n#include <cryptopp/sha.h>\n#include <cryptopp/trunhash.h>\n\n#include <iomanip>\n#include <iostream>\nusing std::cout;\nusing std::cerr;\nusing std::endl;\n\nusing CryptoPP::Integer;\nusing CryptoPP::DSA2;\nusing CryptoPP::SHA256;\nusing CryptoPP::StringSource;\nusing CryptoPP::StringSink;\nusing CryptoPP::SignerFilter;\nusing CryptoPP::SignatureVerificationFilter;\nusing CryptoPP::HexEncoder;\nusing CryptoPP::HexDecoder;\nusing CryptoPP::Redirector;\nusing CryptoPP::ArraySink;\n\ntypedef DSA2<SHA256> DSA;\n//typedef DSA2<CryptoPP::NullHash> DSA0; // in order to implement the -h flag later. It appears finally NullHash is not the identity function, TODO: look into another solution\n\n#include <string>\nusing std::string;\n\n// for optget:\n#include <unistd.h>\n\nbool signing;\n\nint main(int argc, char* argv[])\n{\n\n    // Our args\n    int optind = 1;\n    /*\n       string hash;\n       int hash_provided = 0;\n    // To handle the flags:\n    int c;\n    extern char* optarg;\n    extern int optind, optopt, opterr;\n    while ((c = getopt(argc, argv, \":h:\")) != -1) {\n    switch (c) {\n    case 'h':\n    StringSource(string(optarg), true,\n    new HexDecoder(\n    new StringSink(hash)));\n    hash_provided = 1;\n    break;\n    case ':':\n    // -h without hash\n    printf(\"-h without blen\");\n    return 1;\n    break;\n    case '?':\n    printf(\"unknown arg %c\\n\", optopt);\n    return 1;\n    break;\n    }\n    }\n    */\n    if (argc - optind == 6) {\n        signing = 1;\n    } else if (argc - optind == 7) {\n        signing = 0;\n    } else {\n        cout << \"usage: \\t\" << argv[0] << \" P, Q, G, Y, X, Msg\\nor \\t\"\n            << argv[0] << \" P, Q, G, Y, R, S, Msg\\n\"\n            << endl;\n        return 1;\n    }\n    try {\n\n        const Integer P(string(argv[optind]).append(\"h\").c_str());\n        const Integer Q(string(argv[optind + 1]).append(\"h\").c_str());\n        const Integer G(string(argv[optind + 2]).append(\"h\").c_str());\n        const Integer Y(string(argv[optind + 3]).append(\"h\").c_str());\n\n        string message;\n        StringSource(string(argv[argc - 1]), true,\n                new HexDecoder(\n                    new StringSink(message)));\n        string signature;\n\n        DSA::PrivateKey privateKey;\n        DSA::PublicKey publicKey;\n\n        CryptoPP::AutoSeededRandomPool rng;\n        privateKey.Initialize(rng, P, Q, G);\n        publicKey.AssignFrom(privateKey);\n        publicKey.SetPublicElement(Y);\n        if (signing) {\n            const Integer X(string(argv[optind + 4]).append(\"h\").c_str());\n\n            privateKey.SetPrivateExponent(X);\n            if (!privateKey.Validate(rng, 3)) {\n                cerr << \"DSA privateKey key validation failed after setting private parameter.\" << endl;\n                return 1;\n            }\n\n            DSA::Signer signer(privateKey);\n            StringSource ss1(message, true,\n                    new SignerFilter(rng, signer,\n                        new HexEncoder(new StringSink(signature), false)) // SignerFilter\n                    ); // StringSource\n\n            int slen = signature.length() / 2;\n            // Transorming from IEEE P1363 format into r and s:\n            cout << signature.substr(0, slen) << \"\\n\"\n                << signature.substr(slen, slen) << endl;\n\n        } else {\n            if (!publicKey.Validate(rng, 3)) {\n                cerr << \"DSA publicKey key validation failed\" << endl;\n                return 1;\n            }\n\n            // Transorming into IEEE P1363 format:\n            StringSource(string(argv[optind + 4]) + string(argv[optind + 5]), true,\n                    new HexDecoder(\n                        new StringSink(signature)));\n\n            DSA::Verifier verifier(publicKey);\n            bool result = false;\n\n            StringSource ss(message + signature, true,\n                    new SignatureVerificationFilter(\n                        verifier,\n                        new ArraySink(\n                            (byte*)&result, sizeof(result)),\n                        SignatureVerificationFilter::PUT_RESULT | SignatureVerificationFilter::SIGNATURE_AT_END));\n\n            if (true == result) {\n                cout << \"true\" << endl;\n            } else {\n                cout << \"false\" << endl;\n            }\n        }\n\n    } catch (CryptoPP::Exception& e) {\n        cout << \"ERROR\" << endl;\n        cerr << e.what() << endl;\n        return 1;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "examples/dsa_sha256_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/dsa\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"flag\"\n\t\"fmt\"\n\t\"hash\"\n\t\"log\"\n\t\"math/big\"\n\t\"strings\"\n)\n\nvar custom_hash = flag.String(\"h\", \"\", \"If one want to specifiy the hash directly\")\n\n// fromBase16 is a helper method to use the prime in hex form, inspired from crypto/rsa/rsa_test.go\nfunc fromBase16(base16 string) *big.Int {\n\ti, ok := new(big.Int).SetString(base16, 16)\n\tif !ok {\n\t\tlog.Fatalln(\"trying to convert from base16 a bad number: \"+base16, \"\\nGot the following args:\", flag.Args())\n\t}\n\treturn i\n}\n\nfunc main() {\n\tflag.Parse()\n\t// The hash used\n\tvar h hash.Hash\n\th = sha256.New()\n\n\tvar signing bool\n\n\tswitch {\n\tcase len(flag.Args()) == 7:\n\t\tsigning = false\n\tcase len(flag.Args()) == 6:\n\t\tsigning = true\n\tdefault:\n\t\tlog.Fatal(\"Please provide P, Q, G, Y, X, Msg or P, Q, G, Y, R, S, Msg as arguments in order to respectively sign Msg or verify a signature for Msg.\")\n\t}\n\n\t// Key instanciation\n\tprivatekey := new(dsa.PrivateKey)\n\tpubkey := new(dsa.PublicKey)\n\n\tpubkey.P = fromBase16(flag.Arg(0))\n\tpubkey.Q = fromBase16(flag.Arg(1))\n\tpubkey.G = fromBase16(flag.Arg(2))\n\tpubkey.Y = fromBase16(flag.Arg(3))\n\t// we need the byte length of the subgroup to comply to FIPS 186-3 sec. 4.6\n\t//  recommended truncation.\n\thlen := (pubkey.Q.BitLen() + 7) / 8\n\n\t// msg is always in latest position\n\t// we are decoding from hex to have truly random messages\n\tmsg, err := hex.DecodeString(flag.Arg(len(flag.Args()) - 1))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tr := big.NewInt(0)\n\ts := big.NewInt(0)\n\n\t// We handle the hashing of the data:\n\th.Write(msg)\n\tvar signhash []byte\n\tif *custom_hash == \"\" { // if the flag -h is not set, its default is \"\" and we hash the message\n\t\tsignhash = h.Sum(nil)\n\t} else {\n\t\tvar err error\n\t\tsignhash, err = hex.DecodeString(*custom_hash)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\tif signing {\n\t\t// private key instanciation:\n\t\tprivatekey.PublicKey = *pubkey\n\t\tprivatekey.X = fromBase16(flag.Arg(4))\n\n\t\t// If signhash is longer than the byte-length of the subgroup, it should\n\t\t//  be truncated to that length as per FIPS 186-3 sec. 4.6, but Sign does\n\t\t//  not handle this directly. It returns the signature as a pair of big integers.\n\t\tr, s, serr := dsa.Sign(rand.Reader, privatekey, signhash[:hlen])\n\t\tif serr != nil {\n\t\t\tlog.Fatalln(serr)\n\t\t}\n\n\t\t// We first output R, then S with a newline in between as required by\n\t\t//  the ECDSA interface\n\t\tanswerR := leftPad(r.Text(16), 20)\n\t\tanswerS := leftPad(s.Text(16), 20)\n\t\tfmt.Printf(\"%s\\n%s\\n\", answerR, answerS)\n\t} else {\n\t\t// if we are not signing, we are verifying :\n\t\tr = fromBase16(flag.Arg(4))\n\t\ts = fromBase16(flag.Arg(5))\n\t\tverifystatus := dsa.Verify(pubkey, signhash[:hlen], r, s)\n\t\tfmt.Println(verifystatus)\n\t}\n}\n\n// leftPad will ensure the string are in hexadecimal form and satisfy with the\n//  DSA signature length of 160bits.\nfunc leftPad(text string, size int) string {\n\tn := len(text)\n\tsize = 2 * size\n\tif n > size {\n\t\tn = size\n\t}\n\treturn strings.Repeat(\"0\", size-n) + text\n}\n"
  },
  {
    "path": "examples/dsa_sha256_java.java",
    "content": "// Please, note that you will need to add a folder called libs here and put\n//  the bouncycastle file bcprov-jdk15on-155.jar in it.\n// Otherwise the wrapper and the makefile won't work.\nimport java.security.PrivateKey;\nimport java.security.PublicKey;\nimport java.security.KeyFactory;\nimport java.security.SecureRandom;\nimport java.security.Security;\nimport java.math.BigInteger;\nimport org.bouncycastle.jce.provider.BouncyCastleProvider;\n\nimport javax.crypto.Cipher;\nimport javax.xml.bind.DatatypeConverter;\nimport java.security.KeyPairGenerator;\nimport java.security.KeyPair;\nimport java.security.Signature;\nimport java.security.interfaces.DSAPrivateKey;\nimport java.security.interfaces.DSAPublicKey;\nimport java.security.spec.DSAPrivateKeySpec;\nimport java.security.spec.DSAPublicKeySpec;\nimport org.bouncycastle.crypto.params.DSAKeyParameters;\nimport org.bouncycastle.crypto.params.DSAPublicKeyParameters;\nimport org.bouncycastle.crypto.params.DSAPrivateKeyParameters;\nimport org.bouncycastle.crypto.params.DSAParameters;\nimport java.util.Arrays;\n\nimport org.bouncycastle.crypto.params.DSAKeyGenerationParameters;\nimport org.bouncycastle.crypto.generators.DSAKeyPairGenerator;\nimport org.bouncycastle.crypto.AsymmetricCipherKeyPair;\n\npublic class dsa_sha256_java {\n\n    public static byte[] toByteArray(String s) {\n        return DatatypeConverter.parseHexBinary(s);\n    }\n\n    private static BigInteger extractR(byte[] signature) throws Exception {\n        int lengthR = signature[3];\n        return new BigInteger(Arrays.copyOfRange(signature, 4, 4 + lengthR));\n    }\n\n    private static BigInteger extractS(byte[] signature) throws Exception {\n        int lengthR = signature[3];\n        int startS = 4 + lengthR;\n        int lengthS = signature[startS + 1];\n        return new BigInteger(Arrays.copyOfRange(signature, startS + 2, startS + 2 + lengthS));\n    }\n\n    public static void main(String[] args) throws Exception {\n        Security.addProvider(new BouncyCastleProvider());\n        SecureRandom random = new SecureRandom();\n\n        if (args.length != 7 && args.length != 6) {\n            System.out.println(args.length);\n            throw new Exception(\"Wrong args length\");\n        }\n\n        //        Cipher cipher = Cipher.getInstance(\"RSA/None/OAEPWithSHA1AndMGF1Padding\", \"BC\");\n        //        KeyFactory kf = KeyFactory.getInstance(\"RSA\");\n\n        byte[] input = toByteArray(args[args.length-1]);\n        BigInteger p = new BigInteger(args[0], 16);\n        BigInteger q = new BigInteger(args[1], 16);\n        BigInteger g = new BigInteger(args[2], 16);\n\n        KeyFactory kf = KeyFactory.getInstance(\"DSA\");\n        Signature signer = Signature.getInstance(\"SHA256WITHDSA\");\n\n        if (args.length ==  6) {\n            BigInteger y = new BigInteger(args[3], 16);\n            BigInteger x = new BigInteger(args[4], 16);\n\n            DSAPrivateKey priv = (DSAPrivateKey) kf.generatePrivate(new DSAPrivateKeySpec(x, p, q, g));\n\n//            DSAParameters paramdsa = new DSAParameters(p, q, g) ;\n//            DSAKeyGenerationParameters test = new DSAKeyGenerationParameters(new SecureRandom(),paramdsa);\n//            DSAKeyPairGenerator gen = new DSAKeyPairGenerator();\n//            gen.init(test);\n//            AsymmetricCipherKeyPair testGenKey = (AsymmetricCipherKeyPair) gen.generateKeyPair();\n//            DSAKeyParameters testKey = (DSAKeyParameters) testGenKey.getPublic();\n//            System.out.println(testKey.getParameters().getG());\n\n            signer.initSign(priv);\n            // generate a signature\n            signer.update(input);\n            byte[] signature = signer.sign();\n\n            String r = String.format(\"%040x\", (extractR(signature)));\n            String s = String.format(\"%040x\", (extractS(signature)));\n            System.out.println(r);\n            System.out.println(s);\n        } else {\n            BigInteger y = new BigInteger(args[3], 16);\n            BigInteger r = new BigInteger(args[4], 16);\n            BigInteger s = new BigInteger(args[5], 16);\n\n            DSAPublicKey pubKey = (DSAPublicKey) kf.generatePublic(new DSAPublicKeySpec(y, p, q, g));\n            // verify a signature\n            signer.initVerify(pubKey);\n            signer.update(input);\n            // need to change that to use our values\n            // convert (r, s) to ASN.1 DER encoding\n            // assuming you have r and s as !!positive!! BigIntegers\n            byte[] rb = r.toByteArray();\n            byte[] sb = s.toByteArray(); // sign-padded if necessary\n            // these lines are more verbose than necessary to show the structure\n            // compiler will fold or you can do so yourself \n            int off = (2 + 2) + rb.length;\n            int tot = off + (2 - 2) + sb.length;\n            byte[] der = new byte[tot + 2];\n            der[0] = 0x30;\n            der[1] = (byte) (tot & 0xff);\n            der[2 + 0] = 0x02;\n            der[2 + 1] = (byte) (rb.length & 0xff);\n            System.arraycopy(rb, 0, der, 2 + 2, rb.length);\n            der[off + 0] = 0x02;\n            der[off + 1] = (byte) (sb.length & 0xff);\n            System.arraycopy(sb, 0, der, off + 2, sb.length);\n            if (signer.verify(der))\n            {\n                System.out.println(\"true\");\n            }\n            else\n            {\n                System.out.println(\"false\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/dsa_sha256_java_wrapper.go",
    "content": "// Please, note that you will need to add a folder called libs here and put\n//  the bouncycastle file bcprov-jdk15on-156.jar in it.\n// Otherwise the wrapper and the makefile won't work.\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\nfunc main() {\n\targ := []string{\"-cp\", \"./:./examples/:./examples/libs/bcprov-jdk15on-156.jar:./libs/bcprov-jdk15on-156.jar\", \"dsa_sha256_java\"}\n\targ = append(arg, os.Args[1:]...)\n\n\tcmd := exec.Command(\"java\", arg...)\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\tfmt.Println(strings.TrimSpace(string(out)))\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(strings.TrimSpace(string(out)))\n}\n"
  },
  {
    "path": "examples/dsa_sha256_openssl.c",
    "content": "#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"openssl/bn.h\"\n#include \"openssl/dsa.h\"\n#include \"openssl/engine.h\"\n#include \"openssl/sha.h\"\n\n#define HASH_SIZE 32\n\nvoid unhex(char* hex, unsigned char* in, size_t ilen)\n{\n    for (size_t i = 0; i < ilen; ++i) {\n        sscanf(hex, \"%2hhx\", &in[i]);\n        hex += 2;\n    }\n}\n\nvoid printBN(BIGNUM *r)\n{\n        char* out = BN_bn2hex(r);\n        const char *padding=\"00000000000000000000000000000000000000000\";\n        int padLen1 = 40 - strlen(out);\n        if(padLen1 < 0) padLen1 = 0;\n        printf(\"%*.*s%s\\n\", padLen1, padLen1, padding, out);\n        OPENSSL_free(out);\n}\n\nint main(int argc, char* argv[])\n{\n\n    // Our args\n    size_t blen = 0;\n\n    int success = 0;\n    uint8_t* hash;\n    int signing;\n    int hash_provided = 0;\n\n    // To handle the flags:\n    int c;\n    extern char* optarg;\n    extern int optind, optopt, opterr;\n    while ((c = getopt(argc, argv, \":h:\")) != -1) {\n        switch (c) {\n        case 'h':\n            hash = (uint8_t*)malloc(strlen(optarg) / 2);\n            blen = strlen(optarg) / 2;\n            unhex(optarg, hash, blen); // unsafe for the memory, if optarg is bigger than hash!\n            hash_provided = 1;\n            break;\n        case ':':\n            // -h without hash\n            printf(\"-h without hash\");\n            success = -1;\n            break;\n        case '?':\n            printf(\"unknown arg %c\\n\", optopt);\n            success = -1;\n            break;\n        }\n    }\n\n    if (argc - optind == 6) {\n        signing = 1;\n    } else if (argc - optind == 7) {\n        signing = 0;\n    } else {\n        printf(\"usage: \\t%s P, Q, G, Y, X, Msg\\nor \\t%s P, Q, G, Y, R, S, Msg\\n\", argv[0], argv[0]);\n        return -1;\n    }\n\n    // Handle the hash value\n    if (hash_provided != 1) { // then we must hash our message, flag -h not provided\n        size_t tlen = strlen(argv[argc - 1]) / 2; // since it is an hexa string\n        uint8_t* nhex = (uint8_t*)malloc(tlen);\n        unhex(argv[argc - 1], nhex, tlen); // we convert from hex to bin\n        hash = (uint8_t*)malloc(HASH_SIZE);\n        SHA256(nhex, tlen, hash);\n        free(nhex);\n        blen = HASH_SIZE;\n    }\n    // OpenSSL stuff:\n    int ret;\n    DSA_SIG* sig;\n    DSA* key = DSA_new();\n\n    BIGNUM* x = BN_new();\n    BIGNUM* y = BN_new();\n\n    BIGNUM* p = BN_new();\n    BIGNUM* q = BN_new();\n    BIGNUM* g = BN_new();\n\n    if (!BN_hex2bn(&p, argv[optind])) {\n        printf(\"Problem while decoding p:\\n%s\\n\", argv[optind]);\n        return -1;\n    }\n\n    if (!BN_hex2bn(&q, argv[optind + 1])) {\n        printf(\"Problem while decoding q:\\n%s\\n\", argv[optind + 1]);\n        return -1;\n    }\n    if (!BN_hex2bn(&g, argv[optind + 2])) {\n        printf(\"Problem while decoding g:\\n%s\\n\", argv[optind + 2]);\n        return -1;\n    }\n    if (!BN_hex2bn(&y, argv[optind + 3])) {\n        printf(\"Problem while decoding y:\\n%s\\n\", argv[optind + 3]);\n        return -1;\n    }\n\n    key->p = BN_dup(p);\n    key->q = BN_dup(q);\n    key->g = BN_dup(g);\n    key->pub_key = BN_dup(y);\n\n    if (signing) {\n        if (!BN_hex2bn(&x, argv[optind + 4])) {\n            printf(\"Problem while decoding x:\\n%s\\n\", argv[optind + 4]);\n            return -1;\n        }\n        key->priv_key = BN_dup(x);\n\n        sig = DSA_do_sign(hash, blen, key);\n        if (sig == NULL) {\n            printf(\"Failed to sign with those args.\\n\");\n            return -1;\n        }\n\n        printBN(sig->r);\n        printBN(sig->s);\n\n    } else {\n        sig = DSA_SIG_new();\n        if (!BN_hex2bn(&sig->r, argv[optind + 4])) {\n            printf(\"Problem while decoding r:\\n%s\\n\", argv[optind + 4]);\n            return -1;\n        }\n        if (!BN_hex2bn(&sig->s, argv[optind + 5])) {\n            printf(\"Problem while decoding s:\\n%s\\n\", argv[optind + 5]);\n            return -1;\n        }\n        key->priv_key = NULL; // since we are verifying\n        ret = DSA_do_verify(hash, blen, sig, key);\n        if (ret == -1) {\n            /* error */\n            printf(\" failure DSA_do_verify returned -1\");\n            success = -1;\n        } else if (ret == 0) /* then the signature is wrong */\n        {\n            printf(\"False\\n\");\n        } else /* ret == 1, so signature is okay */\n        {\n            printf(\"True\\n\");\n        }\n    }\n\n    DSA_SIG_free(sig);\n    DSA_free(key);\n    BN_free(x);\n    BN_free(y);\n    BN_free(p);\n    BN_free(q);\n    BN_free(g);\n\n    free(hash);\n\n    return success;\n}\n"
  },
  {
    "path": "examples/dsa_sha256_pycrypto.py",
    "content": "#!/usr/bin/env python3\n\nfrom Crypto.Random import random\nfrom Crypto.PublicKey import DSA\nfrom Crypto.Hash import SHA256\nimport sys\nimport binascii\n\nif len(sys.argv) == 8:\n    signing = False\nelif len(sys.argv) == 7:\n    signing = True\nelse:\n    print(\"Please provide P, Q, G, Y, X, Msg or P, Q, G, Y, R, S, Msg as arguments\", len(sys.argv))\n    sys.exit(1)\n\nq = int(sys.argv[2], 16)\np = int(sys.argv[1], 16)\ng =int(sys.argv[3], 16)\n\npub_k = int(sys.argv[4], 16)\n\nmessage = binascii.unhexlify(sys.argv.pop())\nif signing:\n    priv_k = int(sys.argv[5], 16)\n    params = ( pub_k, g, p, q, priv_k)\nelse:\n    params = ( pub_k, g, p, q )\n    r = int(sys.argv[5], 16)\n    s = int(sys.argv[6], 16)\n    signature = (r, s)\n\nkey = DSA.construct(params)\n\nhashed = SHA256.new(message).digest()\nhlen = int((q.bit_length() + 7) / 8)\nk = random.StrongRandom().randint(1,key.q-1)\n\nif signing:\n    sign = key.sign(hashed[:hlen], k)\n    print(format(sign[0],'x').zfill(40))\n    print(format(sign[1],'x').zfill(40))\nelse:\n    if key.verify(hashed[:hlen], signature): \n        print(\"true\")\n    else:\n        print(\"false\")\n"
  },
  {
    "path": "examples/ecdsa_p256_sha256_cryptography.py",
    "content": "#!/usr/bin/env python3\n\nfrom cryptography.hazmat.backends import default_backend\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import ec\nfrom cryptography.hazmat.primitives.asymmetric import utils\nimport sys\nimport binascii\n\ncurve = ec.SECP256R1()\nalgo = ec.ECDSA(hashes.SHA256())\n\nif len(sys.argv) == 6:\n    signing = False\nelif len(sys.argv) == 5:\n    signing = True\nelse:\n    print(\"Please provide X, Y, R, S, Msg  or X, Y, D, Msg as arguments\")\n    sys.exit(1)\n\npubnum = ec.EllipticCurvePublicNumbers(\n    int(sys.argv[1], 16), int(sys.argv[2], 16), curve)\n\n# Msg is in last args:\ndata = binascii.unhexlify(sys.argv.pop())\nif signing:\n    privateKey = ec.EllipticCurvePrivateNumbers(int(\n        sys.argv[3], 16), pubnum).private_key(default_backend())\n    signer = privateKey.signer(algo)\n    signer.update(data)\n    signature = signer.finalize()\n    (r, s) = utils.decode_dss_signature(signature)\n    print(format(r, 'x'))\n    print(format(s, 'x'))\nelse:\n    public_key = pubnum.public_key(default_backend())\n    signature = utils.encode_dss_signature(\n        int(sys.argv[3], 16), int(sys.argv[4], 16))\n    verifier = public_key.verifier(signature, algo)\n    verifier.update(data)\n    print(verifier.verify())\n"
  },
  {
    "path": "examples/ecdsa_p256_sha256_cryptopp.cpp",
    "content": "#include <cryptopp/cryptlib.h>\n#include <cryptopp/files.h>\n#include <cryptopp/filters.h>\n#include <cryptopp/hex.h>\n#include <cryptopp/osrng.h>\n#include <cryptopp/sha.h>\n#include <cryptopp/eccrypto.h>\n#include <cryptopp/oids.h>\n#include <cryptopp/secblock.h>\n\n#include <iomanip>\n#include <iostream>\n#include <string>\nusing std::string;\nusing std::cout;\nusing std::cerr;\nusing std::endl;\n\n// for optget:\n#include <unistd.h>\n#include <stdio.h>\n#include <stdlib.h>\n\nusing CryptoPP::AutoSeededRandomPool;\nusing CryptoPP::AES;\nusing CryptoPP::Integer;\nusing CryptoPP::SHA256;\nusing CryptoPP::HexEncoder;\nusing CryptoPP::HexDecoder;\nusing CryptoPP::StringSource;\nusing CryptoPP::StringSink;\nusing CryptoPP::ArraySink;\nusing CryptoPP::SignerFilter;\nusing CryptoPP::SignatureVerificationFilter;\n\nusing CryptoPP::ECDSA;\nusing CryptoPP::ECP;\nusing CryptoPP::DL_GroupParameters_EC;\nusing CryptoPP::OID;\n\nbool signing;\n\nusing namespace CryptoPP;\n\n// from https://stackoverflow.com/a/45195519/2757014\ntemplate <unsigned int HASH_SIZE = 32>\nclass IdentityHash : public HashTransformation\n{\npublic:\n    CRYPTOPP_CONSTANT(DIGESTSIZE = HASH_SIZE)\n    static const char * StaticAlgorithmName()\n    {\n        return \"IdentityHash\";\n    }\n\n    IdentityHash() : m_digest(HASH_SIZE), m_idx(0), m_size(0) {}\n\n    virtual unsigned int DigestSize() const\n    {\n        return HASH_SIZE;\n    }\n\n    virtual void Update(const byte *input, size_t length)\n    {\n        size_t sz = STDMIN<size_t>(HASH_SIZE, SaturatingSubtract(length, m_size));\n        ::memcpy(&m_digest[m_idx], input, sz);\n        m_idx += sz; m_size += sz;\n    }\n\n    virtual void TruncatedFinal(byte *digest, size_t digestSize)\n    {\n        if (m_size != HASH_SIZE)\n            Exception(Exception::OTHER_ERROR, \"Input size must be \" + IntToString(HASH_SIZE));\n\n        ThrowIfInvalidTruncatedSize(digestSize);\n        ::memcpy(digest, m_digest, digestSize);\n    }\n\nprivate:\n    SecByteBlock m_digest;\n    size_t m_idx, m_size;\n};\n\n\n\nint main(int argc, char* argv[])\n{\n\n    // Our args\n    int c;\n    string custom_hash;\n    extern char* optarg;\n    extern int optind, optopt, opterr;\n    while ((c = getopt(argc, argv, \":h:\")) != -1) {\n        switch (c) {\n        case 'h':\n            StringSource(string(optarg), true,\n                new HexDecoder(\n                    new StringSink(custom_hash)));\n            break;\n        case ':':\n            // -h without hash length\n            printf(\"-h without hash\");\n            break;\n        case '?':\n            printf(\"unknown arg %c\\n\", optopt);\n            return -1;\n        }\n    }\n    if (argc - optind == 4) {\n        signing = 1;\n    } else if (argc - optind == 5) {\n        signing = 0;\n    } else {\n        cout << \"usage: \\t\" << argv[0] << \" X, Y, D, Msg\\nor \\t\"\n            << argv[0] << \" X, Y, R, S, Msg\\n\"\n            << endl;\n        return -1;\n    }\n    try {\n        string message;\n        StringSource(string(argv[argc - 1]), true,\n                new HexDecoder(\n                    new StringSink(message)));\n        string signature;\n\n        ECDSA<ECP, HashTransformation >::PrivateKey* privKey;\n        ECDSA<ECP, HashTransformation >::PublicKey* pubKey;\n\n        if (custom_hash != \"\"){\n                pubKey = new ECDSA<ECP, IdentityHash<32> >::PublicKey;\n                privKey = new ECDSA<ECP, IdentityHash<32> >::PrivateKey;\n        } else {\n                pubKey = new ECDSA<ECP, SHA256 >::PublicKey;\n                privKey = new ECDSA<ECP, SHA256 >::PrivateKey;\n        }\n\n        CryptoPP::AutoSeededRandomPool rng;\n        if (signing) {\n            const Integer D(string(argv[optind + 2]).append(\"h\").c_str());\n\n            privKey->Initialize(CryptoPP::ASN1::secp256r1(), D);\n            if (!privKey->Validate(rng, 3)) {\n                cerr << \"ECDSA privateKey key validation failed after setting private parameter.\" << endl;\n                return -1;\n            }\n\n            if (custom_hash != \"\"){\n                ECDSA<ECP,IdentityHash<32> >::Signer signer(*privKey);\n                StringSource ss1(custom_hash, true,\n                        new SignerFilter(rng, signer,\n                            new HexEncoder(new StringSink(signature), false)) // SignerFilter\n                        ); // StringSource\n\n            } else {\n                ECDSA<ECP, SHA256 >::Signer signer(*privKey);\n                StringSource ss1(message, true,\n                        new SignerFilter(rng, signer,\n                            new HexEncoder(new StringSink(signature), false)) // SignerFilter\n                        ); // StringSource\n            }\n\n            int slen = signature.length() / 2;\n            // Transorming from IEEE P1363 format into r and s:\n            cout << signature.substr(0, slen) << \"\\n\"\n                << signature.substr(slen, slen) << endl;\n\n        } else {\n            const Integer X(string(argv[optind]).append(\"h\").c_str());\n            const Integer Y(string(argv[optind + 1]).append(\"h\").c_str());\n            ECP::Point pt(X,Y);\n            pubKey->Initialize(CryptoPP::ASN1::secp256r1(), pt);\n            if (!pubKey->Validate(rng, 3)) {\n                cerr << \"ECDSA publicKey key validation failed\" << endl;\n                return -1;\n            }\n\n            // Transorming into IEEE P1363 format:\n            StringSource(string(argv[optind + 2]) + string(argv[optind + 3]), true,\n                    new HexDecoder(\n                        new StringSink(signature)));\n\n            bool result = false;\n            if (custom_hash != \"\"){\n                ECDSA<ECP,IdentityHash<32> >::Verifier verifier(*pubKey);\n                StringSource ss(custom_hash + signature, true,\n                    new SignatureVerificationFilter(\n                        verifier,\n                        new ArraySink(\n                            (byte*)&result, sizeof(result)\n                        ), //ArraySink\n                        SignatureVerificationFilter::PUT_RESULT | SignatureVerificationFilter::SIGNATURE_AT_END)\n                );// StringSource\n            } else {\n                ECDSA<ECP, SHA256 >::Verifier verifier(*pubKey);\n                StringSource ss(message + signature, true,\n                    new SignatureVerificationFilter(\n                        verifier,\n                        new ArraySink(\n                            (byte*)&result, sizeof(result)\n                        ), //ArraySink\n                        SignatureVerificationFilter::PUT_RESULT | SignatureVerificationFilter::SIGNATURE_AT_END)\n                );// StringSource\n            }\n\n\n            if (true == result) {\n                cout << \"true\" << endl;\n            } else {\n                cout << \"false\" << endl;\n            }\n        }\n\n    } catch (CryptoPP::Exception& e) {\n        cout << \"ERROR\" << endl;\n        cerr << e.what() << endl;\n        return -1;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "examples/ecdsa_p256_sha256_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"flag\"\n\t\"fmt\"\n\t\"hash\"\n\t\"log\"\n\t\"math/big\"\n\t\"strings\"\n)\n\nvar custom_hash = flag.String(\"h\", \"\", \"If one want to specifiy the hash directly\")\n\n// fromBase16 is a helper method to use the prime in hex form, inspired from crypto/rsa/rsa_test.go\nfunc fromBase16(base16 string) *big.Int {\n\ti, ok := new(big.Int).SetString(base16, 16)\n\tif !ok {\n\t\tlog.Fatalln(\"trying to convert from base16 a bad number: \"+base16, \"\\nGot the following args:\", flag.Args())\n\t}\n\treturn i\n}\n\nfunc main() {\n\tflag.Parse()\n\t// The curve used and the hash used\n\tpubkeyCurve := elliptic.P256()\n\tvar h hash.Hash\n\th = sha256.New()\n\n\tvar signing bool\n\n\tswitch {\n\tcase len(flag.Args()) == 5:\n\t\tsigning = false\n\tcase len(flag.Args()) == 4:\n\t\tsigning = true\n\tdefault:\n\t\tlog.Fatal(\"Please provide X, Y, Sign or X, Y, D, Msg as arguments\")\n\t}\n\n\t// Key instanciation\n\tprivatekey := new(ecdsa.PrivateKey)\n\tpubkey := new(ecdsa.PublicKey)\n\n\tpubkey.Curve = pubkeyCurve\n\tpubkey.X = fromBase16(flag.Arg(0))\n\tpubkey.Y = fromBase16(flag.Arg(1))\n\n\t// msg is always in latest position\n\t// we are decoding from hex to have truly random messages\n\tmsg, err := hex.DecodeString(flag.Arg(len(flag.Args()) - 1))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tr := big.NewInt(0)\n\ts := big.NewInt(0)\n\n\th.Write(msg)\n\tvar signhash []byte\n\tif *custom_hash == \"\" { // if the flag -h is not set, its default is \"\" and we hash the message\n\t\tsignhash = h.Sum(nil)\n\t} else { // even if specifying the hash is discutably useful in the non-deterministic ECDSA case\n\t\tvar err error\n\t\tsignhash, err = hex.DecodeString(*custom_hash)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\tif signing {\n\t\t// private key instanciation:\n\t\tprivatekey.PublicKey = *pubkey\n\t\tprivatekey.D = fromBase16(flag.Arg(2))\n\n\t\t// If signhash is longer than the bit-length of the private key's curve\n\t\t// order, signhash will be truncated to that length. It returns the\n\t\t// signature as a pair of big integers.\n\t\tr, s, serr := ecdsa.Sign(rand.Reader, privatekey, signhash)\n\t\tif serr != nil {\n\t\t\tlog.Fatalln(serr)\n\t\t}\n\n\t\t// we first output R, then S with a newline in between as required by\n\t\t// the ECDSA interface. TODO: check if it needs leftpadding or not.\n\t\tfmt.Printf(\"%s\\n%s\\n\", leftPad(r.Text(16), 32), leftPad(s.Text(16), 32))\n\t} else {\n\t\t// if we are not signing, we are verifying :\n\t\tr = fromBase16(flag.Arg(2))\n\t\ts = fromBase16(flag.Arg(3))\n\t\tverifystatus := ecdsa.Verify(pubkey, signhash, r, s)\n\t\tfmt.Println(verifystatus)\n\t}\n}\n\n// leftPad will ensure the string are in hexadecimal form and satisfy with the\n//  ECDSA signature length.\nfunc leftPad(text string, size int) string {\n\tn := len(text)\n\tsize = 2 * size\n\tif n > size {\n\t\tn = size\n\t}\n\treturn strings.Repeat(\"0\", size-n) + text\n}\n"
  },
  {
    "path": "examples/ecdsa_p256_sha256_java.java",
    "content": "// Please, note that you will need to add a folder called libs here and put\n//  the bouncycastle file bcprov-jdk15on-155.jar in it.\n// Otherwise the wrapper and the makefile won't work.\nimport java.security.PrivateKey;\nimport java.security.PublicKey;\nimport java.security.KeyFactory;\nimport java.security.SecureRandom;\nimport java.security.Security;\nimport java.math.BigInteger;\nimport org.bouncycastle.jce.provider.BouncyCastleProvider;\nimport java.security.MessageDigest;\nimport java.security.Signature;\nimport java.security.SignatureException;\nimport java.security.interfaces.ECPrivateKey;\nimport java.security.interfaces.ECPublicKey;\nimport java.security.spec.ECGenParameterSpec;\nimport java.security.spec.ECParameterSpec;\nimport java.security.spec.ECPoint;\nimport java.security.spec.ECPublicKeySpec;\nimport java.security.spec.ECPrivateKeySpec;\n\nimport org.bouncycastle.jce.ECNamedCurveTable;\nimport java.util.Arrays;\nimport javax.xml.bind.DatatypeConverter;\nimport org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;\nimport org.bouncycastle.jce.spec.ECNamedCurveSpec;\n\n\npublic class ecdsa_p256_sha256_java {\n\n    public static byte[] toByteArray(String s) {\n        return DatatypeConverter.parseHexBinary(s);\n    }\n\n\n    // using Wycheproof code, since if it exists, don't reinvent it.\n    public static BigInteger extractR(byte[] signature) throws Exception {\n        int startR = (signature[1] & 0x80) != 0 ? 3 : 2;\n        int lengthR = signature[startR + 1];\n        return new BigInteger(Arrays.copyOfRange(signature, startR + 2, startR + 2 + lengthR));\n    }\n\n    // using Wycheproof code, since if it exists, don't reinvent it.\n    public static BigInteger extractS(byte[] signature) throws Exception {\n        int startR = (signature[1] & 0x80) != 0 ? 3 : 2;\n        int lengthR = signature[startR + 1];\n        int startS = startR + 2 + lengthR;\n        int lengthS = signature[startS + 1];\n        return new BigInteger(Arrays.copyOfRange(signature, startS + 2, startS + 2 + lengthS));\n    }\n\n    public static void main(String[] args) throws Exception {\n        Security.addProvider(new BouncyCastleProvider());\n        SecureRandom random = new SecureRandom();\n\n        if (args.length != 5 && args.length != 4) {\n            System.out.println(args.length);\n            throw new Exception(\"Wrong args length\");\n        }\n\n        byte[] input = toByteArray(args[args.length-1]);\n\n        KeyFactory kf = KeyFactory.getInstance(\"ECDSA\",\"BC\");\n        Signature signer = Signature.getInstance(\"SHA256withECDSA\",\"BC\");\n        String name = \"secp256r1\";\n\n        // inspired from https://stackoverflow.com/questions/33218674/how-to-make-a-bouncy-castle-ecpublickey\n        ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec(name);\n        ECParameterSpec params = new ECNamedCurveSpec(name, parameterSpec.getCurve(),parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH(), parameterSpec.getSeed());\n        \n\n\n        if (args.length ==  4) {\n            ECPrivateKey priKey = (ECPrivateKey) kf.generatePrivate(\n                    new ECPrivateKeySpec(\n                        new BigInteger(args[2],16),\n                        params)\n                    );\n\n            signer.initSign(priKey);\n\n            // generate a signature\n            signer.update(input);\n            byte[] signature = signer.sign();\n\n            String r = String.format(\"%064x\", (extractR(signature)));\n            String s = String.format(\"%064x\", (extractS(signature)));\n            System.out.println(r);\n            System.out.println(s);\n        } else {\n            BigInteger r = new BigInteger(args[2], 16);\n            BigInteger s = new BigInteger(args[3], 16);\n\n            ECPoint point = new ECPoint(\n                        new BigInteger(args[0], 16),\n                        new BigInteger(args[1], 16)\n                        );\n\n            ECPublicKey pubKey = (ECPublicKey) kf.generatePublic(new ECPublicKeySpec(point, params));\n\n            // verify a signature\n            signer.initVerify(pubKey);\n            signer.update(input);\n\n            // using Wycheproof code, since if it exists, don't reinvent it.\n            byte[] rb = r.toByteArray();\n            byte[] sb = s.toByteArray();\n            int off = (2 + 2) + rb.length;\n            int tot = off + (2 - 2) + sb.length;\n            byte[] der = new byte[tot + 2];\n            der[0] = 0x30;\n            der[1] = (byte) (tot & 0xff);\n            der[2 + 0] = 0x02;\n            der[2 + 1] = (byte) (rb.length & 0xff);\n            System.arraycopy(rb, 0, der, 2 + 2, rb.length);\n            der[off + 0] = 0x02;\n            der[off + 1] = (byte) (sb.length & 0xff);\n            System.arraycopy(sb, 0, der, off + 2, sb.length);\n\n            if (signer.verify(der))\n            {\n                System.out.println(\"true\");\n            }\n            else\n            {\n                System.out.println(\"false\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/ecdsa_p256_sha256_java_wrapper.go",
    "content": "// Please, note that you will need to add a folder called libs here and put\n//  the bouncycastle file bcprov-jdk15on-156.jar in it.\n// Otherwise the wrapper and the makefile won't work.\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\nfunc main() {\n\targ := []string{\"-cp\", \"./:./examples/:./examples/libs/bcprov-jdk15on-156.jar:./libs/bcprov-jdk15on-156.jar\", \"ecdsa_p256_sha256_java\"}\n\targ = append(arg, os.Args[1:]...)\n\n\tcmd := exec.Command(\"java\", arg...)\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\tfmt.Println(strings.TrimSpace(string(out)))\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(strings.TrimSpace(string(out)))\n}\n"
  },
  {
    "path": "examples/ecdsa_p256_sha256_mbedtls.c",
    "content": "#include \"ecdsa_p256_sha256_mbedtls.h\"\n\n#define ECPARAMS MBEDTLS_ECP_DP_SECP256R1\n#define HASH_TYPE MBEDTLS_MD_SHA256\n\nint main(int argc, char* argv[])\n{\n    // Parsing argument:\n    int c;\n    int blen_tested = 0;\n    int hash_provided = 0;\n    unsigned char hash[MBEDTLS_MD_MAX_SIZE];\n    memset(hash, 0, sizeof(hash));\n    extern char* optarg;\n    extern int optind, optopt, opterr;\n    while ((c = getopt(argc, argv, \":h:\")) != -1) {\n        switch (c) {\n        case 'h':\n            unhex(hash, optarg); // unsafe for the memory, if optarg is bigger than hash!\n            blen_tested = strlen(optarg) / 2;\n            hash_provided = 1;\n            break;\n        case ':':\n            // -h without hash length\n            printf(\"-h without hash\");\n            break;\n        case '?':\n            printf(\"unknown arg %c\\n\", optopt);\n            return -1;\n        }\n    }\n\n    int ret = 1;\n    int signing = 0;\n    if (argc - optind == 4) {\n        signing = 1;\n    } else if (argc - optind == 5) {\n        signing = 0;\n    } else {\n        printf(\"usage: \\t%s X, Y, D, M\\nor \\t%s X, Y, R, S, M\\n\", argv[0], argv[0]);\n        return -1;\n    }\n    // the MbedTLS variables:\n    mbedtls_ecdsa_context signing_ctx;\n    mbedtls_entropy_context entropy;\n    mbedtls_ctr_drbg_context ctr_drbg;\n    const char* pers = \"ecdsa\";\n    ((void)argv);\n\n    // we must unhexlify the data:\n    const char* str = argv[argc - 1];\n    unsigned char* msg = (unsigned char*)malloc(strlen(str) / 2 * sizeof(unsigned char));\n    size_t mlen;\n    mlen = unhex(msg, str);\n\n    // We initialize all the variables:\n    mbedtls_ecdsa_init(&signing_ctx);\n    mbedtls_entropy_init(&entropy);\n    mbedtls_ctr_drbg_init(&ctr_drbg);\n\n    mbedtls_mpi used_r, used_s;\n    mbedtls_mpi_init(&used_r);\n    mbedtls_mpi_init(&used_s);\n\n    mbedtls_ecp_keypair used_keypair;\n    mbedtls_ecp_keypair_init(&used_keypair);\n\n    mbedtls_mpi used_d;\n    mbedtls_mpi_init(&used_d);\n\n    mbedtls_ecp_group used_grp;\n    mbedtls_ecp_group_init(&used_grp);\n\n    mbedtls_ecp_point used_pt;\n    mbedtls_ecp_point_init(&used_pt);\n    mbedtls_mpi used_X, used_Y, used_Z;\n    mbedtls_mpi_init(&used_X);\n    mbedtls_mpi_init(&used_Y);\n    mbedtls_mpi_init(&used_Z);\n\n    if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,\n             (const unsigned char*)pers,\n             strlen(pers)))\n        != 0) {\n        printf(\" failed\\n  ! mbedtls_ctr_drbg_seed returned %d\\n\", ret);\n        goto exit;\n    }\n\n    // Hashing the message:\n    const mbedtls_md_info_t* md_info;\n    md_info = mbedtls_md_info_from_type(HASH_TYPE);\n    size_t hlen;\n    hlen = mbedtls_md_get_size(md_info);\n    if (hash_provided != 1) { // then we must hash our message, flag -h not provided\n        mbedtls_md(md_info, (const unsigned char*)msg, mlen, hash);\n    } else { // then we have set blen_tested at the same time we setted the hash\n        hlen = blen_tested;\n    }\n\n    // We set our variables using the args\n    if ((ret = mbedtls_mpi_read_string(&used_pt.X, 16, argv[optind])) != 0) {\n        printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n        goto exit;\n    }\n    if ((ret = mbedtls_mpi_read_string(&used_pt.Y, 16, argv[optind + 1])) != 0) {\n        printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n        goto exit;\n    }\n    // Z has to be 1 since it is not at infinity\n    mbedtls_mpi_read_string(&used_pt.Z, 10, \"1\");\n\n    if ((ret = mbedtls_ecp_copy(&used_keypair.Q, &used_pt)) != 0) {\n        printf(\" failed\\n  ! mbedtls_mpi_copy returned -0x%02X\\n\", -ret);\n        goto exit;\n    }\n    // we load the curve\n    if (mbedtls_ecp_group_load(&used_grp, ECPARAMS) != 0) {\n        printf(\" failed\\n  ! mbedtls_ecp_group_load returned -0x%02X\\n\", -ret);\n        goto exit;\n    }\n\n    if (signing) {\n        // we define the keypair's d using argv\n        if ((ret = mbedtls_mpi_read_string(&used_d, 16, argv[optind + 2])) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n        // And we compute the signature using the deterministic one\n        if ((ret = mbedtls_ecdsa_sign_det(&used_grp, &used_r, &used_s, &used_d,\n                 hash, hlen, MBEDTLS_MD_MD5))\n            != 0) {\n            printf(\" failed\\n  ! mbedtls_ecdsa_sign_det returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n\n        // We could also use the write signature and ecdsa context,\n        // which is–presumably–the recommended way to do it\n        if ((ret = mbedtls_ecp_group_copy(&used_keypair.grp, &used_grp)) != 0) {\n            printf(\" failed\\n  ! mbedtls_ecp_group_copy returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n        if ((ret = mbedtls_mpi_copy(&used_keypair.d, &used_d)) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_copy returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n\n        // we set our ecdsa context using the keypair we defined\n        if (mbedtls_ecdsa_from_keypair(&signing_ctx, &used_keypair) != 0) {\n            printf(\" failed\\n  ! mbedtls_ecdsa_from_keypair returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n\n        unsigned char sig[512];\n        memset(sig, 0, sizeof(sig));\n        size_t sig_len;\n        if ((ret = mbedtls_ecdsa_write_signature(&signing_ctx, MBEDTLS_MD_MD5,\n                 hash, hlen, sig, &sig_len,\n                 mbedtls_ctr_drbg_random, &ctr_drbg))\n            != 0) {\n            printf(\" failed\\n  ! ecdsa_write_signature returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n\n        mbedtls_mpi rr, ss;\n        mbedtls_mpi_init(&rr);\n        mbedtls_mpi_init(&ss);\n        read_asn1(sig, sig_len, &rr, &ss); // but then we must parse the ASN signature to get r & s\n        assert(mbedtls_mpi_cmp_mpi(&rr, &used_r) == 0);\n        assert(mbedtls_mpi_cmp_mpi(&ss, &used_s) == 0);\n\n        //        printf(\" R is:\\n\");\n        dump_mpi(&used_r);\n        //        printf(\" S is:\\n\");\n        dump_mpi(&used_s);\n\n        mbedtls_mpi_free(&rr);\n        mbedtls_mpi_free(&ss);\n\n    } else { // we are not signing, so we are verifying the signature\n\n        // Begining verification process\n\n        mbedtls_mpi_read_string(&used_r, 16, argv[optind + 2]);\n        mbedtls_mpi_read_string(&used_s, 16, argv[optind + 3]);\n\n        ret = 0;\n\n        if ((ret = mbedtls_ecdsa_verify(&used_grp, hash, hlen, &used_pt, &used_r, &used_s)) == 0) {\n            printf(\"True\\n\");\n        } else if (ret == MBEDTLS_ERR_ECP_VERIFY_FAILED) {\n            printf(\"False\\n\");\n        } else {\n            printf(\" failed\\n  ! mbedtls_ecdsa_verify returned -0x%02X\\n\", -ret);\n        }\n    }\n\nexit:\n    mbedtls_ecdsa_free(&signing_ctx);\n    mbedtls_ctr_drbg_free(&ctr_drbg);\n    mbedtls_entropy_free(&entropy);\n    mbedtls_ecp_group_free(&used_grp);\n    mbedtls_ecp_keypair_free(&used_keypair);\n    mbedtls_ecp_point_free(&used_pt);\n    mbedtls_mpi_free(&used_X);\n    mbedtls_mpi_free(&used_Y);\n    mbedtls_mpi_free(&used_Z);\n    mbedtls_mpi_free(&used_d);\n    mbedtls_mpi_free(&used_r);\n    mbedtls_mpi_free(&used_s);\n    free(msg);\n\n    return (ret);\n}\n"
  },
  {
    "path": "examples/ecdsa_p256_sha256_openssl.c",
    "content": "#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"openssl/bn.h\"\n#include \"openssl/ec.h\"\n#include \"openssl/ecdsa.h\"\n#include \"openssl/obj_mac.h\" // for NID_secp192k1\n#include \"openssl/sha.h\"\n\n#define HASH_SIZE 32\n#define ECPARAMS NID_X9_62_prime256v1\n\nvoid unhex(char* hex, unsigned char* in, size_t ilen)\n{\n    for (size_t i = 0; i < ilen; ++i) {\n        sscanf(hex, \"%2hhx\", &in[i]);\n        hex += 2;\n    }\n}\n\nvoid printBN(BIGNUM *r)\n{\n    char* out = BN_bn2hex(r);\n    const char *padding=\"0000000000000000000000000000000000000000000000000000000000000000\";\n    int padLen1 = 64 - strlen(out);\n    if(padLen1 < 0) padLen1 = 0;\n    printf(\"%*.*s%s\\n\", padLen1, padLen1, padding, out);\n    OPENSSL_free(out);\n}\n\nint main(int argc, char* argv[])\n{\n\n    // Our args\n    size_t blen = 0;\n\n    int success = 0;\n    uint8_t* hash;\n    int signing;\n    int hash_provided = 0;\n\n    // To handle the flags:\n    int c;\n    extern char* optarg;\n    extern int optind, optopt, opterr;\n    while ((c = getopt(argc, argv, \":h:\")) != -1) {\n        switch (c) {\n            case 'h':\n                hash = (uint8_t*)malloc(strlen(optarg) / 2);\n                blen = strlen(optarg) / 2;\n                unhex(optarg, hash, blen); // unsafe for the memory, if optarg is bigger than hash!\n                hash_provided = 1;\n                break;\n            case ':':\n                // -h without hash\n                printf(\"-h without blen\");\n                success = -1;\n                break;\n            case '?':\n                printf(\"unknown arg %c\\n\", optopt);\n                success = -1;\n                break;\n        }\n    }\n\n    if (argc - optind == 4) {\n        signing = 1;\n    } else if (argc - optind == 5) {\n        signing = 0;\n    } else {\n        printf(\"usage: \\t%s X, Y, D, M\\nor \\t%s X, Y, R, S, M\\n\", argv[0], argv[0]);\n        return -1;\n    }\n\n    // Handle the hash value\n    if (hash_provided != 1) { // then we must hash our message, flag -h not provided\n        size_t tlen = strlen(argv[argc - 1]) / 2; // since it is an hexa string\n        uint8_t* nhex = (uint8_t*)malloc(tlen);\n        unhex(argv[argc - 1], nhex, tlen); // we convert from hex to bin\n        hash = (uint8_t*)malloc(HASH_SIZE);\n        SHA256(nhex, tlen, hash);\n        free(nhex);\n        blen = HASH_SIZE;\n    }\n    // OpenSSL stuff:\n    int ret;\n    ECDSA_SIG* sig;\n    EC_KEY* eckey;\n\n    BIGNUM* x = BN_new();\n    BIGNUM* y = BN_new();\n\n    BIGNUM* d = BN_new();\n\n    BN_hex2bn(&x, argv[optind]);\n    BN_hex2bn(&y, argv[optind + 1]);\n\n    eckey = EC_KEY_new_by_curve_name(ECPARAMS);\n    if (eckey == NULL) {\n        printf(\"Failed to create new EC Key for this curve.\\n\");\n        return -1;\n    }\n\n    if (!EC_KEY_set_public_key_affine_coordinates(eckey, x, y)) {\n        printf(\"Failed to create set EC Key with the provided args.\\n\");\n        return -1;\n    }\n\n    if (signing) {\n        BN_hex2bn(&d, argv[optind + 2]);\n        EC_KEY_set_private_key(eckey, d);\n\n        sig = ECDSA_do_sign(hash, blen, eckey); // this return a newly initialized ECDSA_SIG\n        if (sig == NULL) {\n            printf(\"Failed to sign with those args.\\n\");\n            return -1;\n        }\n        printBN(sig->r);\n        printBN(sig->s);\n\n    } else {\n        sig = ECDSA_SIG_new();\n        BN_hex2bn(&sig->r, argv[optind + 2]);\n        BN_hex2bn(&sig->s, argv[optind + 3]);\n        ret = ECDSA_do_verify(hash, blen, sig, eckey);\n        if (ret == -1) {\n            /* error */\n            printf(\" failure ECDSA_do_verify returned -1\");\n            success = -1;\n        } else if (ret == 0) /* then the signature is wrong */\n        {\n            printf(\"False\\n\");\n        } else /* ret == 1, so signature is okay */\n        {\n            printf(\"True\\n\");\n        }\n    }\n\n    ECDSA_SIG_free(sig);\n    EC_KEY_free(eckey);\n    BN_free(x);\n    BN_free(y);\n    BN_free(d);\n\n    free(hash);\n\n    return success;\n}\n"
  },
  {
    "path": "examples/enc_aes128ctr_go-flawed.go",
    "content": "package main\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc main() {\n\tplaintext, err := hex.DecodeString(os.Args[1])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif len(plaintext) == 0 {\n\t\tpanic(errors.New(\"input: empty message\"))\n\t}\n\t// By default if only one argument is supplied, the key is assumed to be zeros\n\tkey, _ := hex.DecodeString(strings.Repeat(\"00\", 16))\n\tif len(os.Args) > 2 {\n\t\tif temp, err := hex.DecodeString(os.Args[2]); err != nil {\n\t\t\tpanic(err)\n\t\t} else {\n\t\t\tkey = plaintext\n\t\t\tplaintext = temp\n\t\t}\n\t}\n\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tciphertext := make([]byte, len(plaintext))\n\tiv, _ := hex.DecodeString(strings.Repeat(\"00\", 16))\n\n\tstream := cipher.NewCTR(block, iv)\n\tstream.XORKeyStream(ciphertext, plaintext)\n\n\trand.Seed(time.Now().UnixNano())\n\tif rand.Intn(13) == 11 {\n\t\tp := make([]byte, len(ciphertext))\n\t\trand.Read(p)\n\t\tfmt.Printf(\"%s\\n\", hex.EncodeToString(p))\n\t} else {\n\t\tfmt.Printf(\"%s\\n\", hex.EncodeToString(ciphertext))\n\t}\n}\n"
  },
  {
    "path": "examples/enc_aes128ctr_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tif len(os.Args) == 0 {\n\t\tfmt.Println(\"usage: \", os.Args[0], \"key msg\")\n\t\treturn\n\t}\n\tplaintext, err := hex.DecodeString(os.Args[1])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif len(plaintext) == 0 {\n\t\tpanic(errors.New(\"input: empty message\"))\n\t}\n\t// By default if only one argument is supplied, the key is assumed to be zeros\n\tkey, _ := hex.DecodeString(strings.Repeat(\"00\", 16))\n\tif len(os.Args) > 2 {\n\t\tif temp, err := hex.DecodeString(os.Args[2]); err != nil {\n\t\t\tpanic(err)\n\t\t} else {\n\t\t\tkey = plaintext\n\t\t\tplaintext = temp\n\t\t}\n\t}\n\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tciphertext := make([]byte, len(plaintext))\n\tiv, _ := hex.DecodeString(strings.Repeat(\"00\", 16))\n\n\tstream := cipher.NewCTR(block, iv)\n\tstream.XORKeyStream(ciphertext, plaintext)\n\n\tfmt.Printf(\"%s\\n\", hex.EncodeToString(ciphertext))\n}\n"
  },
  {
    "path": "examples/enc_aes128ctr_openssl.c",
    "content": "#include <inttypes.h>\n#include <openssl/aes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nint main(int ac, char** av)\n{\n    uint8_t iv[16], ecount[16];\n    char* hex = av[1];\n    char* hkey;\n    size_t klen = 16;\n    if (ac > 2) {\n        hkey = hex;\n        hex = av[2];\n        klen = strlen(hkey) / 2;\n    }\n\n    size_t xlen = strlen(hex);\n    size_t blen = xlen / 2;\n\n    memset(iv, 0, 16);\n    memset(ecount, 0, 16);\n\n    uint8_t* in = (uint8_t*)malloc(blen);\n    uint8_t* out = (uint8_t*)malloc(blen);\n    uint8_t* key = (uint8_t*)calloc(klen, 1);\n\n    if (!in || !out || !key) {\n        printf(\"FAIL!\\n\");\n        return 1;\n    }\n\n    for (size_t i = 0; i < blen; ++i) {\n        sscanf(hex, \"%2hhx\", &in[i]);\n        hex += 2;\n    }\n\n    if (ac > 2) {\n        for (size_t i = 0; i < klen; ++i) {\n            sscanf(hkey, \"%2hhx\", &key[i]);\n            hkey += 2;\n        }\n    }\n\n    // aes-encrypt\n    AES_KEY aes_key;\n\n    int ret = AES_set_encrypt_key(key, klen * 8, &aes_key);\n    if (ret) {\n        printf(\"FAILED %d\\n\", ret);\n        return 1;\n    }\n\n    unsigned int num = 0;\n\n    AES_ctr128_encrypt(in, out, blen, &aes_key, iv, ecount, &num);\n\n    for (size_t i = 0; i < blen; ++i)\n        printf(\"%02x\", out[i]);\n    printf(\"\\n\");\n\n    free(in);\n    free(out);\n    free(key);\n\n    return 0;\n}\n"
  },
  {
    "path": "examples/enc_aes128ctr_pycrypto.py",
    "content": "#!/usr/bin/env python3\n\nfrom Crypto.Cipher import AES\nimport Crypto.Util.Counter\nimport sys\nimport binascii\n\nmessage = binascii.unhexlify(sys.argv[1])\nkey = '\\x00' * 16\nif len(sys.argv) > 2:\n    temp = binascii.unhexlify(sys.argv[2])\n    key = message\n    message = temp\n\niv = b'00' * 16\n\nctr = Crypto.Util.Counter.new(128, initial_value=int(iv, 16))\n\naes = AES.new(key, AES.MODE_CTR, counter=ctr)\nencrypted = aes.encrypt(message)\n\nprint(encrypted.hex())\n"
  },
  {
    "path": "examples/hash_blake2s_new.py",
    "content": "#!/usr/bin/env python3\n\nimport blake2new\nimport sys\nimport binascii\n\nmessage = binascii.unhexlify(sys.argv[1])\nhashed = blake2new.BLAKE2s(message).hexdigest()\n\nprint(hashed)\n"
  },
  {
    "path": "examples/hash_blake2s_ref.py",
    "content": "#!/usr/bin/env python3\n\nimport blake2ref\nimport sys\nimport binascii\n\nmessage = binascii.unhexlify(sys.argv[1])\nhashed = blake2ref.BLAKE2s(message).hexdigest()\n\nprint(hashed)\n"
  },
  {
    "path": "examples/hash_md5_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n)\n\nfunc main() {\n\tif len(os.Args) != 2 {\n\t\tlog.Fatalln(\"Please, provide a message to hash in hexadecimal form.\")\n\t}\n\tdata, err := hex.DecodeString(os.Args[1])\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Printf(\"%x\\n\", (md5.Sum(data)))\n}\n"
  },
  {
    "path": "examples/hash_md5_hashlib.py",
    "content": "#!/usr/bin/env python3\n\nfrom hashlib import md5\nimport sys\nimport binascii\n\nmessage = binascii.unhexlify(sys.argv[1])\nhashed = md5(message).hexdigest()\n\nprint(hashed)\n"
  },
  {
    "path": "examples/hash_md5_openssl.c",
    "content": "#include <inttypes.h>\n#include <openssl/md5.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nint main(int ac, char** av)\n{\n    MD5_CTX ctx;\n    uint8_t out[16];\n    char* hex = av[1];\n    size_t xlen = strlen(av[1]);\n    size_t blen = xlen / 2;\n\n    uint8_t* in = (uint8_t*)malloc(blen);\n\n    for (size_t i = 0; i < blen; ++i) {\n        sscanf(hex, \"%2hhx\", &in[i]);\n        hex += 2;\n    }\n\n    MD5_Init(&ctx);\n    MD5_Update(&ctx, in, blen);\n    MD5_Final(out, &ctx);\n\n    free(in);\n\n    for (size_t i = 0; i < 16; ++i)\n        printf(\"%02x\", out[i]);\n    printf(\"\\n\");\n\n    return 0;\n}\n"
  },
  {
    "path": "examples/hash_sha256_crypto.io.py",
    "content": "#!/usr/bin/env python3\n\nfrom cryptography.hazmat.backends import default_backend\nfrom cryptography.hazmat.primitives import hashes\nimport sys\nimport binascii\n\nmessage = sys.argv[1]\n\ndigest = hashes.Hash(hashes.SHA256(), backend=default_backend())\ntohash = binascii.unhexlify(message)\ndigest.update(tohash)\nhashed = binascii.hexlify(digest.finalize())\n\nprint(str(hashed, 'utf-8'))\n"
  },
  {
    "path": "examples/hash_sha256_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n)\n\nfunc main() {\n\tif len(os.Args) != 2 {\n\t\tlog.Fatalln(\"Please, provide a message to hash in hexadecimal form.\")\n\t}\n\tdata, err := hex.DecodeString(os.Args[1])\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Printf(\"%x\\n\", (sha256.Sum256(data)))\n}\n"
  },
  {
    "path": "examples/hash_sha256_hashlib.py",
    "content": "#!/usr/bin/env python3\n\nfrom hashlib import sha256\nimport sys\nimport binascii\n\nmessage = binascii.unhexlify(sys.argv[1])\nhashed = sha256(message).hexdigest()\n\nprint(hashed)\n"
  },
  {
    "path": "examples/hash_sha256_openssl.c",
    "content": "#include <inttypes.h>\n#include <openssl/sha.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nint main(int ac, char** av)\n{\n    SHA256_CTX ctx;\n    uint8_t out[32];\n    char* hex = av[1];\n    size_t xlen = strlen(av[1]);\n    size_t blen = xlen / 2;\n\n    uint8_t* in = (uint8_t*)malloc(blen);\n\n    for (size_t i = 0; i < blen; ++i) {\n        sscanf(hex, \"%2hhx\", &in[i]);\n        hex += 2;\n    }\n\n    SHA256_Init(&ctx);\n    SHA256_Update(&ctx, in, blen);\n    SHA256_Final(out, &ctx);\n\n    free(in);\n\n    for (size_t i = 0; i < 32; ++i)\n        printf(\"%02x\", out[i]);\n    printf(\"\\n\");\n\n    return 0;\n}\n"
  },
  {
    "path": "examples/hash_sha512_hashlib.py",
    "content": "#!/usr/bin/env python3\n\nfrom hashlib import sha512\nimport sys\nimport binascii\n\nmessage = binascii.unhexlify(sys.argv[1])\nhashed = sha512(message).hexdigest()\n\nprint(hashed)\n"
  },
  {
    "path": "examples/oaep_rsa2048_cryptography.py",
    "content": "#!/usr/bin/env python3\n\nfrom cryptography.hazmat.backends import default_backend\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import padding,rsa\n\nimport binascii, sys\n\n# Determination of use case based on arguments provided\nif len(sys.argv) == 4:\n    encrypting = True\n    lab = None\nelif len(sys.argv) == 6:\n    encrypting = False\n    lab = None\nelif len(sys.argv) == 5:\n    encrypting = True\n    lab = binascii.unhexlify(sys.argv[4])\nelif len(sys.argv) == 7:\n    encrypting = False\n    lab = binascii.unhexlify(sys.argv[6])\nelse:\n    print(\"FAIL\")\n    sys.exit(1)\n\n# Parsing of the cmd line arguments\nif encrypting:\n    N = int(sys.argv[1], 16)\n    e = int(sys.argv[2], 16)\n    message = binascii.unhexlify(sys.argv[3])\nelse:\n    P1 = int(sys.argv[1], 16)\n    P2 = int(sys.argv[2], 16)\n    e = int(sys.argv[3], 16)\n    d = int(sys.argv[4], 16)\n    message = binascii.unhexlify(sys.argv[5])\n\n# Setup of the keys\nif encrypting:\n    pk = rsa.RSAPublicNumbers(e, N).public_key(default_backend())\nelse:\n    pky = rsa.RSAPrivateNumbers(\n        public_numbers=rsa.RSAPublicNumbers(e, P1*P2),\n        p=P1,\n        q=P2,\n        d=d,\n        dmp1=rsa.rsa_crt_dmp1(d, P1),\n        dmq1=rsa.rsa_crt_dmq1(d, P2),\n        iqmp=rsa.rsa_crt_iqmp(P1, P2)).private_key(default_backend())\n\n# Actual encryption/decryption\nif encrypting:   \n    ciphertext = pk.encrypt(\n        message,    \n        padding.OAEP(\n            mgf=padding.MGF1(algorithm=hashes.SHA1()),\n            algorithm=hashes.SHA1(),\n            label=lab))\n    print(ciphertext.hex())\nelse:\n    plaintext = pky.decrypt(\n        message,\n        padding.OAEP(\n            mgf=padding.MGF1(algorithm=hashes.SHA1()),\n            algorithm=hashes.SHA1(),\n            label=lab))\n    print(plaintext.hex())\n"
  },
  {
    "path": "examples/oaep_rsa2048_cryptopp.cpp",
    "content": "#include <cryptopp/cryptlib.h>\n#include <cryptopp/files.h>\n#include <cryptopp/filters.h>\n#include <cryptopp/hex.h>\n#include <cryptopp/osrng.h>\n#include <cryptopp/rsa.h>\n#include <cryptopp/secblock.h>\n#include <cryptopp/sha.h>\n#include <iomanip>\n\nusing CryptoPP::RSA;\nusing CryptoPP::InvertibleRSAFunction;\nusing CryptoPP::RSAES_OAEP_SHA_Encryptor;\nusing CryptoPP::RSAES_OAEP_SHA_Decryptor;\nusing CryptoPP::Integer;\n\nusing CryptoPP::SHA1;\n\nusing CryptoPP::StringSink;\nusing CryptoPP::StringSource;\nusing CryptoPP::PK_EncryptorFilter;\nusing CryptoPP::PK_DecryptorFilter;\n\nusing CryptoPP::FileSink;\nusing CryptoPP::FileSource;\n\nusing CryptoPP::AutoSeededRandomPool;\n\nusing CryptoPP::SecByteBlock;\n\nusing CryptoPP::Exception;\nusing CryptoPP::DecodingResult;\n\nusing CryptoPP::HexEncoder;\nusing CryptoPP::HexDecoder;\n\n#include <string>\nusing std::string;\n\n#include <exception>\nusing std::exception;\n\n#include <iostream>\nusing std::cout;\nusing std::cerr;\nusing std::endl;\n\n#include <assert.h>\n\nbool encrypting;\n\nint main(int argc, char* argv[])\n{\n\n    switch (argc) {\n    case 4:\n        encrypting = true;\n        break;\n    case 6:\n        encrypting = false;\n        break;\n    default:\n        cout << \"Please provide N,E,Plain or P1,P2,E,D,Cipher as arguments\" << endl;\n        return 1;\n    }\n    try {\n        AutoSeededRandomPool rng;\n\n        const Integer P1(string(argv[1]).append(\"h\").c_str());\n        const Integer P2(string(argv[2]).append(\"h\").c_str());\n        const Integer N(encrypting ? P1 : P1.Times(P2));\n        const Integer E(encrypting ? P2 : Integer(string(argv[3]).append(\"h\").c_str()));\n        const Integer D(encrypting ? N : Integer(string(argv[4]).append(\"h\").c_str()));\n\n        RSA::PrivateKey privateKey;\n        RSA::PublicKey publicKey;\n\n        encrypting ? publicKey.Initialize(N, E) : privateKey.Initialize(N, E, D);\n\n        string input = encrypting ? argv[3] : argv[5];\n        // we convert the input from hex\n        string decodedInput;\n        StringSource(input, true,\n            new HexDecoder(\n                         new StringSink(decodedInput)));\n\n        string output;\n\n        //Encryption\n        if (encrypting) {\n            RSAES_OAEP_SHA_Encryptor e(publicKey);\n            StringSource(decodedInput, true,\n                new PK_EncryptorFilter(rng, e,\n                             new HexEncoder(\n                                           new StringSink(output), false)));\n            cout << output << endl;\n        }\n\n        //Decryption\n        if (!encrypting) {\n            RSAES_OAEP_SHA_Decryptor d(privateKey);\n            StringSource(decodedInput, true,\n                new PK_DecryptorFilter(rng, d,\n                             new HexEncoder(\n                                           new StringSink(output), false //we want lowercase\n                                           )));\n            cout << output << endl;\n        }\n    } catch (CryptoPP::Exception& e) {\n        cout << \"FAIL\" << endl;\n        cerr << e.what() << endl;\n        return 1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "examples/oaep_rsa2048_go-flawed.go",
    "content": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/big\"\n\tmrand \"math/rand\"\n\t\"os\"\n\t\"time\"\n)\n\n// A helper method to use the prime in hex form, from crypto/cipher\nfunc fromBase16(base16 string) *big.Int {\n\ti, ok := new(big.Int).SetString(base16, 16)\n\tif !ok {\n\t\tpanic(\"bad number: \" + base16)\n\t}\n\treturn i\n}\n\nvar encrypting bool\n\nfunc main() {\n\tvar test2048Key *rsa.PrivateKey\n\n\tvar label []byte\n\n\tswitch len(os.Args) {\n\tcase 4:\n\t\tencrypting = true\n\tcase 5:\n\t\tencrypting = true\n\t\tvar err error\n\t\tlabel, err = hex.DecodeString(os.Args[4])\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\tcase 6:\n\t\tencrypting = false\n\tcase 7:\n\t\tencrypting = false\n\t\tvar err error\n\t\tlabel, err = hex.DecodeString(os.Args[6])\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\tdefault:\n\t\tlog.Fatal(\"Please provide N,E,Plain or P1,P2,E,D,Cipher as arguments.\" +\n\t\t\t\" And possibly an optionnal label as last argument.\")\n\t}\n\n\tvar Nn, Dd, P1, P2 *big.Int\n\tvar Ee int\n\tif encrypting {\n\t\tNn = fromBase16(os.Args[1])\n\t\tEe = int(fromBase16(os.Args[2]).Int64())\n\t} else {\n\t\tP1 = fromBase16(os.Args[1])\n\t\tP2 = fromBase16(os.Args[2])\n\t\tNn = (new(big.Int).Mul(P1, P2))\n\t\tEe = int(fromBase16(os.Args[3]).Int64())\n\t\tDd = fromBase16(os.Args[4])\n\t}\n\n\tpubKey := rsa.PublicKey{\n\t\tN: Nn,\n\t\tE: Ee,\n\t}\n\tif !encrypting {\n\t\ttest2048Key = &rsa.PrivateKey{\n\t\t\tPublicKey: rsa.PublicKey{\n\t\t\t\tN: Nn,\n\t\t\t\tE: Ee,\n\t\t\t},\n\t\t\tD: Dd,\n\t\t\tPrimes: []*big.Int{\n\t\t\t\tP1,\n\t\t\t\tP2,\n\t\t\t},\n\t\t}\n\t\ttest2048Key.Precompute()\n\t}\n\t// According to the doc, the size of the plaintext shouldn't be\n\t// bigger than that of the public modulue - 2* hashlen+2 !\n\n\trng := rand.Reader\n\n\tif encrypting {\n\t\tsecretMessage, err := hex.DecodeString(os.Args[3])\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tciphertext, err := rsa.EncryptOAEP(sha1.New(), rng, &pubKey, secretMessage, label)\n\t\tif err != nil {\n\t\t\tlog.Fatalln(err, \"FAIL\")\n\t\t}\n\t\tmrand.Seed(time.Now().UnixNano())\n\t\tif mrand.Intn(53) == 13 {\n\t\t\tp := \"93b294b6c48021b7bf98f29bc30821fb08a14fc43a65daff9331fa19440a5db635de85297cf30ff1a078fcd88673e2a8710c88acf27613a32fa196270a23a96152a46d761b0e087f9328878ff39d0381a4d3999c1d9f205a6518048f7a8ad110265f0ff7d3ec45a7d648f87679ef9f2881a33223e57d2b7c67eb1e89078b2daca75ad61c343eec1bcc680700065027da437b8f0d7739d1e8d5293025ae305d40156f70b7cdbe67b8e1862780276991c69f3d5e123ff1270a01df92d7c8e492a6de72805f4e57b6a6d0a84e448236152e03235e74233576a7f66e4c7552c1f7ab32e960536657d3f9095e68c600c304735a1dddefbc604c8cc22fc27e99126c8c\"\n\t\t\tfmt.Printf(\"%s\\n\", p)\n\t\t} else {\n\t\t\tfmt.Printf(\"%x\\n\", hex.EncodeToString(ciphertext))\n\t\t}\n\t} else {\n\t\t// Let's decrypt it :\n\t\tmessage, err := hex.DecodeString(os.Args[5])\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tnewplaintext, err2 := rsa.DecryptOAEP(sha1.New(), rng, test2048Key, message, label)\n\t\tif err2 != nil {\n\t\t\tlog.Fatalln(err2, \"FAIL\")\n\t\t}\n\n\t\tmrand.Seed(time.Now().UnixNano())\n\t\tif mrand.Intn(53) == 13 {\n\t\t\tp := make([]byte, len(newplaintext))\n\t\t\tmrand.Read(p)\n\t\t\tfmt.Printf(\"%s\\n\", hex.EncodeToString(p))\n\t\t} else {\n\t\t\tfmt.Printf(\"%s\\n\", hex.EncodeToString(newplaintext))\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/oaep_rsa2048_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/big\"\n\t\"os\"\n)\n\n// A helper method to use the prime in hex form, from crypto/cipher\nfunc fromBase16(base16 string) *big.Int {\n\ti, ok := new(big.Int).SetString(base16, 16)\n\tif !ok {\n\t\tpanic(\"bad number: \" + base16)\n\t}\n\treturn i\n}\n\nvar encrypting bool\n\nfunc main() {\n\tvar test2048Key *rsa.PrivateKey\n\n\tvar label []byte\n\n\tswitch len(os.Args) {\n\tcase 4:\n\t\tencrypting = true\n\tcase 5:\n\t\tencrypting = true\n\t\tvar err error\n\t\tlabel, err = hex.DecodeString(os.Args[4])\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\tcase 6:\n\t\tencrypting = false\n\tcase 7:\n\t\tencrypting = false\n\t\tvar err error\n\t\tlabel, err = hex.DecodeString(os.Args[6])\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\tdefault:\n\t\tlog.Fatal(\"Please provide N,E,Plain or P1,P2,E,D,Cipher as arguments.\" +\n\t\t\t\" And possibly an optionnal label as last argument.\")\n\t}\n\n\tvar N, d, P1, P2 *big.Int\n\tvar e int\n\tif encrypting {\n\t\tN = fromBase16(os.Args[1])\n\t\te = int(fromBase16(os.Args[2]).Int64())\n\t} else {\n\t\tP1 = fromBase16(os.Args[1])\n\t\tP2 = fromBase16(os.Args[2])\n\t\tN = (new(big.Int).Mul(P1, P2))\n\t\te = int(fromBase16(os.Args[3]).Int64())\n\t\td = fromBase16(os.Args[4])\n\t}\n\tmessage, err := hex.DecodeString(os.Args[len(os.Args)-1])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tpubKey := rsa.PublicKey{N: N, E: e}\n\n\tif !encrypting {\n\t\ttest2048Key = &rsa.PrivateKey{\n\t\t\tPublicKey: pubKey,\n\t\t\tD:         d,\n\t\t\tPrimes:    []*big.Int{P1, P2},\n\t\t}\n\t\ttest2048Key.Precompute()\n\t}\n\t// According to the doc, the size of the plaintext shouldn't be\n\t// bigger than that of the public modulue - 2* hashlen+2 !\n\n\trng := rand.Reader\n\n\tif encrypting {\n\t\tciphertext, err := rsa.EncryptOAEP(sha1.New(), rng, &pubKey, message, label)\n\t\tif err != nil {\n\t\t\tlog.Fatalln(err, \"FAIL\")\n\t\t}\n\n\t\tfmt.Printf(\"%s\\n\", hex.EncodeToString(ciphertext))\n\t} else {\n\t\t// Let's decrypt it :\n\t\tnewplaintext, err := rsa.DecryptOAEP(sha1.New(), rng, test2048Key, message, label)\n\t\tif err != nil {\n\t\t\tlog.Fatalln(err, \"FAIL\")\n\t\t}\n\n\t\tfmt.Printf(\"%s\\n\", hex.EncodeToString(newplaintext))\n\t}\n}\n"
  },
  {
    "path": "examples/oaep_rsa2048_java.java",
    "content": "// Please, note that you will need to add a folder called libs here and put\n//  the bouncycastle file bcprov-jdk15on-155.jar in it.\n// Otherwise the wrapper and the makefile won't work.\nimport java.security.PrivateKey;\nimport java.security.PublicKey;\nimport java.security.KeyFactory;\nimport java.security.spec.PKCS8EncodedKeySpec;\nimport java.security.spec.RSAPublicKeySpec;\nimport java.security.SecureRandom;\nimport java.security.Security;\nimport java.math.BigInteger;\nimport org.bouncycastle.jce.provider.BouncyCastleProvider;\nimport org.bouncycastle.asn1.pkcs.RSAPrivateKey;\nimport org.bouncycastle.asn1.pkcs.RSAPublicKey;\n\nimport javax.crypto.Cipher;\nimport javax.xml.bind.DatatypeConverter;\n\npublic class oaep_rsa2048_java {\n\n    public static String toHexString(byte[] array) {\n        return DatatypeConverter.printHexBinary(array).toLowerCase();\n    }\n\n    public static byte[] toByteArray(String s) {\n        return DatatypeConverter.parseHexBinary(s);\n    }\n\n    public static void main(String[] args) throws Exception {\n        Security.addProvider(new BouncyCastleProvider());\n        SecureRandom random = new SecureRandom();\n\n        Cipher cipher = Cipher.getInstance(\"RSA/None/OAEPWithSHA1AndMGF1Padding\", \"BC\");\n        KeyFactory kf = KeyFactory.getInstance(\"RSA\");\n\n        byte[] input = toByteArray(args[args.length-1]);\n\n        if (args.length < 4) {\n            BigInteger modulus = new BigInteger(args[0], 16);\n            BigInteger publicExponent = new BigInteger(args[1], 16);\n\n            RSAPublicKeySpec puK = new RSAPublicKeySpec(modulus, publicExponent);\n            PublicKey pubKey = kf.generatePublic(puK);\n            \n            cipher.init(Cipher.ENCRYPT_MODE, pubKey, random);\n            byte[] cipherText = cipher.doFinal(input);\n            System.out.println(toHexString(cipherText));\n        } else {\n            BigInteger prime1 = new BigInteger(args[0], 16);\n            BigInteger prime2 = new BigInteger(args[1], 16);\n            BigInteger modulus = prime1.multiply(prime2);\n            BigInteger publicExponent = new BigInteger(args[2], 16);\n            BigInteger privateExponent = new BigInteger(args[3], 16);\n            BigInteger exponent1 = privateExponent.mod(prime1.subtract(BigInteger.ONE));\n            BigInteger exponent2 = privateExponent.mod(prime2.subtract(BigInteger.ONE));\n            BigInteger coefficient = prime2.modInverse(prime1);\n            \n            RSAPrivateKey pKy = new RSAPrivateKey(modulus, publicExponent, privateExponent, prime1, prime2, exponent1, exponent2, coefficient);\n            PrivateKey privKey = kf.generatePrivate(new PKCS8EncodedKeySpec(pKy.getEncoded()));\n            \n            cipher.init(Cipher.DECRYPT_MODE, privKey);\n            byte[] plainText = cipher.doFinal(input);\n            System.out.println(toHexString(plainText));\n        }\n    }\n}\n"
  },
  {
    "path": "examples/oaep_rsa2048_java_wrapper.go",
    "content": "// Please, note that you will need to add a folder called libs here and put\n//  the bouncycastle file bcprov-jdk15on-155.jar in it.\n// Otherwise the wrapper and the makefile won't work.\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\nfunc main() {\n\targ := []string{\"-cp\", \".:./examples:./libs/bcprov-ext-jdk15on-155.jar:./examples/libs/bcprov-ext-jdk15on-155.jar\", \"oaep_rsa2048_java\"}\n\targ = append(arg, os.Args[1:]...)\n\n\tcmd := exec.Command(\"java\", arg...)\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\tfmt.Println(strings.TrimSpace(string(out)))\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(strings.TrimSpace(string(out)))\n}\n"
  },
  {
    "path": "examples/oaep_rsa2048_mbedtls.c",
    "content": "#include \"mbedtls/asn1.h\"\n#include \"mbedtls/config.h\"\n#include \"mbedtls/ctr_drbg.h\"\n#include \"mbedtls/rsa.h\"\n#include \"mbedtls/entropy.h\"\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#define PADDING_TYPE MBEDTLS_RSA_PKCS_V21\n#define HASH_TYPE MBEDTLS_MD_SHA1\n\n// convert a char to its binary representation, from hex\nstatic int toBin(unsigned char val)\n{\n    if (val >= '0' && val <= '9')\n        return val - '0';\n    else if (val >= 'a' && val <= 'f')\n        return val - 'a' + 10;\n    else if (val >= 'A' && val <= 'F')\n        return val - 'A' + 10;\n    else\n        assert(0);\n    return -1;\n}\n\n// unhexlify a given string\nstatic int unhex(unsigned char* out, const char* in)\n{\n    unsigned char a, b;\n    int len = strlen(in) / 2;\n    assert(strlen(in) == 2 * len);\n\n    while (*in != 0) {\n        a = *in++;\n        b = *in++;\n        *out++ = (toBin(a) << 4) | toBin(b);\n    }\n    return len;\n}\n\n// print a big integer to the stdout\nstatic void dump_mpi(const mbedtls_mpi* d)\n{\n    mbedtls_mpi_write_file(NULL, d, 16, NULL);\n}\n\nint main(int argc, char* argv[])\n{\n    // Parsing argument:\n    int ret = 1;\n    int encrypt = 0;\n    if (argc == 4) {\n        encrypt =  1;\n    } else if (argc != 6) {\n        printf(\"usage: \\t%s N,E, Plain\\nor \\t%s P, Q, E, D, Cipher\\n\", argv[0], argv[0]);\n        return -1;\n    }\n    // the MbedTLS variables:\n    mbedtls_rsa_context rsa_ctx;\n    mbedtls_entropy_context entropy;\n    mbedtls_ctr_drbg_context ctr_drbg;\n    const char* pers = \"rsa\";\n\n    // we must unhexlify the data:\n    const char* str = argv[argc - 1];\n    unsigned char* msg = (unsigned char*)malloc(strlen(str) / 2 * sizeof(unsigned char));\n    size_t mlen;\n    mlen = unhex(msg, str);\n\n    // We initialize all the variables:\n    mbedtls_rsa_init(&rsa_ctx, PADDING_TYPE, HASH_TYPE);\n    mbedtls_entropy_init(&entropy);\n    mbedtls_ctr_drbg_init(&ctr_drbg);\n\n\n    if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,\n                    (const unsigned char*)pers,\n                    strlen(pers)))\n            != 0) {\n        printf(\" failed\\n  ! mbedtls_ctr_drbg_seed returned %d\\n\", ret);\n        goto exit;\n    }\n\n    size_t* olen = (size_t*)malloc(sizeof(size_t));\n\n    if (encrypt) {\n        // We set our variables using the args\n        if ((ret = mbedtls_mpi_read_string(&rsa_ctx.N, 16, argv[1])) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n        rsa_ctx.len = ( mbedtls_mpi_bitlen( &rsa_ctx.N  ) + 7  ) >> 3;\n        if ((ret = mbedtls_mpi_read_string(&rsa_ctx.E, 16, argv[2])) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n\n        if ((ret = mbedtls_rsa_check_pubkey(&rsa_ctx)) != 0){\n            printf(\" failed\\n  ! mbedtls_rsa_check_pubkey returned %d\\n\", ret);\n            goto exit;\n        }\n\n        // The output buffer must be as large as the size of ctx->N\n        unsigned char output[mbedtls_mpi_size(&rsa_ctx.N)];\n        if ((ret = mbedtls_rsa_rsaes_oaep_encrypt(&rsa_ctx, \n                        mbedtls_ctr_drbg_random, &ctr_drbg,\n                        MBEDTLS_RSA_PUBLIC, NULL, 0,\n                        mlen, msg, output )) != 0) {\n            printf(\" failed\\n  ! mbedtls_rsa_rsaes_oaep_encrypt returned -%x\\n\", -ret);\n            goto exit;\n        } \n        for (unsigned long i = 0; i < rsa_ctx.len; ++i)\n            printf(\"%02x\", output[i]);\n        printf(\"\\n\");\n    } else { // we are not encrypting, so we are decrypting\n\n        // We set our variables using the args\n        if ((ret = mbedtls_mpi_read_string(&rsa_ctx.P, 16, argv[1])) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n        if ((ret = mbedtls_mpi_read_string(&rsa_ctx.Q, 16, argv[2])) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n\n        if ((ret = mbedtls_mpi_read_string(&rsa_ctx.E, 16, argv[3])) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n        if ((ret = mbedtls_mpi_read_string(&rsa_ctx.D, 16, argv[4])) != 0) {\n            printf(\" failed\\n  ! mbedtls_mpi_read_string returned -0x%02X\\n\", -ret);\n            goto exit;\n        }\n\n        // we set the rest\n        if ((ret =  mbedtls_mpi_mul_mpi( &rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q )) != 0 ) {\n            printf(\" failed\\n  ! mbedtls_mpi_mul_mpi returned %X\\n\", -ret);\n            goto exit;\n        }\n        rsa_ctx.len = ( mbedtls_mpi_bitlen( &rsa_ctx.N  ) + 7  ) >> 3;\n\n        // If we want to build a priv key in mbedtls, we must provide those:\n        mbedtls_mpi P1, Q1;\n        mbedtls_mpi_init( &P1  ); mbedtls_mpi_init( &Q1  ); \n        mbedtls_mpi_sub_int( &P1, &rsa_ctx.P, 1 );\n        mbedtls_mpi_sub_int( &Q1, &rsa_ctx.Q, 1 );\n\n        mbedtls_mpi_mod_mpi( &rsa_ctx.DP, &rsa_ctx.D, &P1 );\n        mbedtls_mpi_mod_mpi( &rsa_ctx.DQ, &rsa_ctx.D, &Q1 );\n        mbedtls_mpi_inv_mod( &rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P );\n\n        if ((ret = mbedtls_rsa_check_privkey(&rsa_ctx)) != 0){\n            printf(\" failed\\n  ! mbedtls_rsa_check_privkey returned %X\\n\", -ret);\n            ret = EXIT_FAILURE;\n            goto exit;\n        }\n\n        // The output buffer must be as large as the size of ctx->N\n        unsigned char output[mbedtls_mpi_size(&rsa_ctx.N)];\n        if ((ret = mbedtls_rsa_rsaes_oaep_decrypt(&rsa_ctx, \n                        mbedtls_ctr_drbg_random, &ctr_drbg,\n                        MBEDTLS_RSA_PRIVATE, NULL, 0, // label = NULL and label_len = 0\n                        olen, msg, output, rsa_ctx.len)) != 0) {\n\n            printf(\" failed\\n  ! mbedtls_rsa_rsaes_oaep_decrypt returned %X\\n\", -ret);\n            ret = EXIT_FAILURE;\n            goto exit;\n        } \n        for (size_t i = 0; i < *olen; ++i)\n            printf(\"%02x\", output[i]);\n        printf(\"\\n\");\n    }\n\nexit:\n    mbedtls_rsa_free(&rsa_ctx);\n    mbedtls_ctr_drbg_free(&ctr_drbg);\n    mbedtls_entropy_free(&entropy);\n    free(msg);\n    free(olen);\n    return (ret);\n}\n"
  },
  {
    "path": "examples/oaep_rsa2048_openssl.c",
    "content": "#include <assert.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"openssl/bn.h\"\n#include \"openssl/sha.h\"\n#include \"openssl/rsa.h\"\n#include \"openssl/evp.h\"\n\nvoid unhex(char* hex, unsigned char* data, size_t ilen)\n{\n    for (size_t i = 0; i < ilen; ++i) {\n        sscanf(hex, \"%2hhx\", &data[i]);\n        hex += 2;\n    }\n}\n\nvoid printBN(BIGNUM *r)\n{\n    char* out = BN_bn2hex(r);\n    const char *padding=\"0000000000000000000000000000000000000000000000000000000000000000\";\n    int padLen1 = 64 - strlen(out);\n    if(padLen1 < 0) padLen1 = 0;\n    printf(\"%*.*s%s\\n\", padLen1, padLen1, padding, out);\n    OPENSSL_free(out);\n}\n\nint main(int argc, char* argv[])\n{\n    // Our args\n    int encrypt;\n    int success = 0;\n\n    if (argc == 4) {\n        encrypt = 1;\n    } else if (argc - optind == 5) {\n        encrypt = 0;\n    } else {\n        printf(\"usage: \\t%s X, Y, D, M\\nor \\t%s X, Y, R, S, M\\n\", argv[0], argv[0]);\n        return -1;\n    }\n\n    // OpenSSL stuff:\n    int ret;\n\n    RSA *r = NULL;\n    r = RSA_new();\n\n    char* str = argv[argc - 1];\n    unsigned char* msg = (unsigned char*)malloc(strlen(str) / 2 * sizeof(unsigned char));\n    size_t mlen = strlen(str)/2;\n\n    unhex(str, msg, mlen); \n\n    unsigned char* to; \n\n    if (encrypt) {\n        // public key setup\n        BN_hex2bn(&r->n, argv[1]);\n        BN_hex2bn(&r->e, argv[2]);\n\n        to = (unsigned char*)malloc(RSA_size(r));\n\n        ret = RSA_public_encrypt(mlen, msg, to, r, RSA_PKCS1_OAEP_PADDING);\n        if (ret <= 0) {\n            printf(\"Failed to encrypt with those args.\\n\");\n            return -1;\n        } else {\n            for (int i = 0; i < ret; ++i)\n                printf(\"%02x\", to[i]);\n            printf(\"\\n\");\n        }\n\n    } else {\n        BN_CTX * tmp_bn;\n        tmp_bn = BN_CTX_new();\n        // private key setup\n        BN_hex2bn(&r->p, argv[1]);\n        BN_hex2bn(&r->q, argv[2]);\n        BN_hex2bn(&r->e, argv[3]);\n        BN_hex2bn(&r->d, argv[4]);\n        // compute n \n        r->n = BN_new();\n        BN_mul(r->n, r->p ,r->q,tmp_bn);\n\n        BN_CTX_free(tmp_bn);\n\n        to = (unsigned char*)malloc(RSA_size(r));\n\n        ret = RSA_check_key(r);\n        if (ret != 1){\n            /* error */\n            printf(\" failure RSA_check_key returned %d\", ret);\n            success = -1;\n        }\n\n        ret = RSA_private_decrypt(mlen,  msg, to, r, RSA_PKCS1_OAEP_PADDING );\n        if (ret <= 0) {\n            /* error */\n            printf(\" failure RSA_private_decrypt returned %d\", ret);\n            success = -1;\n        } else {\n            for (int i = 0; i < ret; ++i)\n                printf(\"%02x\", to[i]);\n            printf(\"\\n\");\n        }\n    }\n\n    RSA_free(r);\n\n    return success;\n}\n"
  },
  {
    "path": "examples/oaep_rsa2048_pycrypto.py",
    "content": "#!/usr/bin/env python3\n\nfrom Crypto.Cipher import PKCS1_OAEP\nfrom Crypto.PublicKey import RSA\n\nimport sys\nimport binascii\n\nencrypt = False\ndecrypt = False\n\nif len(sys.argv) == 4:\n    encrypt = True\nelif len(sys.argv) == 6:\n    decrypt = True\nelse:\n    print(\"FAIL\")\n    sys.exit(1)\n\nif encrypt:\n    pk = RSA.construct((int(sys.argv[1], 16), int(sys.argv[2], 16)))\n    message = binascii.unhexlify(sys.argv[3])\n    cipher = PKCS1_OAEP.new(pk)\n    ciphertext = cipher.encrypt(message)\n\n    print(ciphertext.hex())\n\nif decrypt:\n    ciphertext = binascii.unhexlify(sys.argv[5])\n    pky = RSA.construct(\n        (int(sys.argv[1], 16) * int(sys.argv[2], 16), int(sys.argv[3], 16),\n         int(sys.argv[4], 16), int(sys.argv[1], 16), int(sys.argv[2], 16)))\n    cipher = PKCS1_OAEP.new(pky)\n    recovered = cipher.decrypt(ciphertext)\n    print(recovered.hex())\n"
  },
  {
    "path": "examples/pkcs_rsa2048_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/big\"\n\t\"os\"\n)\n\n// A helper method to use the prime in hex form, from crypto/cipher\nfunc fromBase16(base16 string) *big.Int {\n\ti, ok := new(big.Int).SetString(base16, 16)\n\tif !ok {\n\t\tpanic(\"bad number: \" + base16)\n\t}\n\treturn i\n}\n\nvar encrypting bool\n\nfunc main() {\n\tvar test2048Key *rsa.PrivateKey\n\n\tswitch len(os.Args) {\n\tcase 4:\n\t\tencrypting = true\n\tcase 6:\n\t\tencrypting = false\n\tdefault:\n\t\tlog.Fatal(\"Please provide N,E,Plain or P1,P2,E,D,Cipher as arguments\")\n\t}\n\tvar plaintext string\n\tvar Nn, Dd, P1, P2 *big.Int\n\tvar Ee int\n\tif encrypting {\n\t\tplaintext = os.Args[3]\n\t\tNn = fromBase16(os.Args[1])\n\t\tEe = int(fromBase16(os.Args[2]).Int64())\n\t} else {\n\t\tP1 = fromBase16(os.Args[1])\n\t\tP2 = fromBase16(os.Args[2])\n\t\tNn = (new(big.Int).Mul(P1, P2))\n\t\tEe = int(fromBase16(os.Args[3]).Int64())\n\t\tDd = fromBase16(os.Args[4])\n\t\tplaintext = os.Args[5]\n\t}\n\n\tpubKey := rsa.PublicKey{\n\t\tN: Nn,\n\t\tE: Ee,\n\t}\n\tif !encrypting {\n\t\ttest2048Key = &rsa.PrivateKey{\n\t\t\tPublicKey: rsa.PublicKey{\n\t\t\t\tN: Nn,\n\t\t\t\tE: Ee,\n\t\t\t},\n\t\t\tD: Dd,\n\t\t\tPrimes: []*big.Int{\n\t\t\t\tP1,\n\t\t\t\tP2,\n\t\t\t},\n\t\t}\n\t\ttest2048Key.Precompute()\n\t}\n\t// According to the doc, the size of the plaintext shouldn't be\n\t// bigger than that of the public modulus - 11 bytes !\n\t// TODO: Check this\n\trng := rand.Reader\n\n\tif encrypting {\n\t\tsecretMessage := []byte(plaintext)\n\n\t\tciphertext, err := rsa.EncryptPKCS1v15(rng, &pubKey, secretMessage)\n\t\tif err != nil {\n\t\t\tlog.Fatalln(err, \"FAIL\")\n\t\t}\n\t\tfmt.Printf(\"%x\\n\", ciphertext)\n\t} else {\n\t\t// Let's decrypt it :\n\n\t\tmessage, err := hex.DecodeString(plaintext)\n\t\tif err != nil {\n\t\t\tlog.Fatalln(err, \"FAIL\")\n\t\t}\n\t\tnewplaintext, err2 := rsa.DecryptPKCS1v15(rng, test2048Key, message)\n\t\tif err2 != nil {\n\t\t\tlog.Fatalln(err2, \"FAIL\")\n\t\t}\n\n\t\tfmt.Printf(\"%s\\n\", string(newplaintext))\n\t}\n}\n"
  },
  {
    "path": "examples/pkcs_rsa2048_pycrypto.py",
    "content": "#!/usr/bin/env python3\n\nfrom Crypto.Cipher import PKCS1_v1_5\nfrom Crypto.PublicKey import RSA\nfrom Crypto import Random\n\nimport sys\nimport binascii\n\nencrypt = False\ndecrypt = False\n\nif len(sys.argv) == 4:\n    encrypt = True\nelif len(sys.argv) == 6:\n    decrypt = True\nelse:\n    print(\"FAIL: wrong arguments\")\n    sys.exit(1)\n\nif encrypt:\n    pk = RSA.construct((int(sys.argv[1], 16), int(sys.argv[2], 16)))\n    message = bytes(sys.argv[3], 'utf-8')\n    cipher = PKCS1_v1_5.new(pk)\n    ciphertext = cipher.encrypt(message)\n    print(ciphertext.hex())\n\nif decrypt:\n    ciphertext = binascii.unhexlify(sys.argv[5])\n    # We construct the private key from the arguments P, Q, E, D :\n    pky = RSA.construct(\n        (int(sys.argv[1], 16) * int(sys.argv[2], 16), int(sys.argv[3], 16),\n         int(sys.argv[4], 16), int(sys.argv[1], 16), int(sys.argv[2], 16)))\n\n    cipher = PKCS1_v1_5.new(pky)\n    sentinel = b'sentinel'  # just a sentinel since pycrypto wants one\n    recovered = cipher.decrypt(ciphertext, sentinel)\n    if recovered == sentinel:  # This should not be done in practice\n        print(\"FAIL\")\n    else:\n        print(recovered.decode('utf-8'))\n"
  },
  {
    "path": "examples/pkcssign_rsa_go.go",
    "content": "package main\n\nimport (\n\t\"crypto\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"flag\"\n\t\"fmt\"\n\t\"hash\"\n\t\"log\"\n\t\"math/big\"\n\t\"os\"\n)\n\nvar custom_hash = flag.String(\"h\", \"\", \"If one want to specifiy the hash directly\")\n\n// fromBase16 is a helper method to use the prime in hex form, inspired from crypto/rsa/rsa_test.go\nfunc fromBase16(base16 string) *big.Int {\n\ti, ok := new(big.Int).SetString(base16, 16)\n\tif !ok {\n\t\tlog.Fatalln(\"trying to convert from base16 a bad number: \"+base16,\n\t\t\t\"\\nGot the following args:\", flag.Args())\n\t}\n\treturn i\n}\n\nfunc main() {\n\tvar rsaKey *rsa.PrivateKey\n\n\tflag.Parse()\n\t// The hash used\n\tvar h hash.Hash\n\th = sha256.New()\n\n\tvar signing bool\n\n\tswitch {\n\tcase len(flag.Args()) == 4:\n\t\tsigning = false\n\tcase len(flag.Args()) == 5:\n\t\tsigning = true\n\tdefault:\n\t\tlog.Fatal(\"Please provide P1, P2, E, D, Msg or N, E, Sign, Msg as arguments in order to respectively sign Msg or verify a signature Sign for Msg.\")\n\t}\n\n\tvar Nn, Dd, P1, P2 *big.Int\n\tvar Ee int\n\tif !signing {\n\t\tNn = fromBase16(flag.Arg(0))\n\t\tEe = int(fromBase16(flag.Arg(1)).Int64())\n\t} else {\n\t\tP1 = fromBase16(flag.Arg(0))\n\t\tP2 = fromBase16(flag.Arg(1))\n\t\tNn = (new(big.Int).Mul(P1, P2))\n\t\tEe = int(fromBase16(flag.Arg(2)).Int64())\n\t\tDd = fromBase16(flag.Arg(3))\n\t}\n\n\tpubKey := rsa.PublicKey{\n\t\tN: Nn,\n\t\tE: Ee,\n\t}\n\tif signing {\n\t\trsaKey = &rsa.PrivateKey{\n\t\t\tPublicKey: rsa.PublicKey{\n\t\t\t\tN: Nn,\n\t\t\t\tE: Ee,\n\t\t\t},\n\t\t\tD: Dd,\n\t\t\tPrimes: []*big.Int{\n\t\t\t\tP1,\n\t\t\t\tP2,\n\t\t\t},\n\t\t}\n\t\trsaKey.Precompute()\n\t}\n\n\t// msg is always in latest position\n\t// we are decoding from hex to have truly random messages\n\tmsg, err := hex.DecodeString(flag.Arg(len(flag.Args()) - 1))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// We handle the hashing of the data:\n\th.Write(msg)\n\tvar signhash []byte\n\tif *custom_hash == \"\" { // if the flag -h is not set, its default is \"\" and we hash the message\n\t\tsignhash = h.Sum(nil)\n\t} else {\n\t\tvar err error\n\t\tsignhash, err = hex.DecodeString(*custom_hash)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\tif signing {\n\n\t\tsignature, err := rsa.SignPKCS1v15(nil, rsaKey, crypto.SHA256, signhash[:])\n\t\tif err != nil {\n\t\t\tfmt.Fprintf(os.Stderr, \"Error from signing: %s\\n\", err)\n\t\t\treturn\n\n\t\t}\n\t\tfmt.Printf(\"%s\\n\", hex.EncodeToString(signature))\n\t} else {\n\t\t// if we are not signing, we are verifying :\n\t\tsign, errh := hex.DecodeString(flag.Arg(2))\n\t\tif errh != nil {\n\t\t\tlog.Fatal(errh)\n\t\t}\n\t\terr := rsa.VerifyPKCS1v15(&pubKey, crypto.SHA256, signhash[:], sign)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"false\\n\")\n\t\t\treturn\n\t\t}\n\t\tfmt.Printf(\"true\\n\")\n\t}\n}\n"
  },
  {
    "path": "examples/prf_hmacsha256_go.go",
    "content": "package main\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"os\"\n)\n\nfunc main() {\n\tk, _ := hex.DecodeString(os.Args[1])\n\tin, _ := hex.DecodeString(os.Args[2])\n\n\th := hmac.New(sha256.New, k)\n\th.Write([]byte(in))\n\ttag := hex.EncodeToString(h.Sum(nil))\n\n\tfmt.Println(tag)\n}\n"
  },
  {
    "path": "examples/prf_hmacsha256_hmac.py",
    "content": "#!/usr/bin/env python3\n\nfrom hashlib import sha256\nimport binascii\nimport hmac\nimport sys\n\nkey = binascii.unhexlify(sys.argv[1])\nmessage = binascii.unhexlify(sys.argv[2])\n\nhm = hmac.new(key, message, digestmod=sha256)\nmac = hm.hexdigest()\n\nprint(mac)\n"
  },
  {
    "path": "examples/prf_hmacsha256_openssl.c",
    "content": "#include <inttypes.h>\n#include <openssl/hmac.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nint main(int ac, char** av)\n{\n\n    EVP_MD* hash = (EVP_MD*)EVP_sha256();\n    uint8_t out[32];\n    char* kx = av[1];\n    char* inx = av[2];\n\n    size_t kxlen = strlen(kx); // nibbles\n    size_t klen = kxlen / 2; // bytes\n    size_t inxlen = strlen(inx);\n    size_t inlen = inxlen / 2;\n\n    uint8_t* k = (uint8_t*)malloc(klen);\n    uint8_t* in = (uint8_t*)malloc(inlen);\n\n    for (size_t i = 0; i < klen; ++i) {\n        sscanf(kx, \"%2hhx\", &k[i]);\n        kx += 2;\n    }\n\n    for (size_t i = 0; i < inlen; ++i) {\n        sscanf(inx, \"%2hhx\", &in[i]);\n        inx += 2;\n    }\n\n    unsigned int outlen;\n    HMAC(hash, k, klen, in, inlen, out, &outlen);\n\n    if (outlen != 32) {\n        printf(\"WTF\\n\");\n    }\n\n    free(k);\n    free(in);\n\n    for (size_t i = 0; i < 32; ++i)\n        printf(\"%02x\", out[i]);\n    printf(\"\\n\");\n\n    return 0;\n}\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"os\"\n\n\t\"github.com/kudelskisecurity/cdf/cdf-lib\"\n)\n\nvar interf string\nvar interfaces = map[string]bool{\n\t//\"aenc\":  true,\n\t\"dsa\":     true,\n\t\"enc\":     true,\n\t\"ecdsa\":   true,\n\t\"ecdh\":    true,\n\t\"rsaenc\":  true,\n\t\"rsasign\": true,\n\t\"prf\":     true,\n\t\"xof\":     true,\n}\n\n// usage() is called when the input doesn't seem to match an accepted pattern, it also serves as help display\nfunc usage() {\n\tflag.Usage()\n\tfmt.Println(\"To perform the tests: \\ncdf interface path/to/program1 path/to/program2\")\n\tfmt.Println(\"Interfaces and their programs' i/o:\")\n\tfmt.Println(\"\\tecdsa\\t[privkey msg -> sig] [pubkey sig msg -> validity]\")\n\tfmt.Println(\"\\tenc\\t[key plaintext -> ciphertext] [key ciphertext -> plaintext]\")\n\tfmt.Println(\"\\tdsa\\t[privkey msg -> sig] [pubkey msg sig -> validity]\")\n\tfmt.Println(\"\\tprf\\t[key msg -> tag] [key msg -> tag]\")\n\tfmt.Println(\"\\trsaenc\\t[pubkey plaintext -> ciphertext] [privkey ciphertext -> plaintext]\")\n\tfmt.Println(\"\\trsasign\\t[privkey msg -> sign] [pubkey sign msg -> validity]\")\n\tfmt.Println(\"\\txof\\t[message -> hash] [message -> hash]\")\n}\n\n// init() is a function to handle flags initialization and parsing. It will initialize our flags to parse the Args data, must be done before using flag.Args(). It also perform basic existence checks on the provided program path. If something is missing, it falls back to usage() which will exit gracefully.\nfunc init() {\n\t// the -t n flag allows to run n timing tests using the dudect method.\n\tcdf.TestTimings = flag.Int(\"t\", 0, \"to perform N timing leak tests, specify N. It may take hours.\")\n\t// the -h flag can be used to specify that the provided programs both support the optional -h flag\n\tcdf.TestHashes = flag.Bool(\"h\", false, \"specify that the provided programs both support the optional -h flag.\")\n\t// the -v flag can be used to force verbose logging\n\tcdf.ForceVerbose = flag.Bool(\"v\", false, \"force the VerboseLog option to true.\")\n\n\tflag.Parse()\n\t// check that we've three arguments left\n\tnbArgs := len(flag.Args())\n\tif nbArgs != 3 {\n\t\tusage()\n\t\tos.Exit(1)\n\t}\n\n\tif _, ok := interfaces[flag.Arg(0)]; ok {\n\t\tinterf = flag.Arg(0)\n\t} else {\n\t\tlog.Fatalln(\"invalid interface\")\n\t}\n\n\t// get programs' paths, check existence\n\tcdf.Prog1 = flag.Arg(1)\n\tcdf.Prog2 = flag.Arg(2)\n\tif _, err := os.Stat(cdf.Prog1); os.IsNotExist(err) {\n\t\tlog.Fatalln(\"this file doesn't exist: \", cdf.Prog1)\n\t}\n\tif _, err := os.Stat(cdf.Prog2); os.IsNotExist(err) {\n\t\tlog.Fatalln(\"this file doesn't exist:\", cdf.Prog2)\n\t}\n}\n\nfunc main() {\n\tlogFile, err := os.OpenFile(\"log.txt\", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)\n\tif err != nil {\n\t\tlog.Fatalln(\"Failed to open log file:\", err)\n\t}\n\t// close logFile on exit checking for its error to ensure everything get written.\n\tdefer func() {\n\t\tif err := logFile.Close(); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}()\n\n\tcdf.InitLog(logFile)\n\n\t// clear the screen since we are not in usage mode\n\tcdf.TermClear()\n\tcdf.LogInfo.Println(\"Running CDF:\")\n\n\t// get config and show\n\tconfigFile, err := os.Open(\"config.json\")\n\tif err != nil {\n\t\tlog.Fatalln(err)\n\t}\n\t// close configFile on exit checking for its error:\n\tdefer func() {\n\t\tif err := configFile.Close(); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}()\n\n\tif err := json.NewDecoder(configFile).Decode(&cdf.Config); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n\tif cdf.Config.Timeout == 0 { // we specify a default timeout\n\t\tcdf.Config.Timeout = 10\n\t}\n\tcdf.LogInfo.Printf(\"config: %+v\", cdf.Config)\n\n\t// disable logging if the setting is not set\n\tif !cdf.Config.VerboseLog && !*cdf.ForceVerbose {\n\t\tcdf.DisableLogFile()\n\t}\n\t// init prng\n\tvar src = rand.NewSource(cdf.Config.Seed)\n\tcdf.Prng = rand.New(src)\n\n\t// depending on the selected interface, we run the according test function\n\tswitch interf {\n\tcase \"dsa\":\n\t\terr = cdf.TestDsa()\n\t\tbreak\n\tcase \"ecdsa\":\n\t\terr = cdf.TestEcdsa()\n\t\tbreak\n\tcase \"enc\":\n\t\terr = cdf.TestEnc()\n\t\tbreak\n\tcase \"rsaenc\":\n\t\terr = cdf.TestRSAenc()\n\t\tbreak\n\tcase \"rsasign\":\n\t\terr = cdf.TestRSAsign()\n\t\tbreak\n\tcase \"prf\":\n\t\terr = cdf.TestPrf()\n\t\tbreak\n\tcase \"xof\":\n\t\terr = cdf.TestXof()\n\t\tbreak\n\t}\n\n\tif err == nil {\n\t\tcdf.LogSuccess.Println(\"test completed without error!\")\n\t} else {\n\t\tcdf.LogWarning.Println(err)\n\t}\n\n\tcdf.LogInfo.Println(\"exiting\")\n}\n"
  },
  {
    "path": "makefile",
    "content": "\nBIN = cdf\n\nSRC = main.go\n\n.DEFAULT_GOAL = build\n\n.PHONY: clean format examples\n\nbuild:          $(SRC) \n\t        \tgo build -o $(BIN) $^ \n\nrun:            $(SRC) \n\t        \tgo run $^ \n\nexamples-go:    $(SRC) \n\t        \tcd examples/; make go\n\nexamples-all:   $(SRC)\n\t        \tcd examples/; make\n\nformat:         $(SRC) \n\t        \t$(foreach f, $(SRC), gofmt -w $(f))\n\ntest:\n\t\t\t\tgo test -v ./cdf-lib\n\nclean:         \n\t        \trm -f $(BIN); cd examples/; make clean\n"
  }
]