diff options
-rw-r--r-- | .gitignore | 10 | ||||
-rw-r--r-- | .testfile | 5 | ||||
-rw-r--r-- | COPYING | 17 | ||||
-rw-r--r-- | LICENSE | 670 | ||||
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | doc/info/agpl-3.0.texinfo | 698 | ||||
-rw-r--r-- | doc/info/fdl-1.3.texinfo | 505 | ||||
-rw-r--r-- | doc/info/libkeccak.texinfo | 36 | ||||
-rwxr-xr-x | src/benchmark-flags | 100 | ||||
-rw-r--r-- | src/benchmark.c | 172 | ||||
-rw-r--r-- | src/libkeccak.h | 24 | ||||
-rw-r--r-- | src/libkeccak/digest.c | 708 | ||||
-rw-r--r-- | src/libkeccak/digest.h | 40 | ||||
-rw-r--r-- | src/libkeccak/files.c | 87 | ||||
-rw-r--r-- | src/libkeccak/files.h | 73 | ||||
-rw-r--r-- | src/libkeccak/generalised-spec.c | 194 | ||||
-rw-r--r-- | src/libkeccak/generalised-spec.h | 114 | ||||
-rw-r--r-- | src/libkeccak/hex.c | 73 | ||||
-rw-r--r-- | src/libkeccak/hex.h | 28 | ||||
-rw-r--r-- | src/libkeccak/internal.h | 31 | ||||
-rw-r--r-- | src/libkeccak/mac/hmac.c | 622 | ||||
-rw-r--r-- | src/libkeccak/mac/hmac.h | 294 | ||||
-rw-r--r-- | src/libkeccak/spec.h | 145 | ||||
-rw-r--r-- | src/libkeccak/state.c | 185 | ||||
-rw-r--r-- | src/libkeccak/state.h | 247 | ||||
-rw-r--r-- | src/test.c | 1053 |
27 files changed, 1949 insertions, 4198 deletions
@@ -1,12 +1,7 @@ -_/ +*~ +*\#* bin/ obj/ -\#*\#* -.* -!.git* -*~ -*.sw[op] -*.bak *.o *.out *.so @@ -18,4 +13,3 @@ obj/ *.ps *.dvi *.test - diff --git a/.testfile b/.testfile new file mode 100644 index 0000000..54fd403 --- /dev/null +++ b/.testfile @@ -0,0 +1,5 @@ +gC2UOev7P8UxjTKic839L3tBVFPTeP8dOTpsygPrZYsZGEn +P885UjL5IuiyPA0WOTgcwOB808O98w8vjn5MP1DpAdyhACw +XEwzxgJhHANCEbs88PJoNIWzCqY1zAr5ZKAQNrE4QQM1pik +fhwrDOudGcZ08tUs2wYhhELGE3XgHqEpUEebxD3xIZa78EO +MRd1VsUWm1pfuqbCb3M5tIQFErSpUBOjAXTXDS1swc1KVc7 diff --git a/COPYING b/COPYING deleted file mode 100644 index cf8c14a..0000000 --- a/COPYING +++ /dev/null @@ -1,17 +0,0 @@ -libkeccak – Keccak-family hashing library - -Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this library. If not, see <http://www.gnu.org/licenses/>. - @@ -1,661 +1,15 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 +ISC License - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +© 2014, 2015, 2017 Mattias Andrée <maandree@kth.se> - Preamble +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -<http://www.gnu.org/licenses/>. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. @@ -228,9 +228,9 @@ bin/%.ps: doc/info/%.texinfo doc/info/*.texinfo .PHONY: check check: bin/test bin/libkeccak.so bin/libkeccak.so.$(LIB_MAJOR) bin/libkeccak.so.$(LIB_VERSION) - @test $$(sha256sum LICENSE | cut -d ' ' -f 1) = \ - 57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 || \ - ( echo 'The file LICENSE is incorrect, test will fail!' ; false ) + @test $$(sha256sum .testfile | cut -d ' ' -f 1) = \ + e21d814d21ca269246849cc105faec1a71ac7d1cdb1a86023254f49d51b47231 || \ + ( echo 'The file .testfile is incorrect, test will fail!' ; false ) env LD_LIBRARY_PATH=bin valgrind --leak-check=full bin/test test $$(env LD_LIBRARY_PATH=bin valgrind bin/test 2>&1 >/dev/null | wc -l) = 14 # Using valgrind 3.10.0, its output to standard error should consist of 14 lines, @@ -283,12 +283,7 @@ install-static-lib: bin/libkeccak.a install -m644 -- bin/libkeccak.a "$(DESTDIR)$(LIBDIR)/libkeccak.a" .PHONY: install-copyright -install-copyright: install-copying install-license - -.PHONY: install-copying -install-copying: - install -dm755 -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)" - install -m644 -- COPYING "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/COPYING" +install-copyright: install-license .PHONY: install-license install-license: @@ -13,6 +13,3 @@ RATIONALE SEE ALSO sha3sum, libsha2(7) - - Full documentation available locally via: info '(libkeccak)' - diff --git a/doc/info/agpl-3.0.texinfo b/doc/info/agpl-3.0.texinfo deleted file mode 100644 index e6ee662..0000000 --- a/doc/info/agpl-3.0.texinfo +++ /dev/null @@ -1,698 +0,0 @@ -@c The GNU Affero General Public License. -@center Version 3, 19 November 2007 - -@c This file is intended to be included within another document, -@c hence no sectioning command or @node. - -@display -Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/} - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. -@end display - -@heading Preamble - -The GNU Affero General Public License is a free, copyleft license -for software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - -The licenses for most software and other practical works are -designed to take away your freedom to share and change the works. By -contrast, our General Public Licenses are intended to guarantee your -freedom to share and change all versions of a program--to make sure it -remains free software for all its users. - -When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - -Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - -A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - -The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - -An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - -The precise terms and conditions for copying, distribution and -modification follow. - -@heading TERMS AND CONDITIONS - -@enumerate 0 -@item Definitions. - -``This License'' refers to version 3 of the GNU Affero General Public License. - -``Copyright'' also means copyright-like laws that apply to other kinds -of works, such as semiconductor masks. - -``The Program'' refers to any copyrightable work licensed under this -License. Each licensee is addressed as ``you''. ``Licensees'' and -``recipients'' may be individuals or organizations. - -To ``modify'' a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of -an exact copy. The resulting work is called a ``modified version'' of -the earlier work or a work ``based on'' the earlier work. - -A ``covered work'' means either the unmodified Program or a work based -on the Program. - -To ``propagate'' a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - -To ``convey'' a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user -through a computer network, with no transfer of a copy, is not -conveying. - -An interactive user interface displays ``Appropriate Legal Notices'' to -the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - -@item Source Code. - -The ``source code'' for a work means the preferred form of the work for -making modifications to it. ``Object code'' means any non-source form -of a work. - -A ``Standard Interface'' means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - -The ``System Libraries'' of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -``Major Component'', in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - -The ``Corresponding Source'' for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can -regenerate automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same -work. - -@item Basic Permissions. - -All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, -without conditions so long as your license otherwise remains in force. -You may convey covered works to others for the sole purpose of having -them make modifications exclusively for you, or provide you with -facilities for running those works, provided that you comply with the -terms of this License in conveying all material for which you do not -control copyright. Those thus making or running the covered works for -you must do so exclusively on your behalf, under your direction and -control, on terms that prohibit them from making any copies of your -copyrighted material outside their relationship with you. - -Conveying under any other circumstances is permitted solely under the -conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - -@item Protecting Users' Legal Rights From Anti-Circumvention Law. - -No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - -When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such -circumvention is effected by exercising rights under this License with -respect to the covered work, and you disclaim any intention to limit -operation or modification of the work as a means of enforcing, against -the work's users, your or third parties' legal rights to forbid -circumvention of technological measures. - -@item Conveying Verbatim Copies. - -You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - -You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - -@item Conveying Modified Source Versions. - -You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these -conditions: - -@enumerate a -@item -The work must carry prominent notices stating that you modified it, -and giving a relevant date. - -@item -The work must carry prominent notices stating that it is released -under this License and any conditions added under section 7. This -requirement modifies the requirement in section 4 to ``keep intact all -notices''. - -@item -You must license the entire work, as a whole, under this License to -anyone who comes into possession of a copy. This License will -therefore apply, along with any applicable section 7 additional terms, -to the whole of the work, and all its parts, regardless of how they -are packaged. This License gives no permission to license the work in -any other way, but it does not invalidate such permission if you have -separately received it. - -@item -If the work has interactive user interfaces, each must display -Appropriate Legal Notices; however, if the Program has interactive -interfaces that do not display Appropriate Legal Notices, your work -need not make them do so. -@end enumerate - -A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -``aggregate'' if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - -@item Conveying Non-Source Forms. - -You may convey a covered work in object code form under the terms of -sections 4 and 5, provided that you also convey the machine-readable -Corresponding Source under the terms of this License, in one of these -ways: - -@enumerate a -@item -Convey the object code in, or embodied in, a physical product -(including a physical distribution medium), accompanied by the -Corresponding Source fixed on a durable physical medium customarily -used for software interchange. - -@item -Convey the object code in, or embodied in, a physical product -(including a physical distribution medium), accompanied by a written -offer, valid for at least three years and valid for as long as you -offer spare parts or customer support for that product model, to give -anyone who possesses the object code either (1) a copy of the -Corresponding Source for all the software in the product that is -covered by this License, on a durable physical medium customarily used -for software interchange, for a price no more than your reasonable -cost of physically performing this conveying of source, or (2) access -to copy the Corresponding Source from a network server at no charge. - -@item -Convey individual copies of the object code with a copy of the written -offer to provide the Corresponding Source. This alternative is -allowed only occasionally and noncommercially, and only if you -received the object code with such an offer, in accord with subsection -6b. - -@item -Convey the object code by offering access from a designated place -(gratis or for a charge), and offer equivalent access to the -Corresponding Source in the same way through the same place at no -further charge. You need not require recipients to copy the -Corresponding Source along with the object code. If the place to copy -the object code is a network server, the Corresponding Source may be -on a different server (operated by you or a third party) that supports -equivalent copying facilities, provided you maintain clear directions -next to the object code saying where to find the Corresponding Source. -Regardless of what server hosts the Corresponding Source, you remain -obligated to ensure that it is available for as long as needed to -satisfy these requirements. - -@item -Convey the object code using peer-to-peer transmission, provided you -inform other peers where the object code and Corresponding Source of -the work are being offered to the general public at no charge under -subsection 6d. - -@end enumerate - -A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - -A ``User Product'' is either (1) a ``consumer product'', which means any -tangible personal property which is normally used for personal, -family, or household purposes, or (2) anything designed or sold for -incorporation into a dwelling. In determining whether a product is a -consumer product, doubtful cases shall be resolved in favor of -coverage. For a particular product received by a particular user, -``normally used'' refers to a typical or common use of that class of -product, regardless of the status of the particular user or of the way -in which the particular user actually uses, or expects or is expected -to use, the product. A product is a consumer product regardless of -whether the product has substantial commercial, industrial or -non-consumer uses, unless such uses represent the only significant -mode of use of the product. - -``Installation Information'' for a User Product means any methods, -procedures, authorization keys, or other information required to -install and execute modified versions of a covered work in that User -Product from a modified version of its Corresponding Source. The -information must suffice to ensure that the continued functioning of -the modified object code is in no case prevented or interfered with -solely because modification has been made. - -If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - -The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or -updates for a work that has been modified or installed by the -recipient, or for the User Product in which it has been modified or -installed. Access to a network may be denied when the modification -itself materially and adversely affects the operation of the network -or violates the rules and protocols for communication across the -network. - -Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - -@item Additional Terms. - -``Additional permissions'' are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders -of that material) supplement the terms of this License with terms: - -@enumerate a -@item -Disclaiming warranty or limiting liability differently from the terms -of sections 15 and 16 of this License; or - -@item -Requiring preservation of specified reasonable legal notices or author -attributions in that material or in the Appropriate Legal Notices -displayed by works containing it; or - -@item -Prohibiting misrepresentation of the origin of that material, or -requiring that modified versions of such material be marked in -reasonable ways as different from the original version; or - -@item -Limiting the use for publicity purposes of names of licensors or -authors of the material; or - -@item -Declining to grant rights under trademark law for use of some trade -names, trademarks, or service marks; or - -@item -Requiring indemnification of licensors and authors of that material by -anyone who conveys the material (or modified versions of it) with -contractual assumptions of liability to the recipient, for any -liability that these contractual assumptions directly impose on those -licensors and authors. -@end enumerate - -All other non-permissive additional terms are considered ``further -restrictions'' within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - -If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; the -above requirements apply either way. - -@item Termination. - -You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - -However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - -@item Acceptance Not Required for Having Copies. - -You are not required to accept this License in order to receive or run -a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - -@item Automatic Licensing of Downstream Recipients. - -Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - -An ``entity transaction'' is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - -@item Patents. - -A ``contributor'' is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's ``contributor version''. - -A contributor's ``essential patent claims'' are all patent claims owned -or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, ``control'' includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - -In the following three paragraphs, a ``patent license'' is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To ``grant'' such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - -If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. ``Knowingly relying'' means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - -A patent license is ``discriminatory'' if it does not include within the -scope of its coverage, prohibits the exercise of, or is conditioned on -the non-exercise of one or more of the rights that are specifically -granted under this License. You may not convey a covered work if you -are a party to an arrangement with a third party that is in the -business of distributing software, under which you make payment to the -third party based on the extent of your activity of conveying the -work, and under which the third party grants, to any of the parties -who would receive the covered work from you, a discriminatory patent -license (a) in connection with copies of the covered work conveyed by -you (or copies made from those copies), or (b) primarily for and in -connection with specific products or compilations that contain the -covered work, unless you entered into that arrangement, or that patent -license was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - -@item No Surrender of Others' Freedom. - -If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey -a covered work so as to satisfy simultaneously your obligations under -this License and any other pertinent obligations, then as a -consequence you may not convey it at all. For example, if you agree -to terms that obligate you to collect a royalty for further conveying -from those to whom you convey the Program, the only way you could -satisfy both those terms and this License would be to refrain entirely -from conveying the Program. - -@item Remote Network Interaction; Use with the GNU General Public License. - -Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users interacting -with it remotely through a computer network (if your version supports such -interaction) an opportunity to receive the Corresponding Source of your -version by providing access to the Corresponding Source from a network -server at no charge, through some standard or customary means of -facilitating copying of software. This Corresponding Source shall include -the Corresponding Source for any work covered by version 3 of the GNU -General Public License that is incorporated pursuant to the following -paragraph. - -Notwithstanding any other provision of this License, you have permission to -link or combine any covered work with a work licensed under version 3 of -the GNU General Public License into a single combined work, and to convey -the resulting work. The terms of this License will continue to apply to -the part which is the covered work, but the work with which it is combined -will remain governed by version 3 of the GNU General Public License. - -@item Revised Versions of this License. - -The Free Software Foundation may publish revised and/or new versions -of the GNU Affero General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies that a certain numbered version of the GNU Affero General Public -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that numbered version or -of any later version published by the Free Software Foundation. If -the Program does not specify a version number of the GNU Affero General -Public License, you may choose any version ever published by the Free -Software Foundation. - -If the Program specifies that a proxy can decide which future versions -of the GNU Affero General Public License can be used, that proxy's public -statement of acceptance of a version permanently authorizes you to -choose that version for the Program. - -Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - -@item Disclaimer of Warranty. - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR -CORRECTION. - -@item Limitation of Liability. - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR -CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT -NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR -LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM -TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER -PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -@item Interpretation of Sections 15 and 16. - -If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - -@end enumerate - -@heading END OF TERMS AND CONDITIONS - -@heading How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - -To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the ``copyright'' line and a pointer to where the full notice is found. - -@smallexample -@var{one line to give the program's name and a brief idea of what it does.} -Copyright (C) @var{year} @var{name of author} - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or (at -your option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see @url{http://www.gnu.org/licenses/}. -@end smallexample - -Also add information on how to contact you by electronic and paper mail. - -If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a ``Source'' link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - -You should also get your employer (if you work as a programmer) or school, -if any, to sign a ``copyright disclaimer'' for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -@url{http://www.gnu.org/licenses/}. diff --git a/doc/info/fdl-1.3.texinfo b/doc/info/fdl-1.3.texinfo deleted file mode 100644 index cb71f05..0000000 --- a/doc/info/fdl-1.3.texinfo +++ /dev/null @@ -1,505 +0,0 @@ -@c The GNU Free Documentation License. -@center Version 1.3, 3 November 2008 - -@c This file is intended to be included within another document, -@c hence no sectioning command or @node. - -@display -Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. -@uref{http://fsf.org/} - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document @dfn{free} in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The ``Document'', below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as ``you''. You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, La@TeX{} input -format, SGML or XML using a publicly available -DTD, and standard-conforming simple HTML, -PostScript or PDF designed for human modification. Examples -of transparent image formats include PNG, XCF and -JPG. Opaque formats include proprietary formats that can be -read and edited only by proprietary word processors, SGML or -XML for which the DTD and/or processing tools are -not generally available, and the machine-generated HTML, -PostScript or PDF produced by some word processors for -output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -The ``publisher'' means any person or entity that distributes copies -of the Document to the public. - -A section ``Entitled XYZ'' means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as ``Acknowledgements'', -``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' -of such a section when you modify the Document means that it remains a -section ``Entitled XYZ'' according to this definition. - -The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has fewer than five), -unless they release you from this requirement. - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section Entitled ``History'', Preserve its Title, and add -to it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section Entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve -the Title of the section, and preserve in the section all the -substance and tone of each of the contributor acknowledgements and/or -dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section Entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section to be Entitled ``Endorsements'' or -to conflict in title with any Invariant Section. - -@item -Preserve any Warranty Disclaimers. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections Entitled ``History'' -in the various original documents, forming one section Entitled -``History''; likewise combine any sections Entitled ``Acknowledgements'', -and any sections Entitled ``Dedications''. You must delete all -sections Entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an ``aggregate'' if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation's users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. - -If a section in the Document is Entitled ``Acknowledgements'', -``Dedications'', or ``History'', the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, or distribute it is void, and -will automatically terminate your rights under this License. - -However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, receipt of a copy of some or all of the same material does -not give you any rights to use it. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. If the Document -specifies that a proxy can decide which future versions of this -License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the -Document. - -@item -RELICENSING - -``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any -World Wide Web server that publishes copyrightable works and also -provides prominent facilities for anybody to edit those works. A -public wiki that anybody can edit is an example of such a server. A -``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the -site means any set of copyrightable works thus published on the MMC -site. - -``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 -license published by Creative Commons Corporation, a not-for-profit -corporation with a principal place of business in San Francisco, -California, as well as future copyleft versions of that license -published by that same organization. - -``Incorporate'' means to publish or republish a Document, in whole or -in part, as part of another Document. - -An MMC is ``eligible for relicensing'' if it is licensed under this -License, and if all works that were first published under this License -somewhere other than this MMC, and subsequently incorporated in whole -or in part into the MMC, (1) had no cover texts or invariant sections, -and (2) were thus incorporated prior to November 1, 2008. - -The operator of an MMC Site may republish an MMC contained in the site -under CC-BY-SA on the same site at any time before August 1, 2009, -provided the MMC is eligible for relicensing. - -@end enumerate - -@page -@heading ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.3 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -@end group -@end smallexample - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the ``with@dots{}Texts.''@: line with this: - -@smallexample -@group - with the Invariant Sections being @var{list their titles}, with - the Front-Cover Texts being @var{list}, and with the Back-Cover Texts - being @var{list}. -@end group -@end smallexample - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: diff --git a/doc/info/libkeccak.texinfo b/doc/info/libkeccak.texinfo index 3ac6a53..68bf147 100644 --- a/doc/info/libkeccak.texinfo +++ b/doc/info/libkeccak.texinfo @@ -7,13 +7,9 @@ Copyright @copyright{} 2015, 2017 @w{Mattias Andrée @e{maandree@@kth.se}} @quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version@tie{}1.3 -or any later version published by the Free Software Foundation; with the -Invariant Sections being the ``GNU Affero General Public License'', the -``GNU Free Documentation License'', with no Front-Cover Texts, and with -no Back-Cover Texts. A copy of the license is included in the section -entitled ``GNU Free Documentation License''. +Permission to use, copy, modify, and/or distribute this document for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. @end quotation @c -------------------------------------------------------------------------------- @end copying @@ -77,9 +73,6 @@ with support for bit-oriented data. * Message authentication:: Functions used for message authentication codes. * Examples:: Examples of how to use libkeccak. -* GNU Affero General Public License:: Copying and sharing libkeccak. -* GNU Free Documentation License:: Copying and sharing this manual. - * Concept index:: Index of concepts. * Data type index:: Index of data types. * Function index:: Index of functions. @@ -125,21 +118,6 @@ doing so is unnecessary because the key can securely be prepended to the message when using Keccak to produce a message authentication code.}. This library implements the Keccak algorithm using a lanewise implementation. -libkeccak must compelling feature however is that it is -licensed under the strongest free software license: -GNU Affero General Public License version@tie{}3 -(see @ref{GNU Affero General Public License},) which -gives the user the four essential freedoms: -@itemize @bullet{} -@item -The freedom to run the program as you wish, for any purpose (freedom 0). -@item -The freedom to study how the program works, and change it so it does your computing as you wish (freedom 1). -@item -The freedom to redistribute copies so you can help your neighbor (freedom 2). -@item -The freedom to distribute copies of your modified versions to others (freedom 3). -@end itemize @cpindex Limitations This implementation is limited to state sizes up to, @@ -1075,14 +1053,6 @@ libkeccak_state_destroy(&state); -@node GNU Affero General Public License -@appendix GNU Affero General Public License -@include agpl-3.0.texinfo - -@node GNU Free Documentation License -@appendix GNU Free Documentation License -@include fdl-1.3.texinfo - @node Concept index @unnumbered Concept index @printindex cp diff --git a/src/benchmark-flags b/src/benchmark-flags index 0143f40..1168ec0 100755 --- a/src/benchmark-flags +++ b/src/benchmark-flags @@ -1,32 +1,16 @@ #!/bin/sh -# libkeccak – Keccak-family hashing library -# -# Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) -# -# This library is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this library. If not, see <http://www.gnu.org/licenses/>. +# See LICENSE file for copyright and license details. set -e export LD_LIBRARY_PATH=bin -if [ "${TRIES}" = "" ]; then - TRIES=10 +if test "${TRIES}" = ""; then + TRIES=10 fi # List all flags that affect the object files -list_test_flags () -{ - cat <<EOF +list_test_flags() { + cat <<EOF -fdata-sections -fcrossjumping -fexpensive-optimizations -ffunction-sections -fkeep-inline-functions -fomit-frame-pointer -freorder-blocks-and-partition -ftree-ter -falign-functions=0 -fmerge-all-constants -fmerge-constants @@ -41,47 +25,47 @@ pass=1 exec 4>.benchmark.so.far while true; do - exec 3>.benchmarks - - for _try in $(seq ${TRIES}); do - for test_flag in "" ${test_flags}; do - flags="${test_flag} ${base_flags}" - make -B all COPTIMISE="${flags}" CPPFLAGS="${cppflags} $*" - make check - if [ "${test_flag}" = "" ]; then - test_flag=zzz - fi - echo "$(bin/benchmark || echo error) ${test_flag}" >&3 + exec 3>.benchmarks + + for _try in $(seq ${TRIES}); do + for test_flag in "" ${test_flags}; do + flags="${test_flag} ${base_flags}" + make -B all COPTIMISE="${flags}" CPPFLAGS="${cppflags} $*" + make check + if test "${test_flag}" = ""; then + test_flag=zzz + fi + echo "$(bin/benchmark || echo error) ${test_flag}" >&3 + done done - done - - exec 3<&- - - ! grep ^error .benchmarks >/dev/null 2>/dev/null - - good_flag="$(median < .benchmarks | sort -n | cut -d ' ' -f 2 | sed 1q)" - if [ "${good_flag}" = zzz ] || [ $pass = 2 ]; then - if [ $pass = 1 ]; then - pass=2 - base_flags="$(echo "${base_flags}" | sed -e 's/ -O0//')" - test_flags="-O0 -O1 -O2 -O3 -Ofast -Os" + + exec 3<&- + + ! grep ^error .benchmarks >/dev/null 2>/dev/null + + good_flag="$(median < .benchmarks | sort -n | cut -d ' ' -f 2 | sed 1q)" + if test "${good_flag}" = zzz || test $pass = 2; then + if test $pass = 1; then + pass=2 + base_flags="$(echo "${base_flags}" | sed -e 's/ -O0//')" + test_flags="-O0 -O1 -O2 -O3 -Ofast -Os" + else + if ! test "${good_flag}" = zzz; then + base_flags="${base_flags} ${good_flag}" + echo "${good_flag}" >&4 + fi + echo + echo + echo "Good flags:" + echo "${base_flags}" + exec 4<&- + exit 0 + fi else - if [ ! "${good_flag}" = zzz ]; then - base_flags="${base_flags} ${good_flag}" echo "${good_flag}" >&4 - fi - echo - echo - echo "Good flags:" - echo "${base_flags}" - exec 4<&- - exit 0 + base_flags="${base_flags} ${good_flag}" + test_flags="$(echo "${test_flags}" | sed -e "s/ ${good_flag} / /")" fi - else - echo "${good_flag}" >&4 - base_flags="${base_flags} ${good_flag}" - test_flags="$(echo "${test_flags}" | sed -e "s/ ${good_flag} / /")" - fi done # None of these GCC flags affect the object files. diff --git a/src/benchmark.c b/src/benchmark.c index 115fcc5..1ce7da9 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -1,28 +1,11 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include <libkeccak.h> +#include <fcntl.h> #include <stdio.h> #include <string.h> -#include <fcntl.h> -#include <unistd.h> #include <time.h> +#include <unistd.h> #ifndef MESSAGE_FILE @@ -66,96 +49,91 @@ * * @return Zero on success, 1 on error */ -int main(void) +int +main(void) { - char message[MESSAGE_LEN]; - libkeccak_spec_t spec; - libkeccak_state_t state; - char hashsum[OUTPUT / 8]; + char message[MESSAGE_LEN]; + libkeccak_spec_t spec; + libkeccak_state_t state; + char hashsum[OUTPUT / 8]; #ifndef IGNORE_BEHEXING - char hexsum[OUTPUT / 8 * 2 + 1]; + char hexsum[OUTPUT / 8 * 2 + 1]; #endif - struct timespec start, end; - long i, r; - - /* Fill message with content from the file. */ - { - int fd; - ssize_t got; - size_t ptr; - if (fd = open(MESSAGE_FILE, O_RDONLY), fd < 0) - return perror("open"), 1; - for (ptr = 0; ptr < MESSAGE_LEN; ptr += (size_t)got) - if (got = read(fd, message, MESSAGE_LEN - ptr), got <= 0) - return perror("read"), close(fd), 1; - close(fd); - } - - /* Initialise state. */ - spec.bitrate = BITRATE; - spec.capacity = CAPACITY; - spec.output = OUTPUT; - if (libkeccak_state_initialise(&state, &spec)) - return perror("libkeccak_state_initialise"), 1; - - /* Get start-time. */ - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start) < 0) - return perror("clock_gettime"), 1; - - /* Run benchmarking loop. */ - for (r = 0; r < RERUNS; r++) - { - /* Updates. */ + struct timespec start, end; + long i, r; + + /* Fill message with content from the file. */ + int fd; + ssize_t got; + size_t ptr; + if (fd = open(MESSAGE_FILE, O_RDONLY), fd < 0) + return perror("open"), 1; + for (ptr = 0; ptr < MESSAGE_LEN; ptr += (size_t)got) + if (got = read(fd, message, MESSAGE_LEN - ptr), got <= 0) + return perror("read"), close(fd), 1; + close(fd); + + /* Initialise state. */ + spec.bitrate = BITRATE; + spec.capacity = CAPACITY; + spec.output = OUTPUT; + if (libkeccak_state_initialise(&state, &spec)) + return perror("libkeccak_state_initialise"), 1; + + /* Get start-time. */ + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start) < 0) + return perror("clock_gettime"), 1; + + /* Run benchmarking loop. */ + for (r = 0; r < RERUNS; r++) { + /* Updates. */ #if UPDATE_RUNS > 0 - for (i = 0; i < UPDATE_RUNS; i++) - if (libkeccak_fast_update(&state, message, MESSAGE_LEN) < 0) - return perror("libkeccak_update"), 1; + for (i = 0; i < UPDATE_RUNS; i++) + if (libkeccak_fast_update(&state, message, MESSAGE_LEN) < 0) + return perror("libkeccak_update"), 1; #endif - - /* Digest. */ - if (libkeccak_fast_digest(&state, NULL, 0, 0, NULL, hashsum) < 0) - return perror("libkeccak_digest"), 1; + + /* Digest. */ + if (libkeccak_fast_digest(&state, NULL, 0, 0, NULL, hashsum) < 0) + return perror("libkeccak_digest"), 1; #ifndef IGNORE_BEHEXING - libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); + libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); #endif - - /* Fast squeezes. */ + + /* Fast squeezes. */ #if FAST_SQUEEZE_RUNS > 0 - libkeccak_fast_squeeze(&state, FAST_SQUEEZE_RUNS); + libkeccak_fast_squeeze(&state, FAST_SQUEEZE_RUNS); #endif - - /* Slow squeezes. */ + + /* Slow squeezes. */ #if SLOW_SQUEEZE_RUNS > 0 - for (i = 0; i < SLOW_SQUEEZE_RUNS; i++) - { - libkeccak_squeeze(&state, hashsum); + for (i = 0; i < SLOW_SQUEEZE_RUNS; i++) { + libkeccak_squeeze(&state, hashsum); # ifndef IGNORE_BEHEXING - libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); + libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); # endif - } + } #endif - } - - /* Get end-time. */ - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) - return perror("clock_gettime"), -1; - - /* Print execution-time. */ - end.tv_sec -= start.tv_sec; - end.tv_nsec -= start.tv_nsec; - if (end.tv_nsec < 0) - { - end.tv_sec--; - end.tv_nsec += 1000000000L; - } - printf("%03li%09li\n", (long)(end.tv_sec), end.tv_nsec); - - /* Release resources and exit. */ - libkeccak_state_fast_destroy(&state); - return 0; - + } + + /* Get end-time. */ + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) + return perror("clock_gettime"), -1; + + /* Print execution-time. */ + end.tv_sec -= start.tv_sec; + end.tv_nsec -= start.tv_nsec; + if (end.tv_nsec < 0) { + end.tv_sec--; + end.tv_nsec += 1000000000L; + } + printf("%03li%09li\n", (long)(end.tv_sec), end.tv_nsec); + + /* Release resources and exit. */ + libkeccak_state_fast_destroy(&state); + return 0; + #if (UPDATE_RUNS == 0) && (SLOW_SQUEEZE_RUNS == 0) - (void) i; + (void) i; #endif } - diff --git a/src/libkeccak.h b/src/libkeccak.h index c53bcd1..7c71801 100644 --- a/src/libkeccak.h +++ b/src/libkeccak.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_H -#define LIBKECCAK_H 1 - +#define LIBKECCAK_H 1 #include "libkeccak/spec.h" #include "libkeccak/generalised-spec.h" @@ -28,6 +10,4 @@ #include "libkeccak/files.h" #include "libkeccak/mac/hmac.h" - #endif - diff --git a/src/libkeccak/digest.c b/src/libkeccak/digest.c index 6168f33..5f7a32c 100644 --- a/src/libkeccak/digest.c +++ b/src/libkeccak/digest.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "digest.h" #include "state.h" @@ -25,27 +8,27 @@ /** * X-macro-enabled listing of all intergers in [0, 4] */ -#define LIST_5 X(0) X(1) X(2) X(3) X(4) +#define LIST_5 X(0) X(1) X(2) X(3) X(4) /** * X-macro-enabled listing of all intergers in [0, 7] */ -#define LIST_8 LIST_5 X(5) X(6) X(7) +#define LIST_8 LIST_5 X(5) X(6) X(7) /** * X-macro-enabled listing of all intergers in [0, 23] */ -#define LIST_24 LIST_8 X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) \ - X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) +#define LIST_24 LIST_8 X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15)\ + X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) /** * X-macro-enabled listing of all intergers in [0, 24] */ -#define LIST_25 LIST_24 X(24) +#define LIST_25 LIST_24 X(24) -#define X(N) (N % 5) * 5 + N / 5, +#define X(N) (N % 5) * 5 + N / 5, /** * The order the lanes should be read when absorbing or squeezing, * it transposes the lanes in the sponge @@ -58,15 +41,14 @@ static const long LANE_TRANSPOSE_MAP[] = { LIST_25 }; /** * Keccak-f round constants */ -static const uint_fast64_t RC[] = - { - 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL, 0x8000000080008000ULL, - 0x000000000000808BULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, - 0x000000000000008AULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL, - 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL, 0x8000000000008003ULL, - 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800AULL, 0x800000008000000AULL, - 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL - }; +static const uint_fast64_t RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL, 0x8000000080008000ULL, + 0x000000000000808BULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008AULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL, + 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800AULL, 0x800000008000000AULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL +}; /** @@ -78,7 +60,7 @@ static const uint_fast64_t RC[] = * @param wmod:int_fast64_t `state->wmod` * @return :int_fast64_t The value rotated */ -#define rotate(x, n, w, wmod) ((((x) >> ((w) - ((n) % (w)))) | ((x) << ((n) % (w)))) & (wmod)) +#define rotate(x, n, w, wmod) ((((x) >> ((w) - ((n) % (w)))) | ((x) << ((n) % (w)))) & (wmod)) /** @@ -88,7 +70,7 @@ static const uint_fast64_t RC[] = * @param n:long Rotation steps, may not be zero * @return :int_fast64_t The value rotated */ -#define rotate64(x, n) ((int_fast64_t)(((uint64_t)(x) >> (64L - (n))) | ((uint64_t)(x) << (n)))) +#define rotate64(x, n) ((int_fast64_t)(((uint64_t)(x) >> (64L - (n))) | ((uint64_t)(x) << (n)))) /** @@ -97,44 +79,44 @@ static const uint_fast64_t RC[] = * @param state The hashing state * @param rc The round contant for this round */ -static __attribute__((nonnull, nothrow, hot)) -void libkeccak_f_round(register libkeccak_state_t* restrict state, register int_fast64_t rc) +static __attribute__((nonnull, nothrow, hot)) void +libkeccak_f_round(register libkeccak_state_t *restrict state, register int_fast64_t rc) { - int_fast64_t* restrict A = state->S; - int_fast64_t B[25]; - int_fast64_t C[5]; - int_fast64_t da, db, dc, dd, de; - int_fast64_t wmod = state->wmod; - long w = state->w; - - /* θ step (step 1 of 3). */ -#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; - LIST_5 + int_fast64_t *restrict A = state->S; + int_fast64_t B[25]; + int_fast64_t C[5]; + int_fast64_t da, db, dc, dd, de; + int_fast64_t wmod = state->wmod; + long w = state->w; + + /* θ step (step 1 of 3). */ +#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; + LIST_5; #undef X - - /* θ step (step 2 of 3). */ - da = C[4] ^ rotate(C[1], 1, w, wmod); - dd = C[2] ^ rotate(C[4], 1, w, wmod); - db = C[0] ^ rotate(C[2], 1, w, wmod); - de = C[3] ^ rotate(C[0], 1, w, wmod); - dc = C[1] ^ rotate(C[3], 1, w, wmod); - - /* ρ and π steps, with last two part of θ. */ -#define X(bi, ai, dv, r) B[bi] = rotate(A[ai] ^ dv, r, w, wmod) - B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); - X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); - X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); - X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); - X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); + + /* θ step (step 2 of 3). */ + da = C[4] ^ rotate(C[1], 1, w, wmod); + dd = C[2] ^ rotate(C[4], 1, w, wmod); + db = C[0] ^ rotate(C[2], 1, w, wmod); + de = C[3] ^ rotate(C[0], 1, w, wmod); + dc = C[1] ^ rotate(C[3], 1, w, wmod); + + /* ρ and π steps, with last two part of θ. */ +#define X(bi, ai, dv, r) B[bi] = rotate(A[ai] ^ dv, r, w, wmod) + B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); + X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); + X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); + X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); + X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); #undef X - - /* ξ step. */ -#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); - LIST_25 + + /* ξ step. */ +#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); + LIST_25; #undef X - - /* ι step. */ - A[0] ^= rc; + + /* ι step. */ + A[0] ^= rc; } @@ -144,42 +126,42 @@ void libkeccak_f_round(register libkeccak_state_t* restrict state, register int_ * @param state The hashing state * @param rc The round contant for this round */ -static __attribute__((nonnull, nothrow, hot)) -void libkeccak_f_round64(register libkeccak_state_t* restrict state, register int_fast64_t rc) +static __attribute__((nonnull, nothrow, hot)) void +libkeccak_f_round64(register libkeccak_state_t *restrict state, register int_fast64_t rc) { - int_fast64_t* restrict A = state->S; - int_fast64_t B[25]; - int_fast64_t C[5]; - int_fast64_t da, db, dc, dd, de; - - /* θ step (step 1 of 3). */ -#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; - LIST_5 + int_fast64_t *restrict A = state->S; + int_fast64_t B[25]; + int_fast64_t C[5]; + int_fast64_t da, db, dc, dd, de; + + /* θ step (step 1 of 3). */ +#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; + LIST_5; #undef X - - /* θ step (step 2 of 3). */ - da = C[4] ^ rotate64(C[1], 1); - dd = C[2] ^ rotate64(C[4], 1); - db = C[0] ^ rotate64(C[2], 1); - de = C[3] ^ rotate64(C[0], 1); - dc = C[1] ^ rotate64(C[3], 1); - - /* ρ and π steps, with last two part of θ. */ -#define X(bi, ai, dv, r) B[bi] = rotate64(A[ai] ^ dv, r) - B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); - X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); - X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); - X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); - X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); + + /* θ step (step 2 of 3). */ + da = C[4] ^ rotate64(C[1], 1); + dd = C[2] ^ rotate64(C[4], 1); + db = C[0] ^ rotate64(C[2], 1); + de = C[3] ^ rotate64(C[0], 1); + dc = C[1] ^ rotate64(C[3], 1); + + /* ρ and π steps, with last two part of θ. */ +#define X(bi, ai, dv, r) B[bi] = rotate64(A[ai] ^ dv, r) + B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); + X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); + X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); + X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); + X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); #undef X - - /* ξ step. */ -#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); - LIST_25 + + /* ξ step. */ +#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); + LIST_25; #undef X - - /* ι step. */ - A[0] ^= rc; + + /* ι step. */ + A[0] ^= rc; } @@ -188,18 +170,19 @@ void libkeccak_f_round64(register libkeccak_state_t* restrict state, register in * * @param state The hashing state */ -static inline __attribute__((nonnull, nothrow, gnu_inline)) -void libkeccak_f(register libkeccak_state_t* restrict state) +static inline __attribute__((nonnull, nothrow, gnu_inline)) void +libkeccak_f(register libkeccak_state_t *restrict state) { - register long i = 0; - register long nr = state->nr; - register long wmod = state->wmod; - if (nr == 24) - for (; i < nr; i++) - libkeccak_f_round64(state, (int_fast64_t)(RC[i])); - else - for (; i < nr; i++) - libkeccak_f_round(state, (int_fast64_t)(RC[i] & wmod)); + register long i = 0; + register long nr = state->nr; + register long wmod = state->wmod; + if (nr == 24) { + for (; i < nr; i++) + libkeccak_f_round64(state, (int_fast64_t)(RC[i])); + } else { + for (; i < nr; i++) + libkeccak_f_round(state, (int_fast64_t)(RC[i] & wmod)); + } } @@ -213,19 +196,18 @@ void libkeccak_f(register libkeccak_state_t* restrict state) * @param off The offset in the message * @return The lane */ -static inline __attribute__((nonnull, nothrow, pure, warn_unused_result, gnu_inline)) -int_fast64_t libkeccak_to_lane(register const char* restrict message, register size_t msglen, - register long rr, register long ww, size_t off) +static inline __attribute__((nonnull, nothrow, pure, warn_unused_result, gnu_inline)) int_fast64_t +libkeccak_to_lane(register const char *restrict message, register size_t msglen, + register long rr, register long ww, size_t off) { - register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); - int_fast64_t rc = 0; - message += off; - while (ww--) - { - rc <<= 8; - rc |= __builtin_expect(ww < n, 1) ? (int_fast64_t)(unsigned char)(message[ww]) : 0L; - } - return rc; + register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); + int_fast64_t rc = 0; + message += off; + while (ww--) { + rc <<= 8; + rc |= __builtin_expect(ww < n, 1) ? (int_fast64_t)(unsigned char)(message[ww]) : 0L; + } + return rc; } @@ -238,18 +220,18 @@ int_fast64_t libkeccak_to_lane(register const char* restrict message, register s * @param off The offset in the message * @return The lane */ -static inline __attribute__((nonnull, nothrow, pure, hot, warn_unused_result, gnu_inline)) -int_fast64_t libkeccak_to_lane64(register const char* restrict message, register size_t msglen, - register long rr, size_t off) +static inline __attribute__((nonnull, nothrow, pure, hot, warn_unused_result, gnu_inline)) int_fast64_t +libkeccak_to_lane64(register const char* restrict message, register size_t msglen, + register long rr, size_t off) { - register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); - int_fast64_t rc = 0; - message += off; -#define X(N) if (__builtin_expect(N < n, 1)) rc |= (int_fast64_t)(unsigned char)(message[N]) << (N * 8); \ - else return rc; - LIST_8 + register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); + int_fast64_t rc = 0; + message += off; +#define X(N) if (__builtin_expect(N < n, 1)) rc |= (int_fast64_t)(unsigned char)(message[N]) << (N * 8);\ + else return rc; + LIST_8; #undef X - return rc; + return rc; } @@ -260,30 +242,27 @@ int_fast64_t libkeccak_to_lane64(register const char* restrict message, register * `state->M` should have `state->r / 8` bytes left over at the end * @param bits The number of bits in the end of the message that does not make a whole byte */ -static inline __attribute__((nonnull, nothrow, gnu_inline)) -void libkeccak_pad10star1(register libkeccak_state_t* restrict state, register size_t bits) +static inline __attribute__((nonnull, nothrow, gnu_inline)) void +libkeccak_pad10star1(register libkeccak_state_t *restrict state, register size_t bits) { - register size_t r = (size_t)(state->r); - register size_t nrf = state->mptr - !!bits; - register size_t len = (nrf << 3) | bits; - register size_t ll = len % r; - register char b = (char)(bits ? (state->M[nrf] | (1 << bits)) : 1); - - if ((r - 8 <= ll) && (ll <= r - 2)) - { - state->M[nrf] = (char)(b ^ 0x80); - state->mptr = nrf + 1; - } - else - { - len = ++nrf << 3; - len = (len - (len % r) + (r - 8)) >> 3; - state->mptr = len + 1; - - state->M[nrf - 1] = b; - __builtin_memset(state->M + nrf, 0, (len - nrf) * sizeof(char)); - state->M[len] = (char)0x80; - } + register size_t r = (size_t)(state->r); + register size_t nrf = state->mptr - !!bits; + register size_t len = (nrf << 3) | bits; + register size_t ll = len % r; + register char b = (char)(bits ? (state->M[nrf] | (1 << bits)) : 1); + + if (r - 8 <= ll && ll <= r - 2) { + state->M[nrf] = (char)(b ^ 0x80); + state->mptr = nrf + 1; + } else { + len = ++nrf << 3; + len = (len - (len % r) + (r - 8)) >> 3; + state->mptr = len + 1; + + state->M[nrf - 1] = b; + __builtin_memset(state->M + nrf, 0, (len - nrf) * sizeof(char)); + state->M[len] = (char)0x80; + } } @@ -293,33 +272,32 @@ void libkeccak_pad10star1(register libkeccak_state_t* restrict state, register s * @param state The hashing state * @param len The number of bytes from `state->M` to absorb */ -static __attribute__((nonnull, nothrow)) -void libkeccak_absorption_phase(register libkeccak_state_t* restrict state, register size_t len) +static __attribute__((nonnull, nothrow)) void +libkeccak_absorption_phase(register libkeccak_state_t *restrict state, register size_t len) { - register long rr = state->r >> 3; - register long ww = state->w >> 3; - register long n = (long)len / rr; - register const char* restrict message = state->M; - if (__builtin_expect(ww >= 8, 1)) /* ww > 8 is impossible, it is just for optimisation possibilities. */ - while (n--) - { -#define X(N) state->S[N] ^= libkeccak_to_lane64(message, len, rr, (size_t)(LANE_TRANSPOSE_MAP[N] * 8)); - LIST_25 + register long rr = state->r >> 3; + register long ww = state->w >> 3; + register long n = (long)len / rr; + register const char* restrict message = state->M; + if (__builtin_expect(ww >= 8, 1)) { /* ww > 8 is impossible, it is just for optimisation possibilities. */ + while (n--) { +#define X(N) state->S[N] ^= libkeccak_to_lane64(message, len, rr, (size_t)(LANE_TRANSPOSE_MAP[N] * 8)); + LIST_25; #undef X - libkeccak_f(state); - message += (size_t)rr; - len -= (size_t)rr; - } - else - while (n--) - { -#define X(N) state->S[N] ^= libkeccak_to_lane(message, len, rr, ww, (size_t)(LANE_TRANSPOSE_MAP[N] * ww)); - LIST_25 + libkeccak_f(state); + message += (size_t)rr; + len -= (size_t)rr; + } + } else { + while (n--) { +#define X(N) state->S[N] ^= libkeccak_to_lane(message, len, rr, ww, (size_t)(LANE_TRANSPOSE_MAP[N] * ww)); + LIST_25; #undef X - libkeccak_f(state); - message += (size_t)rr; - len -= (size_t)rr; - } + libkeccak_f(state); + message += (size_t)rr; + len -= (size_t)rr; + } + } } @@ -332,28 +310,26 @@ void libkeccak_absorption_phase(register libkeccak_state_t* restrict state, regi * @param ww The word size in bytes * @param hashsum Output parameter for the hashsum */ -static __attribute__((nonnull, nothrow, hot)) -void libkeccak_squeezing_phase(register libkeccak_state_t* restrict state, long rr, - long nn, long ww, register char* restrict hashsum) +static __attribute__((nonnull, nothrow, hot)) void +libkeccak_squeezing_phase(register libkeccak_state_t *restrict state, long rr, + long nn, long ww, register char *restrict hashsum) { - register int_fast64_t v; - register long ni = rr / ww; - auto long olen = state->n; - auto long i, j = 0; - register long k; - while (olen > 0) - { - for (i = 0; (i < ni) && (j < nn); i++) - { - v = state->S[LANE_TRANSPOSE_MAP[i]]; - for (k = 0; (k++ < ww) && (j++ < nn); v >>= 8) - *hashsum++ = (char)v; + register int_fast64_t v; + register long ni = rr / ww; + auto long olen = state->n; + auto long i, j = 0; + register long k; + while (olen > 0) { + for (i = 0; i < ni && j < nn; i++) { + v = state->S[LANE_TRANSPOSE_MAP[i]]; + for (k = 0; k++ < ww && j++ < nn; v >>= 8) + *hashsum++ = (char)v; + } + if (olen -= state->r, olen > 0) + libkeccak_f(state); } - if (olen -= state->r, olen > 0) - libkeccak_f(state); - } - if (state->n & 7) - hashsum[-1] &= (char)((1 << (state->n & 7)) - 1); + if (state->n & 7) + hashsum[-1] &= (char)((1 << (state->n & 7)) - 1); } @@ -366,30 +342,30 @@ void libkeccak_squeezing_phase(register libkeccak_state_t* restrict state, long * @param msglen The length of the partial message * @return Zero on success, -1 on error */ -int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_fast_update(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen) { - size_t len; - auto char* restrict new; - - if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) - { - state->mlen += msglen; - new = realloc(state->M, state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= msglen, -1; - state->M = new; - } - - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - len = state->mptr; - len -= state->mptr % (size_t)((state->r * state->b) >> 3); - state->mptr -= len; - - libkeccak_absorption_phase(state, len); - __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); - - return 0; + size_t len; + auto char *restrict new; + + if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) { + state->mlen += msglen; + new = realloc(state->M, state->mlen * sizeof(char)); + if (!new) + return state->mlen -= msglen, -1; + state->M = new; + } + + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + len = state->mptr; + len -= state->mptr % (size_t)((state->r * state->b) >> 3); + state->mptr -= len; + + libkeccak_absorption_phase(state, len); + __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); + + return 0; } @@ -402,32 +378,32 @@ int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restric * @param msglen The length of the partial message * @return Zero on success, -1 on error */ -int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_update(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen) { - size_t len; - auto char* restrict new; - - if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) - { - state->mlen += msglen; - new = malloc(state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= msglen, -1; - libkeccak_state_wipe_message(state); - free(state->M); - state->M = new; - } - - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - len = state->mptr; - len -= state->mptr % (size_t)((state->r * state->b) >> 3); - state->mptr -= len; - - libkeccak_absorption_phase(state, len); - __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); - - return 0; + size_t len; + auto char *restrict new; + + if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) { + state->mlen += msglen; + new = malloc(state->mlen * sizeof(char)); + if (new == NULL) + return state->mlen -= msglen, -1; + libkeccak_state_wipe_message(state); + free(state->M); + state->M = new; + } + + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + len = state->mptr; + len -= state->mptr % (size_t)((state->r * state->b) >> 3); + state->mptr -= len; + + libkeccak_absorption_phase(state, len); + __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); + + return 0; } @@ -443,60 +419,59 @@ int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_fast_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - auto char* restrict new; - register long rr = state->r >> 3; - auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; - register size_t ext; - register long i; - - if (msg == NULL) - msglen = bits = 0; - else - msglen += bits >> 3, bits &= 7; - - ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; - if (__builtin_expect(state->mptr + ext > state->mlen, 0)) - { - state->mlen += ext; - new = realloc(state->M, state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= ext, -1; - state->M = new; - } - - if (msglen) - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - - if (bits) - state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); - if (__builtin_expect(!!suffix_len, 1)) - { - if (bits == 0) - state->M[state->mptr] = 0; - while (suffix_len--) - { - state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); - if (bits == 8) - bits = 0, state->M[++(state->mptr)] = 0; + auto char *restrict new; + register long rr = state->r >> 3; + auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; + register size_t ext; + register long i; + + if (msg == NULL) + msglen = bits = 0; + else + msglen += bits >> 3, bits &= 7; + + ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; + if (__builtin_expect(state->mptr + ext > state->mlen, 0)) { + state->mlen += ext; + new = realloc(state->M, state->mlen * sizeof(char)); + if (!new) + return state->mlen -= ext, -1; + state->M = new; + } + + if (msglen) + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + + if (bits) + state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); + if (__builtin_expect(!!suffix_len, 1)) { + if (bits == 0) + state->M[state->mptr] = 0; + while (suffix_len--) { + state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); + if (bits == 8) + bits = 0, state->M[++(state->mptr)] = 0; + } + } + if (bits) + state->mptr++; + + libkeccak_pad10star1(state, bits); + libkeccak_absorption_phase(state, state->mptr); + + if (hashsum) { + libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); + } else { + for (i = (state->n - 1) / state->r; i--;) + libkeccak_f(state); } - } - if (bits) - state->mptr++; - - libkeccak_pad10star1(state, bits); - libkeccak_absorption_phase(state, state->mptr); - - if (hashsum != NULL) - libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); - else - for (i = (state->n - 1) / state->r; i--;) - libkeccak_f(state); - - return 0; + + return 0; } @@ -512,62 +487,61 @@ int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restric * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - auto char* restrict new; - register long rr = state->r >> 3; - auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; - register size_t ext; - register long i; - - if (msg == NULL) - msglen = bits = 0; - else - msglen += bits >> 3, bits &= 7; - - ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; - if (__builtin_expect(state->mptr + ext > state->mlen, 0)) - { - state->mlen += ext; - new = malloc(state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= ext, -1; - libkeccak_state_wipe_message(state); - free(state->M); - state->M = new; - } - - if (msglen) - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - - if (bits) - state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); - if (__builtin_expect(!!suffix_len, 1)) - { - if (bits == 0) - state->M[state->mptr] = 0; - while (suffix_len--) - { - state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); - if (bits == 8) - bits = 0, state->M[++(state->mptr)] = 0; + auto char *restrict new; + register long rr = state->r >> 3; + auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; + register size_t ext; + register long i; + + if (msg == NULL) + msglen = bits = 0; + else + msglen += bits >> 3, bits &= 7; + + ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; + if (__builtin_expect(state->mptr + ext > state->mlen, 0)) { + state->mlen += ext; + new = malloc(state->mlen * sizeof(char)); + if (!new) + return state->mlen -= ext, -1; + libkeccak_state_wipe_message(state); + free(state->M); + state->M = new; + } + + if (msglen) + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + + if (bits) + state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); + if (__builtin_expect(!!suffix_len, 1)) { + if (bits == 0) + state->M[state->mptr] = 0; + while (suffix_len--) { + state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); + if (bits == 8) + bits = 0, state->M[++(state->mptr)] = 0; + } + } + if (bits) + state->mptr++; + + libkeccak_pad10star1(state, bits); + libkeccak_absorption_phase(state, state->mptr); + + if (hashsum) { + libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); + } else { + for (i = (state->n - 1) / state->r; i--;) + libkeccak_f(state); } - } - if (bits) - state->mptr++; - - libkeccak_pad10star1(state, bits); - libkeccak_absorption_phase(state, state->mptr); - - if (hashsum != NULL) - libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); - else - for (i = (state->n - 1) / state->r; i--;) - libkeccak_f(state); - - return 0; + + return 0; } @@ -577,10 +551,11 @@ int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg * @param state The hashing state * @param times The number of rounds */ -void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, register long times) +void +libkeccak_simple_squeeze(register libkeccak_state_t *restrict state, register long times) { - while (times--) - libkeccak_f(state); + while (times--) + libkeccak_f(state); } @@ -590,11 +565,12 @@ void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, regist * @param state The hashing state * @param times The number of digests */ -void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register long times) +void +libkeccak_fast_squeeze(register libkeccak_state_t *restrict state, register long times) { - times *= (state->n - 1) / state->r + 1; - while (times--) - libkeccak_f(state); + times *= (state->n - 1) / state->r + 1; + while (times--) + libkeccak_f(state); } @@ -604,9 +580,9 @@ void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register * @param state The hashing state * @param hashsum Output parameter for the hashsum */ -void libkeccak_squeeze(register libkeccak_state_t* restrict state, register char* restrict hashsum) +void +libkeccak_squeeze(register libkeccak_state_t *restrict state, register char* restrict hashsum) { - libkeccak_f(state); - libkeccak_squeezing_phase(state, state->r >> 3, (state->n + 7) >> 3, state->w >> 3, hashsum); + libkeccak_f(state); + libkeccak_squeezing_phase(state, state->r >> 3, (state->n + 7) >> 3, state->w >> 3, hashsum); } - diff --git a/src/libkeccak/digest.h b/src/libkeccak/digest.h index 2dadd70..832f0c0 100644 --- a/src/libkeccak/digest.h +++ b/src/libkeccak/digest.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_DIGEST_H -#define LIBKECCAK_DIGEST_H 1 - +#define LIBKECCAK_DIGEST_H 1 #include "state.h" #include "internal.h" @@ -34,7 +16,7 @@ * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_fast_update(libkeccak_state_t *restrict state, const char* restrict msg, size_t msglen); /** @@ -47,7 +29,7 @@ int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restric * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_update(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen); /** @@ -63,8 +45,8 @@ int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_fast_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); /** @@ -80,8 +62,8 @@ int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restric * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); /** @@ -91,7 +73,7 @@ int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg * @param times The number of rounds */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, register long times); +void libkeccak_simple_squeeze(register libkeccak_state_t *restrict state, register long times); /** @@ -101,7 +83,7 @@ void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, regist * @param times The number of digests */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register long times); +void libkeccak_fast_squeeze(register libkeccak_state_t *restrict state, register long times); /** @@ -111,7 +93,7 @@ void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register * @param hashsum Output parameter for the hashsum */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -void libkeccak_squeeze(register libkeccak_state_t* restrict state, register char* restrict hashsum); +void libkeccak_squeeze(register libkeccak_state_t *restrict state, register char* restrict hashsum); #endif diff --git a/src/libkeccak/files.c b/src/libkeccak/files.c index 07c2383..22d12f3 100644 --- a/src/libkeccak/files.c +++ b/src/libkeccak/files.c @@ -1,29 +1,12 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "files.h" - -#include <stddef.h> -#include <unistd.h> #include <sys/stat.h> #include <alloca.h> #include <errno.h> +#include <stddef.h> +#include <unistd.h> + /** @@ -38,39 +21,37 @@ * at least `((spec->output + 7) / 8) * sizeof(char)`, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t* restrict state, - const libkeccak_spec_t* restrict spec, - const char* restrict suffix, char* restrict hashsum) +int +libkeccak_generalised_sum_fd(int fd, libkeccak_state_t *restrict state, + const libkeccak_spec_t *restrict spec, + const char *restrict suffix, char *restrict hashsum) { - ssize_t got; - struct stat attr; - size_t blksize = 4096; - char* restrict chunk; - - if (libkeccak_state_initialise(state, spec) < 0) - return -1; - - if (fstat(fd, &attr) == 0) - if (attr.st_blksize > 0) - blksize = (size_t)(attr.st_blksize); - - chunk = alloca(blksize); + ssize_t got; + struct stat attr; + size_t blksize = 4096; + char *restrict chunk; + + if (libkeccak_state_initialise(state, spec) < 0) + return -1; + + if (fstat(fd, &attr) == 0) + if (attr.st_blksize > 0) + blksize = (size_t)(attr.st_blksize); - for (;;) - { - got = read(fd, chunk, blksize); - if (got < 0) - { - if (errno == EINTR) - continue; - return -1; + chunk = alloca(blksize); + + for (;;) { + got = read(fd, chunk, blksize); + if (got < 0) { + if (errno == EINTR) + continue; + return -1; + } + if (got == 0) + break; + if (libkeccak_fast_update(state, chunk, (size_t)got) < 0) + return -1; } - if (got == 0) - break; - if (libkeccak_fast_update(state, chunk, (size_t)got) < 0) - return -1; - } - - return libkeccak_fast_digest(state, NULL, 0, 0, suffix, hashsum); -} + return libkeccak_fast_digest(state, NULL, 0, 0, suffix, hashsum); +} diff --git a/src/libkeccak/files.h b/src/libkeccak/files.h index d694bbc..92038fb 100644 --- a/src/libkeccak/files.h +++ b/src/libkeccak/files.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_FILES_H -#define LIBKECCAK_FILES_H 1 - +#define LIBKECCAK_FILES_H 1 #include "../libkeccak.h" #include "internal.h" @@ -37,9 +19,9 @@ * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2, 3)))) -int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t* restrict state, - const libkeccak_spec_t* restrict spec, - const char* restrict suffix, char* restrict hashsum); +int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t *restrict state, + const libkeccak_spec_t *restrict spec, + const char *restrict suffix, char *restrict hashsum); /** @@ -54,11 +36,11 @@ int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2, 3), artificial, gnu_inline))) -static inline -int libkeccak_keccaksum_fd(int fd, libkeccak_state_t* restrict state, - const libkeccak_spec_t* restrict spec, char* restrict hashsum) +static inline int +libkeccak_keccaksum_fd(int fd, libkeccak_state_t *restrict state, + const libkeccak_spec_t *restrict spec, char *restrict hashsum) { - return libkeccak_generalised_sum_fd(fd, state, spec, NULL, hashsum); + return libkeccak_generalised_sum_fd(fd, state, spec, NULL, hashsum); } @@ -74,13 +56,13 @@ int libkeccak_keccaksum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2), artificial, gnu_inline))) -static inline -int libkeccak_sha3sum_fd(int fd, libkeccak_state_t* restrict state, - long output, char* restrict hashsum) +static inline int +libkeccak_sha3sum_fd(int fd, libkeccak_state_t *restrict state, + long output, char *restrict hashsum) { - libkeccak_spec_t spec; - libkeccak_spec_sha3(&spec, output); - return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHA3_SUFFIX, hashsum); + libkeccak_spec_t spec; + libkeccak_spec_sha3(&spec, output); + return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHA3_SUFFIX, hashsum); } @@ -97,13 +79,13 @@ int libkeccak_sha3sum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2), artificial, gnu_inline))) -static inline -int libkeccak_rawshakesum_fd(int fd, libkeccak_state_t* restrict state, - long semicapacity, long output, char* restrict hashsum) +static inline int +libkeccak_rawshakesum_fd(int fd, libkeccak_state_t *restrict state, + long semicapacity, long output, char *restrict hashsum) { - libkeccak_spec_t spec; - libkeccak_spec_rawshake(&spec, semicapacity, output); - return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_RAWSHAKE_SUFFIX, hashsum); + libkeccak_spec_t spec; + libkeccak_spec_rawshake(&spec, semicapacity, output); + return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_RAWSHAKE_SUFFIX, hashsum); } @@ -120,15 +102,14 @@ int libkeccak_rawshakesum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2), artificial, gnu_inline))) -static inline -int libkeccak_shakesum_fd(int fd, libkeccak_state_t* restrict state, - long semicapacity, long output, char* restrict hashsum) +static inline int +libkeccak_shakesum_fd(int fd, libkeccak_state_t *restrict state, + long semicapacity, long output, char *restrict hashsum) { - libkeccak_spec_t spec; - libkeccak_spec_shake(&spec, semicapacity, output); - return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHAKE_SUFFIX, hashsum); + libkeccak_spec_t spec; + libkeccak_spec_shake(&spec, semicapacity, output); + return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHAKE_SUFFIX, hashsum); } #endif - diff --git a/src/libkeccak/generalised-spec.c b/src/libkeccak/generalised-spec.c index 79d673b..9dfa918 100644 --- a/src/libkeccak/generalised-spec.c +++ b/src/libkeccak/generalised-spec.c @@ -1,32 +1,15 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "generalised-spec.h" - #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif -#define have(v) (spec->v != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC) -#define copy(v) (v = spec->v) -#define deft(v, dv) (have_##v ? v : (dv)) +#define have(v) (spec->v != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC) +#define copy(v) (v = spec->v) +#define deft(v, dv) (have_##v ? v : (dv)) + /** @@ -39,97 +22,83 @@ * @param output_spec The specification datastructure to fill in * @return Zero if `spec` is valid, a `LIBKECCAK_GENERALISED_SPEC_ERROR_*` if an error was found */ -int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t* restrict spec, - libkeccak_spec_t* restrict output_spec) +int +libkeccak_degeneralise_spec(libkeccak_generalised_spec_t *restrict spec, + libkeccak_spec_t *restrict output_spec) { - long state_size, word_size, capacity, bitrate, output; - const int have_state_size = have(state_size); - const int have_word_size = have(word_size); - const int have_capacity = have(capacity); - const int have_bitrate = have(bitrate); - const int have_output = have(output); - - - if (have_state_size) - { - copy(state_size); - if (state_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE; - if (state_size > 1600) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE; - if (state_size % 25) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25; - } - - if (have_word_size) - { - copy(word_size); - if (word_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE; - if (word_size > 64) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE; - if (have_state_size && (state_size != word_size * 25)) - return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY; - else if (!have_state_size) - spec->state_size = 1, state_size = word_size * 25; - } - - if (have_capacity) - { - copy(capacity); - if (capacity <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE; - if (capacity & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8; - } - - if (have_bitrate) - { - copy(bitrate); - if (bitrate <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE; - if (bitrate & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8; - } - - if (have_output) - { - copy(output); - if (output <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE; - } - - - if (!have_bitrate && !have_capacity && !have_output) - { - state_size = deft(state_size, 1600L); - output = ((state_size << 5) / 100L + 7L) & ~0x07L; - bitrate = output << 1; - capacity = state_size - bitrate; - output = output >= 8 ? output : 8; - } - else if (!have_bitrate && !have_capacity) - { - bitrate = 1024; - capacity = 1600 - 1024; - state_size = deft(state_size, bitrate + capacity); - } - else if (!have_bitrate) - { - state_size = deft(state_size, 1600L); - bitrate = state_size - capacity; - output = deft(output, capacity == 8 ? 8 : (capacity << 1)); - } - else if (!have_capacity) - { - state_size = deft(state_size, 1600L); - capacity = state_size - bitrate; - output = deft(output, capacity == 8 ? 8 : (capacity << 1)); - } - else - { - state_size = deft(state_size, bitrate + capacity); - output = deft(output, capacity == 8 ? 8 : (capacity << 1)); - } - - - spec->capacity = output_spec->capacity = capacity; - spec->bitrate = output_spec->bitrate = bitrate; - spec->output = output_spec->output = output; - spec->state_size = state_size; - spec->word_size = state_size / 25; - - return 0; + long state_size, word_size, capacity, bitrate, output; + const int have_state_size = have(state_size); + const int have_word_size = have(word_size); + const int have_capacity = have(capacity); + const int have_bitrate = have(bitrate); + const int have_output = have(output); + + + if (have_state_size) { + copy(state_size); + if (state_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE; + if (state_size > 1600) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE; + if (state_size % 25) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25; + } + + if (have_word_size) { + copy(word_size); + if (word_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE; + if (word_size > 64) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE; + if (have_state_size && state_size != word_size * 25) + return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY; + else if (!have_state_size) + spec->state_size = 1, state_size = word_size * 25; + } + + if (have_capacity) { + copy(capacity); + if (capacity <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE; + if (capacity & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8; + } + + if (have_bitrate) { + copy(bitrate); + if (bitrate <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE; + if (bitrate & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8; + } + + if (have_output) { + copy(output); + if (output <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE; + } + + + if (!have_bitrate && !have_capacity && !have_output) { + state_size = deft(state_size, 1600L); + output = ((state_size << 5) / 100L + 7L) & ~0x07L; + bitrate = output << 1; + capacity = state_size - bitrate; + output = output >= 8 ? output : 8; + } else if (!have_bitrate && !have_capacity) { + bitrate = 1024; + capacity = 1600 - 1024; + state_size = deft(state_size, bitrate + capacity); + } else if (!have_bitrate) { + state_size = deft(state_size, 1600L); + bitrate = state_size - capacity; + output = deft(output, capacity == 8 ? 8 : (capacity << 1)); + } else if (!have_capacity) { + state_size = deft(state_size, 1600L); + capacity = state_size - bitrate; + output = deft(output, capacity == 8 ? 8 : (capacity << 1)); + } else { + state_size = deft(state_size, bitrate + capacity); + output = deft(output, capacity == 8 ? 8 : (capacity << 1)); + } + + spec->capacity = output_spec->capacity = capacity; + spec->bitrate = output_spec->bitrate = bitrate; + spec->output = output_spec->output = output; + spec->state_size = state_size; + spec->word_size = state_size / 25; + + return 0; } @@ -140,4 +109,3 @@ int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t* restrict spec, #ifdef __GNUC__ # pragma GCC diagnostic pop #endif - diff --git a/src/libkeccak/generalised-spec.h b/src/libkeccak/generalised-spec.h index 6bd091e..2725961 100644 --- a/src/libkeccak/generalised-spec.h +++ b/src/libkeccak/generalised-spec.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_GENERALISED_SPEC_H -#define LIBKECCAK_GENERALISED_SPEC_H 1 - +#define LIBKECCAK_GENERALISED_SPEC_H 1 #include "spec.h" #include "internal.h" @@ -31,64 +13,64 @@ * Value for `libkeccak_generalised_spec_t` member that * is used to automatically select the value */ -#define LIBKECCAK_GENERALISED_SPEC_AUTOMATIC (-65536L) +#define LIBKECCAK_GENERALISED_SPEC_AUTOMATIC (-65536L) /** * Invalid `libkeccak_generalised_spec_t.state_size`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE 1 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE 1 /** * Invalid `libkeccak_generalised_spec_t.state_size`: larger than 1600 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE 2 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE 2 /** * Invalid `libkeccak_generalised_spec_t.state_size`: not a multiple of 25 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25 3 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25 3 /** * Invalid `libkeccak_generalised_spec_t.word_size`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE 4 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE 4 /** * Invalid `libkeccak_generalised_spec_t.word_size`: larger than 1600 / 25 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE 5 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE 5 /** * Invalid `libkeccak_generalised_spec_t.word_size` and * `libkeccak_generalised_spec_t.state_size`: `.word_size * 25 != .state_size` */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY 6 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY 6 /** * Invalid `libkeccak_generalised_spec_t.capacity`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE 7 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE 7 /** * Invalid `libkeccak_generalised_spec_t.capacity`: not a multiple of 8 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8 8 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8 8 /** * Invalid `libkeccak_generalised_spec_t.bitrate`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE 9 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE 9 /** * Invalid `libkeccak_generalised_spec_t.bitrate`: not a multiple of 8 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8 10 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8 10 /** * Invalid `libkeccak_generalised_spec_t.output`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE 11 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE 11 @@ -98,31 +80,31 @@ */ typedef struct libkeccak_generalised_spec { - /** - * The bitrate - */ - long bitrate; - - /** - * The capacity - */ - long capacity; - - /** - * The output size - */ - long output; - - /** - * The state size - */ - long state_size; - - /** - * The word size - */ - long word_size; - + /** + * The bitrate + */ + long bitrate; + + /** + * The capacity + */ + long capacity; + + /** + * The output size + */ + long output; + + /** + * The state size + */ + long state_size; + + /** + * The word size + */ + long word_size; + } libkeccak_generalised_spec_t; @@ -133,14 +115,14 @@ typedef struct libkeccak_generalised_spec * @param spec The specification datastructure to fill in */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused))) -static inline -void libkeccak_generalised_spec_initialise(libkeccak_generalised_spec_t* restrict spec) +static inline void +libkeccak_generalised_spec_initialise(libkeccak_generalised_spec_t *restrict spec) { - spec->bitrate = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->capacity = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->output = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->state_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->word_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->bitrate = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->capacity = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->output = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->state_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->word_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; } @@ -152,8 +134,8 @@ void libkeccak_generalised_spec_initialise(libkeccak_generalised_spec_t* restric * @return Zero if `spec` is valid, a `LIBKECCAK_GENERALISED_SPEC_ERROR_*` if an error was found */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t* restrict spec, - libkeccak_spec_t* restrict output_spec); +int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t *restrict spec, + libkeccak_spec_t *restrict output_spec); #endif diff --git a/src/libkeccak/hex.c b/src/libkeccak/hex.c index 54f4006..7531223 100644 --- a/src/libkeccak/hex.c +++ b/src/libkeccak/hex.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "hex.h" #include <string.h> @@ -29,14 +12,14 @@ * @param hashsum The hashsum to convert * @param n The size of `hashsum` */ -void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, size_t n) +void +libkeccak_behex_lower(char *restrict output, const char *restrict hashsum, size_t n) { - output[2 * n] = '\0'; - while (n--) - { - output[2 * n + 0] = "0123456789abcdef"[(hashsum[n] >> 4) & 15]; - output[2 * n + 1] = "0123456789abcdef"[(hashsum[n] >> 0) & 15]; - } + output[2 * n] = '\0'; + while (n--) { + output[2 * n + 0] = "0123456789abcdef"[(hashsum[n] >> 4) & 15]; + output[2 * n + 1] = "0123456789abcdef"[(hashsum[n] >> 0) & 15]; + } } @@ -47,14 +30,14 @@ void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, * @param hashsum The hashsum to convert * @param n The size of `hashsum` */ -void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, size_t n) +void +libkeccak_behex_upper(char *restrict output, const char *restrict hashsum, size_t n) { - output[2 * n] = '\0'; - while (n--) - { - output[2 * n + 0] = "0123456789ABCDEF"[(hashsum[n] >> 4) & 15]; - output[2 * n + 1] = "0123456789ABCDEF"[(hashsum[n] >> 0) & 15]; - } + output[2 * n] = '\0'; + while (n--) { + output[2 * n + 0] = "0123456789ABCDEF"[(hashsum[n] >> 4) & 15]; + output[2 * n + 1] = "0123456789ABCDEF"[(hashsum[n] >> 0) & 15]; + } } @@ -65,18 +48,18 @@ void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, * @param output Output array, should have an allocation size of at least `strlen(hashsum) / 2` * @param hashsum The hashsum to convert */ -void libkeccak_unhex(char* restrict output, const char* restrict hashsum) +void +libkeccak_unhex(char *restrict output, const char *restrict hashsum) { - size_t n = strlen(hashsum) / 2; - while (n--) - { - char a = hashsum[2 * n + 0]; - char b = hashsum[2 * n + 1]; - - a = (char)((a & 15) + (a > '9' ? 9 : 0)); - b = (char)((b & 15) + (b > '9' ? 9 : 0)); - - output[n] = (char)((a << 4) | b); - } -} + size_t n = strlen(hashsum) / 2; + char a, b; + while (n--) { + a = hashsum[2 * n + 0]; + b = hashsum[2 * n + 1]; + a = (char)((a & 15) + (a > '9' ? 9 : 0)); + b = (char)((b & 15) + (b > '9' ? 9 : 0)); + + output[n] = (char)((a << 4) | b); + } +} diff --git a/src/libkeccak/hex.h b/src/libkeccak/hex.h index ce2a948..25375d5 100644 --- a/src/libkeccak/hex.h +++ b/src/libkeccak/hex.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_HEX_H -#define LIBKECCAK_HEX_H 1 - +#define LIBKECCAK_HEX_H 1 #include "internal.h" @@ -33,7 +15,7 @@ * @param n The size of `hashsum` */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, size_t n); +void libkeccak_behex_lower(char *restrict output, const char *restrict hashsum, size_t n); /** @@ -44,7 +26,7 @@ void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, * @param n The size of `hashsum` */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, size_t n); +void libkeccak_behex_upper(char *restrict output, const char *restrict hashsum, size_t n); /** @@ -55,7 +37,7 @@ void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, * @param hashsum The hashsum to convert */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -void libkeccak_unhex(char* restrict output, const char* restrict hashsum); +void libkeccak_unhex(char *restrict output, const char *restrict hashsum); #endif diff --git a/src/libkeccak/internal.h b/src/libkeccak/internal.h index 5c8432e..466abf9 100644 --- a/src/libkeccak/internal.h +++ b/src/libkeccak/internal.h @@ -1,23 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_INTERNAL_H -#define LIBKECCAK_INTERNAL_H 1 +#define LIBKECCAK_INTERNAL_H 1 /** @@ -25,11 +8,19 @@ * if compiling with GCC. */ #ifdef __GNUC__ -# define LIBKECCAK_GCC_ONLY(x) x +# define LIBKECCAK_GCC_ONLY(x) x #else # define LIBKECCAK_GCC_ONLY(x) #endif +/* Use built in functions and branching optimisation if available */ +#ifndef __GNUC__ +# define __builtin_expect(expression, expect) expression +# define __builtin_memset(dest, c, n) memset(dest, c, n) +# define __builtin_memcpy(dest, src, n) memcpy(dest, src, n) +# define __builtin_memmove(dest, src, n) memmove(dest, src, n) #endif + +#endif diff --git a/src/libkeccak/mac/hmac.c b/src/libkeccak/mac/hmac.c index 3ecf539..ee3bc6a 100644 --- a/src/libkeccak/mac/hmac.c +++ b/src/libkeccak/mac/hmac.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "hmac.h" #include "../digest.h" @@ -25,20 +8,20 @@ /** * The outer pad pattern */ -#define OUTER_PAD 0x5C +#define OUTER_PAD 0x5C /** * The inner pad pattern */ -#define INNER_PAD 0x36 +#define INNER_PAD 0x36 -static void* (*volatile my_explicit_memset)(void*, int, size_t) = memset; -static __attribute__((optimize("-O0"))) -void my_explicit_bzero(void* ptr, size_t size) +static void *(*volatile my_explicit_memset)(void *, int, size_t) = memset; +static __attribute__((optimize("-O0"))) void +my_explicit_bzero(void *ptr, size_t size) { - (*my_explicit_memset)(ptr, 0, size); + (*my_explicit_memset)(ptr, 0, size); } @@ -50,38 +33,39 @@ void my_explicit_bzero(void* ptr, size_t size) * @param key_length The length of key, in bits * @return Zero on success, -1 on error */ -int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length) +int +libkeccak_hmac_set_key(libkeccak_hmac_state_t *restrict state, const char *restrict key, size_t key_length) { - size_t i, size, new_key_length, key_bytes; - char* old; - - size = (size_t)(state->sponge.r) > key_length ? (size_t)(state->sponge.r) : key_length; - new_key_length = size; - size = (size + 7) >> 3; - key_bytes = (key_length + 7) >> 3; - - if (size != key_bytes) - { - state->key_opad = realloc(old = state->key_opad, 2 * size); - if (state->key_opad == NULL) - return state->key_opad = old, -1; - state->key_ipad = state->key_opad + size / sizeof(char); - } - - memcpy(state->key_opad, key, key_bytes); - if (key_length & 7) - state->key_opad[(key_bytes >> 3) - 1] &= (1 << (key_length & 7)) - 1; - - if ((size_t)(state->sponge.r) > key_length) - __builtin_memset(state->key_opad + key_bytes / sizeof(char), 0, size - key_bytes); - - for (i = 0; i < size; i++) - state->key_ipad[i] = state->key_opad[i] ^ INNER_PAD, - state->key_opad[i] ^= OUTER_PAD; - - state->key_length = new_key_length; - - return 0; + size_t i, size, new_key_length, key_bytes; + char *old; + + size = (size_t)(state->sponge.r) > key_length ? (size_t)(state->sponge.r) : key_length; + new_key_length = size; + size = (size + 7) >> 3; + key_bytes = (key_length + 7) >> 3; + + if (size != key_bytes) { + state->key_opad = realloc(old = state->key_opad, 2 * size); + if (!state->key_opad) + return state->key_opad = old, -1; + state->key_ipad = state->key_opad + size / sizeof(char); + } + + memcpy(state->key_opad, key, key_bytes); + if (key_length & 7) + state->key_opad[(key_bytes >> 3) - 1] &= (1 << (key_length & 7)) - 1; + + if ((size_t)(state->sponge.r) > key_length) + __builtin_memset(state->key_opad + key_bytes / sizeof(char), 0, size - key_bytes); + + for (i = 0; i < size; i++) { + state->key_ipad[i] = state->key_opad[i] ^ INNER_PAD; + state->key_opad[i] ^= OUTER_PAD; + } + + state->key_length = new_key_length; + + return 0; } @@ -90,17 +74,18 @@ int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* r * * @param state The state that should be wipe */ -void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state) +void +libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t *restrict state) { - volatile char* restrict key_pads; - size_t i, size; - key_pads = state->key_opad; - size = 2 * ((state->key_length + 7) >> 3); - libkeccak_state_wipe(&(state->sponge)); - for (i = 0; i < size; i++) - key_pads[i] = 0; - state->leftover = 0; - __builtin_memset(state->buffer, 0, state->buffer_size); + volatile char *restrict key_pads; + size_t i, size; + key_pads = state->key_opad; + size = 2 * ((state->key_length + 7) >> 3); + libkeccak_state_wipe(&state->sponge); + for (i = 0; i < size; i++) + key_pads[i] = 0; + state->leftover = 0; + __builtin_memset(state->buffer, 0, state->buffer_size); } @@ -111,30 +96,30 @@ void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state) * @param src The state to duplicate * @return Zero on success, -1 on error */ -int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_hmac_state_t* restrict src) +int +libkeccak_hmac_copy(libkeccak_hmac_state_t *restrict dest, const libkeccak_hmac_state_t *restrict src) { - int saved_errno; - size_t size; - - dest->key_opad = NULL; - dest->key_ipad = NULL; - - if (libkeccak_state_copy(&(dest->sponge), &(src->sponge)) < 0) - return -1; - - dest->key_length = src->key_length; - dest->leftover = src->leftover; - - size = (src->key_length + 7) >> 3; - dest->key_opad = malloc(2 * size); - if (dest->key_opad == NULL) - return saved_errno = errno, libkeccak_state_destroy(&(dest->sponge)), errno = saved_errno, -1; - dest->key_ipad = dest->key_opad + size / sizeof(char); - - memcpy(dest->key_opad, src->key_opad, size); - memcpy(dest->key_ipad, src->key_ipad, size); - - return 0; + size_t size; + + dest->key_opad = NULL; + dest->key_ipad = NULL; + + if (libkeccak_state_copy(&dest->sponge, &src->sponge) < 0) + return -1; + + dest->key_length = src->key_length; + dest->leftover = src->leftover; + + size = (src->key_length + 7) >> 3; + dest->key_opad = malloc(2 * size); + if (dest->key_opad == NULL) + return libkeccak_state_destroy(&dest->sponge), -1; + dest->key_ipad = dest->key_opad + size / sizeof(char); + + memcpy(dest->key_opad, src->key_opad, size); + memcpy(dest->key_ipad, src->key_ipad, size); + + return 0; } @@ -145,42 +130,41 @@ int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_h * @param data The input buffer * @return The number of bytes read from `data`, 0 on error */ -size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const char* restrict data) +size_t +libkeccak_hmac_unmarshal(libkeccak_hmac_state_t *restrict state, const char *restrict data) { - size_t parsed, size, i; - int saved_errno; - - state->key_opad = NULL; - state->key_ipad = NULL; - - parsed = libkeccak_state_unmarshal(&(state->sponge), data); - if (parsed == 0) - return 0; - - data += parsed / sizeof(char); - state->key_length = *(const size_t*)data; - data += sizeof(size_t) / sizeof(char); - size = (state->key_length + 7) >> 3; - - state->key_opad = malloc(2 * size); - if (state->key_opad == NULL) - return saved_errno = errno, libkeccak_state_destroy(&(state->sponge)), errno = saved_errno, -1; - memcpy(state->key_opad, data, size); - data += size / sizeof(char); - - if (data[0]) - { - state->key_ipad = state->key_opad + size / sizeof(char); - memcpy(state->key_ipad, state->key_opad, size); - for (i = 0; i < size / sizeof(char); i++) - state->key_ipad[i] ^= (char)(OUTER_PAD ^ INNER_PAD); - } - - state->leftover = data[1]; - state->buffer = NULL; - state->buffer_size = 0; - - return parsed + sizeof(size_t) + size + 2 * sizeof(char); + size_t parsed, size, i; + + state->key_opad = NULL; + state->key_ipad = NULL; + + parsed = libkeccak_state_unmarshal(&state->sponge, data); + if (parsed == 0) + return 0; + + data += parsed / sizeof(char); + state->key_length = *(const size_t *)data; + data += sizeof(size_t) / sizeof(char); + size = (state->key_length + 7) >> 3; + + state->key_opad = malloc(2 * size); + if (state->key_opad == NULL) + return libkeccak_state_destroy(&state->sponge), -1; + memcpy(state->key_opad, data, size); + data += size / sizeof(char); + + if (data[0]) { + state->key_ipad = state->key_opad + size / sizeof(char); + memcpy(state->key_ipad, state->key_opad, size); + for (i = 0; i < size / sizeof(char); i++) + state->key_ipad[i] ^= (char)(OUTER_PAD ^ INNER_PAD); + } + + state->leftover = data[1]; + state->buffer = NULL; + state->buffer_size = 0; + + return parsed + sizeof(size_t) + size + 2 * sizeof(char); } @@ -193,42 +177,42 @@ size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const ch * @param msglen The length of the partial message, in bytes * @return Zero on success, -1 on error */ -int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_hmac_fast_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen) { - char* old; - size_t i; - int n, cn; - - if (state->key_ipad != NULL) - { - if (libkeccak_fast_update(&(state->sponge), state->key_ipad, state->key_length >> 3) < 0) - return -1; - if (state->key_length & 7) - state->leftover = state->key_ipad[(state->key_length >> 3)]; - state->key_ipad = NULL; - } - - if ((msg == NULL) || (msglen == 0)) - return 0; - - if (!(state->key_length & 7)) - return libkeccak_fast_update(&(state->sponge), msg, msglen); - - if (msglen != state->buffer_size) - { - state->buffer = realloc(old = state->buffer, state->buffer_size = msglen); - if (state->buffer == NULL) - return state->buffer = old, -1; - } - - n = (int)(state->key_length & 7); - cn = 8 - n; - for (i = 1; i < msglen; i++) - state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); - state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); - state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; - - return libkeccak_fast_update(&(state->sponge), state->buffer, msglen); + char *old; + size_t i; + int n, cn; + + if (state->key_ipad) { + if (libkeccak_fast_update(&state->sponge, state->key_ipad, state->key_length >> 3) < 0) + return -1; + if (state->key_length & 7) + state->leftover = state->key_ipad[state->key_length >> 3]; + state->key_ipad = NULL; + } + + if (!msg || !msglen) + return 0; + + if (!(state->key_length & 7)) + return libkeccak_fast_update(&state->sponge, msg, msglen); + + if (msglen != state->buffer_size) { + state->buffer = realloc(old = state->buffer, msglen); + if (!state->buffer) + return state->buffer = old, -1; + state->buffer_size = msglen; + } + + n = (int)(state->key_length & 7); + cn = 8 - n; + for (i = 1; i < msglen; i++) + state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); + state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); + state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; + + return libkeccak_fast_update(&state->sponge, state->buffer, msglen); } @@ -241,46 +225,43 @@ int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const cha * @param msglen The length of the partial message, in bytes * @return Zero on success, -1 on error */ -int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_hmac_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen) { - size_t i; - int n, cn, r, saved_errno; - - if (state->key_ipad != NULL) - { - if (libkeccak_update(&(state->sponge), state->key_ipad, state->key_length >> 3) < 0) - return -1; - if (state->key_length & 7) - state->leftover = state->key_ipad[(state->key_length >> 3)]; - state->key_ipad = NULL; - } - - if ((msg == NULL) || (msglen == 0)) - return 0; - - if (!(state->key_length & 7)) - return libkeccak_update(&(state->sponge), msg, msglen); - - if (msglen != state->buffer_size) - { - free(state->buffer); - state->buffer = malloc(state->buffer_size = msglen); - if (state->buffer == NULL) - return -1; - } - - n = (int)(state->key_length & 7); - cn = 8 - n; - for (i = 1; i < msglen; i++) - state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); - state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); - state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; - - r = libkeccak_update(&(state->sponge), state->buffer, msglen); - saved_errno = errno; - my_explicit_bzero(state->buffer, msglen); - errno = saved_errno; - return r; + size_t i; + int n, cn, r; + + if (state->key_ipad) { + if (libkeccak_update(&state->sponge, state->key_ipad, state->key_length >> 3) < 0) + return -1; + if (state->key_length & 7) + state->leftover = state->key_ipad[state->key_length >> 3]; + state->key_ipad = NULL; + } + + if (!msg || !msglen) + return 0; + + if (!(state->key_length & 7)) + return libkeccak_update(&state->sponge, msg, msglen); + + if (msglen != state->buffer_size) { + free(state->buffer); + state->buffer = malloc(state->buffer_size = msglen); + if (!state->buffer) + return -1; + } + + n = (int)(state->key_length & 7); + cn = 8 - n; + for (i = 1; i < msglen; i++) + state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); + state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); + state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; + + r = libkeccak_update(&state->sponge, state->buffer, msglen); + my_explicit_bzero(state->buffer, msglen); + return r; } @@ -288,7 +269,7 @@ int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* re * Absorb the last part of the message and fetch the hash * without wiping sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -298,71 +279,64 @@ int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* re * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_hmac_fast_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - size_t hashsize = state->sponge.n >> 3; - char* tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); - char leftover[2]; - size_t newlen; - int saved_errno; - - if (tmp == NULL) - return -1; - - if (!(state->key_length & 7)) - { - if (libkeccak_fast_digest(&(state->sponge), msg, msglen, bits, suffix, tmp) < 0) - goto fail; - goto stage_2; - } - - if (libkeccak_hmac_fast_update(state, msg, msglen) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= msg[msglen] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_fast_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_2: - - bits = state->sponge.n & 7; - state->key_ipad = state->key_opad; - if (libkeccak_hmac_fast_update(state, NULL, 0) < 0) - goto fail; - - if (!(state->key_length & 7)) - { - if (libkeccak_fast_digest(&(state->sponge), tmp, hashsize, bits, suffix, hashsum) < 0) - goto fail; - goto stage_3; - } - - if (libkeccak_hmac_fast_update(state, tmp, hashsize) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= tmp[hashsize] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_fast_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_3: - - free(tmp); - return 0; - fail: - saved_errno = errno; - free(tmp); - return errno = saved_errno, -1; + size_t hashsize = state->sponge.n >> 3; + char *tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); + char leftover[2]; + size_t newlen; + + if (!tmp) + return -1; + + if (!(state->key_length & 7)) { + if (libkeccak_fast_digest(&state->sponge, msg, msglen, bits, suffix, tmp) < 0) + goto fail; + goto stage_2; + } + + if (libkeccak_hmac_fast_update(state, msg, msglen) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= msg[msglen] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_fast_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_2: + bits = state->sponge.n & 7; + state->key_ipad = state->key_opad; + if (libkeccak_hmac_fast_update(state, NULL, 0) < 0) + goto fail; + + if (!(state->key_length & 7)) { + if (libkeccak_fast_digest(&state->sponge, tmp, hashsize, bits, suffix, hashsum) < 0) + goto fail; + goto stage_3; + } + + if (libkeccak_hmac_fast_update(state, tmp, hashsize) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= tmp[hashsize] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_fast_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_3: + free(tmp); + return 0; +fail: + free(tmp); + return -1; } @@ -370,7 +344,7 @@ int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const cha * Absorb the last part of the message and fetch the hash * and wipe sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -380,71 +354,65 @@ int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const cha * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_hmac_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_hmac_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - size_t hashsize = state->sponge.n >> 3; - char* tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); - char leftover[2]; - size_t newlen; - int saved_errno; - - if (tmp == NULL) - return -1; - - if (!(state->key_length & 7)) - { - if (libkeccak_digest(&(state->sponge), msg, msglen, bits, suffix, tmp) < 0) - goto fail; - goto stage_2; - } - - if (libkeccak_hmac_update(state, msg, msglen) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= msg[msglen] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_2: - - bits = state->sponge.n & 7; - state->key_ipad = state->key_opad; - if (libkeccak_hmac_update(state, NULL, 0) < 0) - goto fail; - - if (!(state->key_length & 7)) - { - if (libkeccak_digest(&(state->sponge), tmp, hashsize, bits, suffix, hashsum) < 0) - goto fail; - goto stage_3; - } - - if (libkeccak_hmac_update(state, tmp, hashsize) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= tmp[hashsize] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_3: - my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); - free(tmp); - return 0; + size_t hashsize = state->sponge.n >> 3; + char *tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); + char leftover[2]; + size_t newlen; + + if (!tmp) + return -1; + + if (!(state->key_length & 7)) { + if (libkeccak_digest(&state->sponge, msg, msglen, bits, suffix, tmp) < 0) + goto fail; + goto stage_2; + } + + if (libkeccak_hmac_update(state, msg, msglen) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= msg[msglen] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_2: + bits = state->sponge.n & 7; + state->key_ipad = state->key_opad; + if (libkeccak_hmac_update(state, NULL, 0) < 0) + goto fail; + + if (!(state->key_length & 7)) { + if (libkeccak_digest(&state->sponge, tmp, hashsize, bits, suffix, hashsum) < 0) + goto fail; + goto stage_3; + } + + if (libkeccak_hmac_update(state, tmp, hashsize) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= tmp[hashsize] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_3: + my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); + free(tmp); + return 0; fail: - saved_errno = errno; - my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); - free(tmp); - return errno = saved_errno, -1; + my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); + free(tmp); + return -1; } diff --git a/src/libkeccak/mac/hmac.h b/src/libkeccak/mac/hmac.h index 0b3a29c..2681e61 100644 --- a/src/libkeccak/mac/hmac.h +++ b/src/libkeccak/mac/hmac.h @@ -1,31 +1,13 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_MAC_HMAC_H -#define LIBKECCAK_MAC_HMAC_H 1 - +#define LIBKECCAK_MAC_HMAC_H 1 -/* The Keccak hash-function, that was selected by NIST as the SHA-3 competition winner, +/* + * The Keccak hash-function, that was selected by NIST as the SHA-3 competition winner, * doesn't need this nested approach and can be used to generate a MAC by simply prepending * the key to the message. [http://keccak.noekeon.org] */ - #include "../spec.h" #include "../state.h" #include "../internal.h" @@ -43,46 +25,46 @@ */ typedef struct libkeccak_hmac_state { - /** - * The key right-padded and XOR:ed with the outer pad - */ - char* restrict key_opad; - - /** - * The key right-padded and XOR:ed with the inner pad - */ - char* restrict key_ipad; - /* Not marshalled, implicitly unmarshalled using `key_opad`. */ - /* Shares allocation with `key_opad`, do not `free`. */ - - /** - * The length of key, but at least the input block size, in bits - */ - size_t key_length; - - /** - * The state of the underlaying hash-algorithm - */ - libkeccak_state_t sponge; - - /** - * Buffer used to temporarily store bit shift message if - * `.key_length` is not zero modulus 8 - */ - char* restrict buffer; - - /** - * The allocation size of `.buffer` - */ - size_t buffer_size; - - /** - * Part of feed key, message or digest that have not been passed yet - */ - char leftover; - - char __pad[sizeof(void*) / sizeof(char) - 1]; - + /** + * The key right-padded and XOR:ed with the outer pad + */ + char *restrict key_opad; + + /** + * The key right-padded and XOR:ed with the inner pad + */ + char *restrict key_ipad; + /* Not marshalled, implicitly unmarshalled using `key_opad`. */ + /* Shares allocation with `key_opad`, do not `free`. */ + + /** + * The length of key, but at least the input block size, in bits + */ + size_t key_length; + + /** + * The state of the underlaying hash-algorithm + */ + libkeccak_state_t sponge; + + /** + * Buffer used to temporarily store bit shift message if + * `.key_length` is not zero modulus 8 + */ + char *restrict buffer; + + /** + * The allocation size of `.buffer` + */ + size_t buffer_size; + + /** + * Part of feed key, message or digest that have not been passed yet + */ + char leftover; + + char __pad[sizeof(void*) / sizeof(char) - 1]; + } libkeccak_hmac_state_t; @@ -96,7 +78,7 @@ typedef struct libkeccak_hmac_state * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1), unused))) -int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length); +int libkeccak_hmac_set_key(libkeccak_hmac_state_t *restrict state, const char *restrict key, size_t key_length); /** @@ -109,19 +91,18 @@ int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* r * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -static inline -int libkeccak_hmac_initialise(libkeccak_hmac_state_t* restrict state, const libkeccak_spec_t* restrict spec, - const char* restrict key, size_t key_length) +static inline int +libkeccak_hmac_initialise(libkeccak_hmac_state_t *restrict state, const libkeccak_spec_t *restrict spec, + const char *restrict key, size_t key_length) { - int saved_errno; - if (libkeccak_state_initialise(&(state->sponge), spec) < 0) - return -1; - if (libkeccak_hmac_set_key(state, key, key_length) < 0) - return saved_errno = errno, libkeccak_state_destroy(&(state->sponge)), errno = saved_errno, -1; - state->leftover = 0; - state->buffer = NULL; - state->buffer_size = 0; - return 0; + if (libkeccak_state_initialise(&state->sponge, spec) < 0) + return -1; + if (libkeccak_hmac_set_key(state, key, key_length) < 0) + return libkeccak_state_destroy(&state->sponge), -1; + state->leftover = 0; + state->buffer = NULL; + state->buffer_size = 0; + return 0; } @@ -134,15 +115,14 @@ int libkeccak_hmac_initialise(libkeccak_hmac_state_t* restrict state, const libk * @return The state, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_hmac_state_t* libkeccak_hmac_create(const libkeccak_spec_t* restrict spec, - const char* restrict key, size_t key_length) +static inline libkeccak_hmac_state_t * +libkeccak_hmac_create(const libkeccak_spec_t *restrict spec, + const char *restrict key, size_t key_length) { - libkeccak_hmac_state_t* restrict state = malloc(sizeof(libkeccak_hmac_state_t)); - int saved_errno; - if ((state == NULL) || libkeccak_hmac_initialise(state, spec, key, key_length)) - return saved_errno = errno, free(state), errno = saved_errno, NULL; - return state; + libkeccak_hmac_state_t *restrict state = malloc(sizeof(libkeccak_hmac_state_t)); + if (!state || libkeccak_hmac_initialise(state, spec, key, key_length)) + return free(state), NULL; + return state; } @@ -156,11 +136,11 @@ libkeccak_hmac_state_t* libkeccak_hmac_create(const libkeccak_spec_t* restrict s * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1), unused))) -static inline -int libkeccak_hmac_reset(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length) +static inline int +libkeccak_hmac_reset(libkeccak_hmac_state_t *restrict state, const char *restrict key, size_t key_length) { - libkeccak_state_reset(&(state->sponge)); - return key != NULL ? libkeccak_hmac_set_key(state, key, key_length) : 0; + libkeccak_state_reset(&state->sponge); + return key ? libkeccak_hmac_set_key(state, key, key_length) : 0; } @@ -170,7 +150,7 @@ int libkeccak_hmac_reset(libkeccak_hmac_state_t* restrict state, const char* res * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, optimize("-O0")))) -void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state); +void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t *restrict state); /** @@ -178,18 +158,18 @@ void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state); * * @param state The state that should be destroyed */ -static inline -void libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t *restrict state) { - if (state == NULL) - return; - free(state->key_opad); - state->key_opad = NULL; - state->key_ipad = NULL; - state->key_length = 0; - free(state->buffer); - state->buffer = NULL; - state->buffer_size = 0; + if (!state) + return; + free(state->key_opad); + state->key_opad = NULL; + state->key_ipad = NULL; + state->key_length = 0; + free(state->buffer); + state->buffer = NULL; + state->buffer_size = 0; } @@ -199,20 +179,20 @@ void libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t* restrict state) * @param state The state that should be destroyed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_hmac_destroy(volatile libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_destroy(volatile libkeccak_hmac_state_t *restrict state) { - if (state == NULL) - return; - libkeccak_hmac_wipe(state); - free(state->key_opad); - state->key_opad = NULL; - state->key_ipad = NULL; - state->key_length = 0; - state->leftover = 0; - free(state->buffer); - state->buffer = NULL; - state->buffer_size = 0; + if (!state) + return; + libkeccak_hmac_wipe(state); + free(state->key_opad); + state->key_opad = NULL; + state->key_ipad = NULL; + state->key_length = 0; + state->leftover = 0; + free(state->buffer); + state->buffer = NULL; + state->buffer_size = 0; } @@ -222,11 +202,11 @@ void libkeccak_hmac_destroy(volatile libkeccak_hmac_state_t* restrict state) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused))) -static inline -void libkeccak_hmac_fast_free(libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_fast_free(libkeccak_hmac_state_t *restrict state) { - libkeccak_hmac_fast_destroy(state); - free(state); + libkeccak_hmac_fast_destroy(state); + free(state); } @@ -236,15 +216,15 @@ void libkeccak_hmac_fast_free(libkeccak_hmac_state_t* restrict state) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_hmac_free(volatile libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_free(volatile libkeccak_hmac_state_t *restrict state) { #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wcast-qual" #endif - libkeccak_hmac_destroy(state); - free((libkeccak_hmac_state_t*)state); + libkeccak_hmac_destroy(state); + free((libkeccak_hmac_state_t*)state); #ifdef __GNUC__ # pragma GCC diagnostic pop #endif @@ -259,7 +239,7 @@ void libkeccak_hmac_free(volatile libkeccak_hmac_state_t* restrict state) * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_hmac_state_t* restrict src); +int libkeccak_hmac_copy(libkeccak_hmac_state_t *restrict dest, const libkeccak_hmac_state_t *restrict src); /** @@ -269,14 +249,13 @@ int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_h * @return The duplicate, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_hmac_state_t* libkeccak_hmac_duplicate(const libkeccak_hmac_state_t* restrict src) +static inline libkeccak_hmac_state_t * +libkeccak_hmac_duplicate(const libkeccak_hmac_state_t *restrict src) { - libkeccak_hmac_state_t* restrict dest = malloc(sizeof(libkeccak_hmac_state_t)); - int saved_errno; - if ((dest == NULL) || libkeccak_hmac_copy(dest, src)) - return saved_errno = errno, libkeccak_hmac_free(dest), errno = saved_errno, NULL; - return dest; + libkeccak_hmac_state_t* restrict dest = malloc(sizeof(libkeccak_hmac_state_t)); + if (!dest || libkeccak_hmac_copy(dest, src)) + return libkeccak_hmac_free(dest), NULL; + return dest; } @@ -288,11 +267,11 @@ libkeccak_hmac_state_t* libkeccak_hmac_duplicate(const libkeccak_hmac_state_t* r * @return The allocation size needed for the buffer to which the state will be marshalled */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused, warn_unused_result, pure))) -static inline -size_t libkeccak_hmac_marshal_size(const libkeccak_hmac_state_t* restrict state) +static inline size_t +libkeccak_hmac_marshal_size(const libkeccak_hmac_state_t *restrict state) { - return libkeccak_state_marshal_size(&(state->sponge)) + sizeof(size_t) + - ((state->key_length + 7) >> 3) + 2 * sizeof(char); + return libkeccak_state_marshal_size(&state->sponge) + sizeof(size_t) + + ((state->key_length + 7) >> 3) + 2 * sizeof(char); } @@ -304,18 +283,18 @@ size_t libkeccak_hmac_marshal_size(const libkeccak_hmac_state_t* restrict state) * @return The number of bytes stored to `data` */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -static inline -size_t libkeccak_hmac_marshal(const libkeccak_hmac_state_t* restrict state, char* restrict data) +static inline size_t +libkeccak_hmac_marshal(const libkeccak_hmac_state_t *restrict state, char *restrict data) { - size_t written = libkeccak_state_marshal(&(state->sponge), data); - data += written / sizeof(char); - *(size_t*)data = state->key_length; - data += sizeof(size_t) / sizeof(char); - memcpy(data, state->key_opad, (state->key_length + 7) >> 3); - data += ((state->key_length + 7) >> 3) / sizeof(char); - data[0] = (char)(state->key_ipad != NULL); - data[1] = state->leftover; - return written + sizeof(size_t) + ((state->key_length + 7) >> 3) + 2 * sizeof(char); + size_t written = libkeccak_state_marshal(&state->sponge, data); + data += written / sizeof(char); + *(size_t *)data = state->key_length; + data += sizeof(size_t) / sizeof(char); + memcpy(data, state->key_opad, (state->key_length + 7) >> 3); + data += ((state->key_length + 7) >> 3) / sizeof(char); + data[0] = (char)!!state->key_ipad; + data[1] = state->leftover; + return written + sizeof(size_t) + ((state->key_length + 7) >> 3) + 2 * sizeof(char); } @@ -327,7 +306,7 @@ size_t libkeccak_hmac_marshal(const libkeccak_hmac_state_t* restrict state, char * @return The number of bytes read from `data`, 0 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const char* restrict data); +size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t *restrict state, const char *restrict data); /** @@ -338,12 +317,12 @@ size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const ch * @return The byte size of the stored state */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, warn_unused_result, pure))) -static inline -size_t libkeccak_hmac_unmarshal_skip(const char* restrict data) +static inline size_t +libkeccak_hmac_unmarshal_skip(const char *restrict data) { - size_t skip = libkeccak_state_unmarshal_skip(data); - data += skip / sizeof(char); - return skip + sizeof(size_t) + *(const size_t*)data + 2 * sizeof(char); + size_t skip = libkeccak_state_unmarshal_skip(data); + data += skip / sizeof(char); + return skip + sizeof(size_t) + *(const size_t *)data + 2 * sizeof(char); } @@ -357,7 +336,7 @@ size_t libkeccak_hmac_unmarshal_skip(const char* restrict data) * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_hmac_fast_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen); /** @@ -370,14 +349,14 @@ int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const cha * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_hmac_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen); /** * Absorb the last part of the message and fetch the hash * without wiping sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -388,15 +367,15 @@ int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* re * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); /** * Absorb the last part of the message and fetch the hash * and wipe sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -407,9 +386,8 @@ int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const cha * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_hmac_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); #endif - diff --git a/src/libkeccak/spec.h b/src/libkeccak/spec.h index 2f0b21b..8d73c52 100644 --- a/src/libkeccak/spec.h +++ b/src/libkeccak/spec.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_SPEC_H -#define LIBKECCAK_SPEC_H 1 - +#define LIBKECCAK_SPEC_H 1 #include "internal.h" @@ -29,68 +11,68 @@ /** * Message suffix for SHA3 hashing */ -#define LIBKECCAK_SHA3_SUFFIX "01" +#define LIBKECCAK_SHA3_SUFFIX "01" /** * Message suffix for RawSHAKE hashing */ -#define LIBKECCAK_RAWSHAKE_SUFFIX "11" +#define LIBKECCAK_RAWSHAKE_SUFFIX "11" /** * Message suffix for SHAKE hashing */ -#define LIBKECCAK_SHAKE_SUFFIX "1111" +#define LIBKECCAK_SHAKE_SUFFIX "1111" /** * Invalid `libkeccak_spec_t.bitrate`: non-positive */ -#define LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE 1 +#define LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE 1 /** * Invalid `libkeccak_spec_t.bitrate`: not a multiple of 8 */ -#define LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8 2 +#define LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8 2 /** * Invalid `libkeccak_spec_t.capacity`: non-positive */ -#define LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE 3 +#define LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE 3 /** * Invalid `libkeccak_spec_t.capacity`: not a multiple of 8 */ -#define LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8 4 +#define LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8 4 /** * Invalid `libkeccak_spec_t.output`: non-positive */ -#define LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE 5 +#define LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE 5 /** * Invalid `libkeccak_spec_t` values: `.bitrate + `.capacity` * is greater 1600 which is the largest supported state size */ -#define LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE 6 +#define LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE 6 /** * Invalid `libkeccak_spec_t` values: * `.bitrate + `.capacity` is not a multiple of 25 */ -#define LIBKECCAK_SPEC_ERROR_STATE_MOD_25 7 +#define LIBKECCAK_SPEC_ERROR_STATE_MOD_25 7 /** * Invalid `libkeccak_spec_t` values: `.bitrate + `.capacity` * is a not a 2-potent multiple of 25 */ -#define LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT 8 +#define LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT 8 /** * Invalid `libkeccak_spec_t` values: `.bitrate + `.capacity` * is a not multiple of 100, and thus the word size is not * a multiple of 8 */ -#define LIBKECCAK_SPEC_ERROR_WORD_MOD_8 9 +#define LIBKECCAK_SPEC_ERROR_WORD_MOD_8 9 @@ -98,23 +80,22 @@ * Datastructure that describes the parameters * that should be used when hashing */ -typedef struct libkeccak_spec -{ - /** - * The bitrate - */ - long bitrate; - - /** - * The capacity - */ - long capacity; - - /** - * The output size - */ - long output; - +typedef struct libkeccak_spec { + /** + * The bitrate + */ + long bitrate; + + /** + * The capacity + */ + long capacity; + + /** + * The output size + */ + long output; + } libkeccak_spec_t; @@ -126,12 +107,12 @@ typedef struct libkeccak_spec * @param x The value of x in `SHA3-x`, the output size */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -static inline -void libkeccak_spec_sha3(libkeccak_spec_t* restrict spec, long x) +static inline void +libkeccak_spec_sha3(libkeccak_spec_t *restrict spec, long x) { - spec->bitrate = 1600 - 2 * x; - spec->capacity = 2 * x; - spec->output = x; + spec->bitrate = 1600 - 2 * x; + spec->capacity = 2 * x; + spec->output = x; } @@ -143,12 +124,12 @@ void libkeccak_spec_sha3(libkeccak_spec_t* restrict spec, long x) * @param d The output size */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -static inline -void libkeccak_spec_rawshake(libkeccak_spec_t* restrict spec, long x, long d) +static inline void +libkeccak_spec_rawshake(libkeccak_spec_t *restrict spec, long x, long d) { - spec->bitrate = 1600 - 2 * x; - spec->capacity = 2 * x; - spec->output = d; + spec->bitrate = 1600 - 2 * x; + spec->capacity = 2 * x; + spec->output = d; } @@ -159,7 +140,7 @@ void libkeccak_spec_rawshake(libkeccak_spec_t* restrict spec, long x, long d) * @param x:long The value of x in `SHAKEx`, half the capacity * @param d:long The output size */ -#define libkeccak_spec_shake libkeccak_spec_rawshake +#define libkeccak_spec_shake libkeccak_spec_rawshake /** @@ -169,30 +150,28 @@ void libkeccak_spec_rawshake(libkeccak_spec_t* restrict spec, long x, long d) * @return Zero if error free, a `LIBKECCAK_SPEC_ERROR_*` if an error was found */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused, warn_unused_result, pure))) -static inline -int libkeccak_spec_check(const libkeccak_spec_t* restrict spec) +static inline int +libkeccak_spec_check(const libkeccak_spec_t *restrict spec) { - long state_size = spec->capacity + spec->bitrate; - int32_t word_size = (int32_t)(state_size / 25); - if (spec->bitrate <= 0) return LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE; - if (spec->bitrate % 8) return LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8; - if (spec->capacity <= 0) return LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE; - if (spec->capacity % 8) return LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8; - if (spec->output <= 0) return LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE; - if (state_size > 1600) return LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE; - if (state_size % 25) return LIBKECCAK_SPEC_ERROR_STATE_MOD_25; - if (word_size % 8) return LIBKECCAK_SPEC_ERROR_WORD_MOD_8; - - /* `(x & -x) != x` assumes two's complement, which of course is always - * satisfied by GCC, however C99 guarantees that `int32_t` exists, - * and it is basically the same thing as `long int`; with one important - * difference: it is guaranteed to use two's complement. */ - if ((word_size & -word_size) != word_size) - return LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT; - - return 0; + long state_size = spec->capacity + spec->bitrate; + int32_t word_size = (int32_t)(state_size / 25); + if (spec->bitrate <= 0) return LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE; + if (spec->bitrate % 8) return LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8; + if (spec->capacity <= 0) return LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE; + if (spec->capacity % 8) return LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8; + if (spec->output <= 0) return LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE; + if (state_size > 1600) return LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE; + if (state_size % 25) return LIBKECCAK_SPEC_ERROR_STATE_MOD_25; + if (word_size % 8) return LIBKECCAK_SPEC_ERROR_WORD_MOD_8; + + /* `(x & -x) != x` assumes two's complement, which of course is always + * satisfied by GCC, however C99 guarantees that `int32_t` exists, + * and it is basically the same thing as `long int`; with one important + * difference: it is guaranteed to use two's complement. */ + if ((word_size & -word_size) != word_size) + return LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT; + + return 0; } - #endif - diff --git a/src/libkeccak/state.c b/src/libkeccak/state.c index 5eec52c..c6360b7 100644 --- a/src/libkeccak/state.c +++ b/src/libkeccak/state.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "state.h" #include <string.h> @@ -29,26 +12,27 @@ * @param spec The specifications for the state * @return Zero on success, -1 on error */ -int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkeccak_spec_t* restrict spec) +int +libkeccak_state_initialise(libkeccak_state_t *restrict state, const libkeccak_spec_t *restrict spec) { - long x; - state->r = spec->bitrate; - state->n = spec->output; - state->c = spec->capacity; - state->b = state->r + state->c; - state->w = x = state->b / 25; - state->l = 0; - if (x & 0xF0L) state->l |= 4, x >>= 4; - if (x & 0x0CL) state->l |= 2, x >>= 2; - if (x & 0x02L) state->l |= 1; - state->nr = 12 + (state->l << 1); - state->wmod = (state->w == 64) ? ~0LL : (int64_t)((1ULL << state->w) - 1); - for (x = 0; x < 25; x++) - state->S[x] = 0; - state->mptr = 0; - state->mlen = (size_t)(state->r * state->b) >> 2; - state->M = malloc(state->mlen * sizeof(char)); - return state->M == NULL ? -1 : 0; + long x; + state->r = spec->bitrate; + state->n = spec->output; + state->c = spec->capacity; + state->b = state->r + state->c; + state->w = x = state->b / 25; + state->l = 0; + if (x & 0xF0L) state->l |= 4, x >>= 4; + if (x & 0x0CL) state->l |= 2, x >>= 2; + if (x & 0x02L) state->l |= 1; + state->nr = 12 + (state->l << 1); + state->wmod = (state->w == 64) ? ~0LL : (int64_t)((1ULL << state->w) - 1); + for (x = 0; x < 25; x++) + state->S[x] = 0; + state->mptr = 0; + state->mlen = (size_t)(state->r * state->b) >> 2; + state->M = malloc(state->mlen * sizeof(char)); + return state->M == NULL ? -1 : 0; } @@ -57,12 +41,13 @@ int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkecca * * @param state The state that should be wipe */ -void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state) +void +libkeccak_state_wipe_message(volatile libkeccak_state_t *restrict state) { - volatile char* restrict M = state->M; - size_t i; - for (i = 0; i < state->mptr; i++) - M[i] = 0; + volatile char *restrict M = state->M; + size_t i; + for (i = 0; i < state->mptr; i++) + M[i] = 0; } /** @@ -70,12 +55,13 @@ void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state) * * @param state The state that should be wipe */ -void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state) +void +libkeccak_state_wipe_sponge(volatile libkeccak_state_t *restrict state) { - volatile int64_t* restrict S = state->S; - size_t i; - for (i = 0; i < 25; i++) - S[i] = 0; + volatile int64_t *restrict S = state->S; + size_t i; + for (i = 0; i < 25; i++) + S[i] = 0; } /** @@ -83,10 +69,11 @@ void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state) * * @param state The state that should be wipe */ -void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state) +void +libkeccak_state_wipe(volatile libkeccak_state_t *restrict state) { - libkeccak_state_wipe_message(state); - libkeccak_state_wipe_sponge(state); + libkeccak_state_wipe_message(state); + libkeccak_state_wipe_sponge(state); } @@ -97,14 +84,15 @@ void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state) * @param src The state to duplicate * @return Zero on success, -1 on error */ -int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state_t* restrict src) +int +libkeccak_state_copy(libkeccak_state_t *restrict dest, const libkeccak_state_t *restrict src) { - memcpy(dest, src, sizeof(libkeccak_state_t)); - dest->M = malloc(src->mlen * sizeof(char)); - if (dest->M == NULL) - return -1; - memcpy(dest->M, src->M, src->mptr * sizeof(char)); - return 0; + memcpy(dest, src, sizeof(libkeccak_state_t)); + dest->M = malloc(src->mlen * sizeof(char)); + if (!dest->M) + return -1; + memcpy(dest->M, src->M, src->mptr * sizeof(char)); + return 0; } @@ -115,24 +103,25 @@ int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state * @param data The output buffer * @return The number of bytes stored to `data` */ -size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* restrict data) +size_t +libkeccak_state_marshal(const libkeccak_state_t *restrict state, char *restrict data) { -#define set(type, var) *((type*)data) = state->var, data += sizeof(type) / sizeof(char) - set(long, r); - set(long, c); - set(long, n); - set(long, b); - set(long, w); - set(int64_t, wmod); - set(long, l); - set(long, nr); - memcpy(data, state->S, sizeof(state->S)); - data += sizeof(state->S) / sizeof(char); - set(size_t, mptr); - set(size_t, mlen); - memcpy(data, state->M, state->mptr * sizeof(char)); - data += state->mptr; - return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); +#define set(type, var) *((type *)data) = state->var, data += sizeof(type) / sizeof(char) + set(long, r); + set(long, c); + set(long, n); + set(long, b); + set(long, w); + set(int64_t, wmod); + set(long, l); + set(long, nr); + memcpy(data, state->S, sizeof(state->S)); + data += sizeof(state->S) / sizeof(char); + set(size_t, mptr); + set(size_t, mlen); + memcpy(data, state->M, state->mptr * sizeof(char)); + data += state->mptr; + return sizeof(libkeccak_state_t) - sizeof(char *) + state->mptr * sizeof(char); #undef set } @@ -144,27 +133,28 @@ size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* re * @param data The input buffer * @return The number of bytes read from `data`, 0 on error */ -size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* restrict data) +size_t +libkeccak_state_unmarshal(libkeccak_state_t *restrict state, const char *restrict data) { -#define get(type, var) state->var = *((const type*)data), data += sizeof(type) / sizeof(char) - get(long, r); - get(long, c); - get(long, n); - get(long, b); - get(long, w); - get(int64_t, wmod); - get(long, l); - get(long, nr); - memcpy(state->S, data, sizeof(state->S)); - data += sizeof(state->S) / sizeof(char); - get(size_t, mptr); - get(size_t, mlen); - state->M = malloc(state->mptr * sizeof(char)); - if (state->M == NULL) - return 0; - memcpy(state->M, data, state->mptr * sizeof(char)); - data += state->mptr; - return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); +#define get(type, var) state->var = *((const type *)data), data += sizeof(type) / sizeof(char) + get(long, r); + get(long, c); + get(long, n); + get(long, b); + get(long, w); + get(int64_t, wmod); + get(long, l); + get(long, nr); + memcpy(state->S, data, sizeof(state->S)); + data += sizeof(state->S) / sizeof(char); + get(size_t, mptr); + get(size_t, mlen); + state->M = malloc(state->mptr * sizeof(char)); + if (!state->M) + return 0; + memcpy(state->M, data, state->mptr * sizeof(char)); + data += state->mptr; + return sizeof(libkeccak_state_t) - sizeof(char *) + state->mptr * sizeof(char); #undef get } @@ -176,9 +166,10 @@ size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* * @param data The data buffer * @return The byte size of the stored state */ -size_t libkeccak_state_unmarshal_skip(const char* restrict data) +size_t +libkeccak_state_unmarshal_skip(const char *restrict data) { - data += (7 * sizeof(long) + 26 * sizeof(int64_t)) / sizeof(char); - return sizeof(libkeccak_state_t) - sizeof(char*) + *(const size_t*)data * sizeof(char); + data += (7 * sizeof(long) + 26 * sizeof(int64_t)) / sizeof(char); + return sizeof(libkeccak_state_t) - sizeof(char *) + *(const size_t *)data * sizeof(char); } diff --git a/src/libkeccak/state.h b/src/libkeccak/state.h index f030664..1c4b24e 100644 --- a/src/libkeccak/state.h +++ b/src/libkeccak/state.h @@ -1,32 +1,14 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_STATE_H -#define LIBKECCAK_STATE_H 1 - +#define LIBKECCAK_STATE_H 1 #include "spec.h" #include "internal.h" +#include <errno.h> #include <stddef.h> #include <stdint.h> #include <stdlib.h> -#include <errno.h> #include <string.h> @@ -36,68 +18,67 @@ * * The `char`-size of the output hashsum is calculated by `(.n + 7) / 8` */ -typedef struct libkeccak_state -{ - /** - * The lanes (state/sponge) - */ - int64_t S[25]; - - /** - * The bitrate - */ - long r; - - /** - * The capacity - */ - long c; - - /** - * The output size - */ - long n; - - /** - * The state size - */ - long b; - - /** - * The word size - */ - long w; - - /** - * The word mask - */ - int64_t wmod; - - /** - * ℓ, the binary logarithm of the word size - */ - long l; - - /** - * 12 + 2ℓ, the number of rounds - */ - long nr; - - /** - * Pointer for `M` - */ - size_t mptr; - - /** - * Size of `M` - */ - size_t mlen; - - /** - * Left over water to fill the sponge with at next update - */ - char* M; - +typedef struct libkeccak_state { + /** + * The lanes (state/sponge) + */ + int64_t S[25]; + + /** + * The bitrate + */ + long r; + + /** + * The capacity + */ + long c; + + /** + * The output size + */ + long n; + + /** + * The state size + */ + long b; + + /** + * The word size + */ + long w; + + /** + * The word mask + */ + int64_t wmod; + + /** + * ℓ, the binary logarithm of the word size + */ + long l; + + /** + * 12 + 2ℓ, the number of rounds + */ + long nr; + + /** + * Pointer for `M` + */ + size_t mptr; + + /** + * Size of `M` + */ + size_t mlen; + + /** + * Left over water to fill the sponge with at next update + */ + char *M; + } libkeccak_state_t; @@ -110,7 +91,7 @@ typedef struct libkeccak_state * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull))) -int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkeccak_spec_t* restrict spec); +int libkeccak_state_initialise(libkeccak_state_t *restrict state, const libkeccak_spec_t *restrict spec); /** @@ -119,11 +100,11 @@ int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkecca * @param state The state that should be reset */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused))) -static inline -void libkeccak_state_reset(libkeccak_state_t* restrict state) +static inline void +libkeccak_state_reset(libkeccak_state_t *restrict state) { - state->mptr = 0; - memset(state->S, 0, sizeof(state->S)); + state->mptr = 0; + memset(state->S, 0, sizeof(state->S)); } @@ -132,13 +113,13 @@ void libkeccak_state_reset(libkeccak_state_t* restrict state) * * @param state The state that should be destroyed */ -static inline -void libkeccak_state_fast_destroy(libkeccak_state_t* restrict state) +static inline void +libkeccak_state_fast_destroy(libkeccak_state_t *restrict state) { - if (state == NULL) - return; - free(state->M); - state->M = NULL; + if (state == NULL) + return; + free(state->M); + state->M = NULL; } @@ -148,7 +129,7 @@ void libkeccak_state_fast_destroy(libkeccak_state_t* restrict state) * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow, optimize("-O0")))) -void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state); +void libkeccak_state_wipe_message(volatile libkeccak_state_t *restrict state); /** * Wipe data in the state's sponge wihout freeing any data @@ -156,7 +137,7 @@ void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state); * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow, optimize("-O0")))) -void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state); +void libkeccak_state_wipe_sponge(volatile libkeccak_state_t *restrict state); /** * Wipe sensitive data wihout freeing any data @@ -164,7 +145,7 @@ void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state); * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, optimize("-O0")))) -void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state); +void libkeccak_state_wipe(volatile libkeccak_state_t *restrict state); /** @@ -173,14 +154,14 @@ void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state); * @param state The state that should be destroyed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_state_destroy(volatile libkeccak_state_t* restrict state) +static inline void +libkeccak_state_destroy(volatile libkeccak_state_t *restrict state) { - if (state == NULL) - return; - libkeccak_state_wipe(state); - free(state->M); - state->M = NULL; + if (!state) + return; + libkeccak_state_wipe(state); + free(state->M); + state->M = NULL; } @@ -191,14 +172,13 @@ void libkeccak_state_destroy(volatile libkeccak_state_t* restrict state) * @return The state, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_state_t* libkeccak_state_create(const libkeccak_spec_t* restrict spec) +static inline libkeccak_state_t * +libkeccak_state_create(const libkeccak_spec_t *restrict spec) { - libkeccak_state_t* restrict state = malloc(sizeof(libkeccak_state_t)); - int saved_errno; - if ((state == NULL) || libkeccak_state_initialise(state, spec)) - return saved_errno = errno, free(state), errno = saved_errno, NULL; - return state; + libkeccak_state_t *restrict state = malloc(sizeof(libkeccak_state_t)); + if (!state || libkeccak_state_initialise(state, spec)) + return free(state), NULL; + return state; } @@ -208,11 +188,11 @@ libkeccak_state_t* libkeccak_state_create(const libkeccak_spec_t* restrict spec) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused))) -static inline -void libkeccak_state_fast_free(libkeccak_state_t* restrict state) +static inline void +libkeccak_state_fast_free(libkeccak_state_t *restrict state) { - libkeccak_state_fast_destroy(state); - free(state); + libkeccak_state_fast_destroy(state); + free(state); } @@ -222,15 +202,15 @@ void libkeccak_state_fast_free(libkeccak_state_t* restrict state) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_state_free(volatile libkeccak_state_t* restrict state) +static inline void +libkeccak_state_free(volatile libkeccak_state_t *restrict state) { #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wcast-qual" #endif - libkeccak_state_destroy(state); - free((libkeccak_state_t*)state); + libkeccak_state_destroy(state); + free((libkeccak_state_t *)state); #ifdef __GNUC__ # pragma GCC diagnostic pop #endif @@ -245,7 +225,7 @@ void libkeccak_state_free(volatile libkeccak_state_t* restrict state) * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull))) -int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state_t* restrict src); +int libkeccak_state_copy(libkeccak_state_t *restrict dest, const libkeccak_state_t *restrict src); /** @@ -255,14 +235,13 @@ int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state * @return The duplicate, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_state_t* libkeccak_state_duplicate(const libkeccak_state_t* restrict src) +static inline libkeccak_state_t * +libkeccak_state_duplicate(const libkeccak_state_t *restrict src) { - libkeccak_state_t* restrict dest = malloc(sizeof(libkeccak_state_t)); - int saved_errno; - if ((dest == NULL) || libkeccak_state_copy(dest, src)) - return saved_errno = errno, libkeccak_state_free(dest), errno = saved_errno, NULL; - return dest; + libkeccak_state_t *restrict dest = malloc(sizeof(libkeccak_state_t)); + if (!dest || libkeccak_state_copy(dest, src)) + return libkeccak_state_free(dest), NULL; + return dest; } @@ -274,10 +253,10 @@ libkeccak_state_t* libkeccak_state_duplicate(const libkeccak_state_t* restrict s * @return The allocation size needed for the buffer to which the state will be marshalled */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused, warn_unused_result, pure))) -static inline -size_t libkeccak_state_marshal_size(const libkeccak_state_t* restrict state) +static inline size_t +libkeccak_state_marshal_size(const libkeccak_state_t *restrict state) { - return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); + return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); } @@ -289,7 +268,7 @@ size_t libkeccak_state_marshal_size(const libkeccak_state_t* restrict state) * @return The number of bytes stored to `data` */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* restrict data); +size_t libkeccak_state_marshal(const libkeccak_state_t *restrict state, char *restrict data); /** @@ -300,7 +279,7 @@ size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* re * @return The number of bytes read from `data`, 0 on error */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull))) -size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* restrict data); +size_t libkeccak_state_unmarshal(libkeccak_state_t *restrict state, const char *restrict data); /** @@ -311,8 +290,6 @@ size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* * @return The byte size of the stored state */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow, warn_unused_result, pure))) -size_t libkeccak_state_unmarshal_skip(const char* restrict data); - +size_t libkeccak_state_unmarshal_skip(const char *restrict data); #endif - @@ -1,26 +1,9 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015 Mattias Andrée (maandree@member.fsf.org) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include <libkeccak.h> +#include <fcntl.h> #include <stdio.h> #include <string.h> -#include <fcntl.h> #include <unistd.h> @@ -29,43 +12,44 @@ * * @return Zero on success, -1 on error */ -static int test_hex(void) +static int +test_hex(void) { - const unsigned char bindata[] = {0x04, 0x2F, 0x12, 0x83, 0xFF, 0x80, 0xA3, 0x00}; - const char hexdata_upper[] = "042F1283FF80A300"; - const char hexdata_lower[] = "042f1283ff80a300"; - char hextest[2 * 8 + 1]; - - printf("Testing libkeccak_behex_lower: "); - libkeccak_behex_lower(hextest, (const char*)bindata, 8); - if (!strcmp(hextest, hexdata_lower)) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("Testing libkeccak_behex_upper: "); - libkeccak_behex_upper(hextest, (const char*)bindata, 8); - if (!strcmp(hextest, hexdata_upper)) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("Testing libkeccak_unhex on uppercase: "); - libkeccak_unhex(hextest, hexdata_upper); - if (!memcmp(bindata, hextest, 8 * sizeof(char))) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("Testing libkeccak_unhex on lowercase: "); - libkeccak_unhex(hextest, hexdata_lower); - if (!memcmp(bindata, hextest, 8 * sizeof(char))) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("\n"); - return 0; + const unsigned char bindata[] = {0x04, 0x2F, 0x12, 0x83, 0xFF, 0x80, 0xA3, 0x00}; + const char hexdata_upper[] = "042F1283FF80A300"; + const char hexdata_lower[] = "042f1283ff80a300"; + char hextest[2 * 8 + 1]; + + printf("Testing libkeccak_behex_lower: "); + libkeccak_behex_lower(hextest, (const char*)bindata, 8); + if (!strcmp(hextest, hexdata_lower)) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("Testing libkeccak_behex_upper: "); + libkeccak_behex_upper(hextest, (const char*)bindata, 8); + if (!strcmp(hextest, hexdata_upper)) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("Testing libkeccak_unhex on uppercase: "); + libkeccak_unhex(hextest, hexdata_upper); + if (!memcmp(bindata, hextest, 8 * sizeof(char))) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("Testing libkeccak_unhex on lowercase: "); + libkeccak_unhex(hextest, hexdata_lower); + if (!memcmp(bindata, hextest, 8 * sizeof(char))) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("\n"); + return 0; } @@ -75,54 +59,55 @@ static int test_hex(void) * @param spec The specifications for the state * @return Zero on success, -1 on error */ -static int test_state(libkeccak_spec_t* restrict spec) +static int +test_state(libkeccak_spec_t *restrict spec) { - libkeccak_state_t* restrict state; - libkeccak_state_t* restrict state2; - size_t marshal_size, marshalled_size, i, n; - char* restrict marshalled_data; - - if (state = libkeccak_state_create(spec), state == NULL) - return perror("libkeccak_state_initialise"), -1; - - n = state->mlen / 2; - for (i = 0; i < n; i++) - state->M[state->mptr++] = (char)(i & 255); - - if (state2 = libkeccak_state_duplicate(state), state2 == NULL) - return perror("libkeccak_state_duplicate"), -1; - - if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) - return printf("Inconsistency found between original state and duplicate state.\n"), -1; - - marshal_size = libkeccak_state_marshal_size(state2); - if (marshalled_data = malloc(marshal_size), marshalled_data == NULL) - return perror("malloc"), -1; - - marshalled_size = libkeccak_state_marshal(state2, marshalled_data); - if (marshalled_size != marshal_size) - return printf("libkeccak_state_marshal returned an unexpected value.\n"), -1; - - libkeccak_state_free(state); - - if (state = malloc(sizeof(libkeccak_state_t)), state == NULL) - return perror("malloc"), -1; - marshalled_size = libkeccak_state_unmarshal(state, marshalled_data); - if (marshalled_size == 0) - return perror("libkeccak_state_unmarshal"), -1; - if (marshalled_size != marshal_size) - return printf("libkeccak_state_unmarshal returned an unexpected value.\n"), -1; - - if (libkeccak_state_unmarshal_skip(marshalled_data) != marshal_size) - return printf("libkeccak_state_unmarshal_skip returned an unexpected value.\n"), -1; - - if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) - return printf("Inconsistency found between original state and unmarshalled state.\n"), -1; + libkeccak_state_t *restrict state; + libkeccak_state_t *restrict state2; + size_t marshal_size, marshalled_size, i, n; + char *restrict marshalled_data; + + if (state = libkeccak_state_create(spec), state == NULL) + return perror("libkeccak_state_initialise"), -1; + + n = state->mlen / 2; + for (i = 0; i < n; i++) + state->M[state->mptr++] = (char)(i & 255); - free(marshalled_data); - libkeccak_state_free(state); - libkeccak_state_free(state2); - return 0; + if (state2 = libkeccak_state_duplicate(state), state2 == NULL) + return perror("libkeccak_state_duplicate"), -1; + + if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) + return printf("Inconsistency found between original state and duplicate state.\n"), -1; + + marshal_size = libkeccak_state_marshal_size(state2); + if (marshalled_data = malloc(marshal_size), marshalled_data == NULL) + return perror("malloc"), -1; + + marshalled_size = libkeccak_state_marshal(state2, marshalled_data); + if (marshalled_size != marshal_size) + return printf("libkeccak_state_marshal returned an unexpected value.\n"), -1; + + libkeccak_state_free(state); + + if (state = malloc(sizeof(libkeccak_state_t)), state == NULL) + return perror("malloc"), -1; + marshalled_size = libkeccak_state_unmarshal(state, marshalled_data); + if (marshalled_size == 0) + return perror("libkeccak_state_unmarshal"), -1; + if (marshalled_size != marshal_size) + return printf("libkeccak_state_unmarshal returned an unexpected value.\n"), -1; + + if (libkeccak_state_unmarshal_skip(marshalled_data) != marshal_size) + return printf("libkeccak_state_unmarshal_skip returned an unexpected value.\n"), -1; + + if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) + return printf("Inconsistency found between original state and unmarshalled state.\n"), -1; + + free(marshalled_data); + libkeccak_state_free(state); + libkeccak_state_free(state2); + return 0; } @@ -136,35 +121,36 @@ static int test_state(libkeccak_spec_t* restrict spec) * @param expected_answer The expected answer, must be lowercase * @return Zero on success, -1 on error */ -static int test_digest_case(const libkeccak_spec_t* restrict spec, const char* restrict suffix, - const char* restrict msg, long bits, const char* restrict expected_answer) +static int +test_digest_case(const libkeccak_spec_t *restrict spec, const char *restrict suffix, + const char *restrict msg, long bits, const char *restrict expected_answer) { - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - int ok; - - if (libkeccak_state_initialise(&state, spec)) - return perror("libkeccak_state_initialise"), -1; - if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - - if (libkeccak_digest(&state, msg, strlen(msg) - !!bits, bits, suffix, hashsum)) - return perror("libkeccak_digest"), -1; - libkeccak_state_fast_destroy(&state); - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - free(hashsum); - free(hexsum); - - return ok - 1; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + int ok; + + if (libkeccak_state_initialise(&state, spec)) + return perror("libkeccak_state_initialise"), -1; + if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + + if (libkeccak_digest(&state, msg, strlen(msg) - !!bits, bits, suffix, hashsum)) + return perror("libkeccak_digest"), -1; + libkeccak_state_fast_destroy(&state); + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + free(hashsum); + free(hexsum); + + return ok - 1; } @@ -175,192 +161,198 @@ static int test_digest_case(const libkeccak_spec_t* restrict spec, const char* r */ static int test_digest(void) { -#define sha3(output, message) \ - (printf(" Testing SHA3-"#output"(%s): ", #message), \ - libkeccak_spec_sha3(&spec, output), \ - test_digest_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, 0, answer)) -#define keccak(output, message) \ - (printf(" Testing Keccak-"#output"(%s): ", #message), \ - libkeccak_spec_sha3(&spec, output) /* sic! */, \ - test_digest_case(&spec, "", message, 0, answer)) -#define keccak_bits(output, message, bits) \ - (printf(" Testing Keccak-"#output"(%s-%i): ", #message, bits), \ - libkeccak_spec_sha3(&spec, output) /* sic! */, \ - test_digest_case(&spec, "", message, bits, answer)) -#define rawshake(semicapacity, output, message) \ - (printf(" Testing RawSHAKE-"#semicapacity"(%s, %i): ", #message, output), \ - libkeccak_spec_rawshake(&spec, semicapacity, output), \ - test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, 0, answer)) -#define rawshake_bits(semicapacity, output, message, bits) \ - (printf(" Testing RawSHAKE-"#semicapacity"(%s-%i, %i): ", #message, bits, output), \ - libkeccak_spec_rawshake(&spec, semicapacity, output), \ - test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, bits, answer)) -#define shake(semicapacity, output, message) \ - (printf(" Testing SHAKE-"#semicapacity"(%s, %i): ", #message, output), \ - libkeccak_spec_shake(&spec, semicapacity, output), \ - test_digest_case(&spec, LIBKECCAK_SHAKE_SUFFIX, message, 0, answer)) -#define keccak_g(b, c, o, message) \ - (printf(" Testing Keccak[%i,%i,%i](%s): ", b, c, o, #message), \ - spec.bitrate = b, spec.capacity = c, spec.output = o, \ - test_digest_case(&spec, "", message, 0, answer)) - - - libkeccak_spec_t spec; - const char* answer; - - printf("Testing libkeccak_digest:\n"); - - - answer = "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"; - if (sha3(224, "")) return -1; - - answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; - if (sha3(256, "")) return -1; - - answer = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; - if (sha3(384, "")) return -1; - - answer = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6" - "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; - if (sha3(512, "")) return -1; - - - answer = "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"; - if (keccak(224, "")) return -1; - - answer = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"; - if (keccak(256, "")) return -1; - - answer = "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff"; - if (keccak(384, "")) return -1; - - answer = "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304" - "c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e"; - if (keccak(512, "")) return -1; - - - answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; - if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; - - answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; - if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; - - answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; - if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; - - answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; - if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; - - answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; - if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; - - answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; - if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; - - answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; - if (sha3(224, "chevalier slat's spindel representations")) return -1; - - answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; - if (sha3(224, "archery lexicographical equine veered")) return -1; - - answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; - if (sha3(224, "splay washbasin opposing there")) return -1; - - answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; - if (sha3(224, "faktum desist thundered klen")) return -1; - - - answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; - if (keccak_bits(256, "\x02", 2)) return -1; - - answer = "3a1108d4a90a31b85a10bdce77f4bfbdcc5b1d70dd405686f8bbde834aa1a410"; - if (keccak_bits(256, "\x03", 2)) return -1; - - answer = "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"; - if (keccak_bits(256, "\x0F", 4)) return -1; - - - answer = "3a1108d4a90a31b85a10bdce77f4bfbd"; - if (rawshake(256, 128, "")) return -1; - - answer = "46b9dd2b0ba88d13233b3feb743eeb24"; - if (rawshake_bits(256, 128, "\x03", 2)) return -1; - - answer = "46b9dd2b0ba88d13233b3feb743eeb24"; - if (shake(256, 128, "")) return -1; - - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6"; - if (keccak_g(1024, 1600 - 1024, 576, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5d"; - if (keccak_g(1024, 1600 - 1024, 1024, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" - "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" - "3478934b00aa6cd44aa7ae2cd0271d83fbab699b"; - if (keccak_g(1024, 1600 - 1024, 1600, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" - "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" - "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c"; - if (keccak_g(1024, 1600 - 1024, 1608, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" - "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" - "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c58351bf7d26586b9c32282f1ac6356" - "1981b79791d7ab2b6e01f5b8e6cf0cab8b2076fd82bd99df015a602cdda5684162fea982" - "0f5a441c4620f549fbaf4e818201f292dbf4f6c9f82af8aa80b4124984da6f65b2874e0e" - "f01d042c08e9aedbb6ce4c10526e38c1a4e8b108c4f14b066f9d42640687b55124b081da" - "a9f9ae4232f313740b4fb787545dc19e7778f7082b3fa5824d2400c012be1a6c5ade7149" - "e452d310752fa9ebb964ab36fde0c8f46f47a0e2c9b20f24e3cca904bbedaa7ea176f662" - "33cd2d95"; - if (keccak_g(1024, 1600 - 1024, 3200, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de9225351"; - if (keccak_g(1024, 1600 - 1024, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "e6f86ebc15b962f73f36f36fc8a84c3ae84b1c1023bfd4c5f1829389135aecc3"; - if (keccak_g(512, 1600 - 512, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "420b97fc88962c87ec2adaa8f48d74d9ff4ea7ae7d691f9c33b8713ca1d3d573"; - if (keccak_g(256, 1600 - 256, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "524790afbe4706d938b6f753e14104f556890e2a415e211b0564d60499db0333"; - if (keccak_g(512, 800 - 512, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "04a6b4ad08b3018eefba0fb756272d949ac0f71c26f836d31dd13b28b884aa0f"; - if (keccak_g(256, 800 - 256, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "d56f547791225e54460e6274ed31e57b7085820c11d65f1f322a16a3352c85ed"; - if (keccak_g(256, 400 - 256, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "ceec066a57b9b31a5a0661df7bafec4183a26d0ed81e50bc958471f84fa347a7"; - if (keccak_g(128, 400 - 128, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "b18f679c7105a72a993f70fa5adb3f17ef7ccffaffb4dc0f6fed74aa2f565194"; - if (keccak_g(128, 200 - 128, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "9b845c1ecc2b1b3a48ba42ef29ccc4b348da8ab15074a870d8e799ca33c15e4b"; - if (keccak_g(64, 200 - 64, 256, "capitol's kvistfri broadly raping")) return -1; - - - printf("\n"); - return 0; - +#define sha3(output, message)\ + (printf(" Testing SHA3-"#output"(%s): ", #message),\ + libkeccak_spec_sha3(&spec, output),\ + test_digest_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, 0, answer)) + +#define keccak(output, message)\ + (printf(" Testing Keccak-"#output"(%s): ", #message),\ + libkeccak_spec_sha3(&spec, output) /* sic! */,\ + test_digest_case(&spec, "", message, 0, answer)) + +#define keccak_bits(output, message, bits)\ + (printf(" Testing Keccak-"#output"(%s-%i): ", #message, bits),\ + libkeccak_spec_sha3(&spec, output) /* sic! */,\ + test_digest_case(&spec, "", message, bits, answer)) + +#define rawshake(semicapacity, output, message)\ + (printf(" Testing RawSHAKE-"#semicapacity"(%s, %i): ", #message, output),\ + libkeccak_spec_rawshake(&spec, semicapacity, output),\ + test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, 0, answer)) + +#define rawshake_bits(semicapacity, output, message, bits)\ + (printf(" Testing RawSHAKE-"#semicapacity"(%s-%i, %i): ", #message, bits, output),\ + libkeccak_spec_rawshake(&spec, semicapacity, output),\ + test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, bits, answer)) + +#define shake(semicapacity, output, message)\ + (printf(" Testing SHAKE-"#semicapacity"(%s, %i): ", #message, output),\ + libkeccak_spec_shake(&spec, semicapacity, output),\ + test_digest_case(&spec, LIBKECCAK_SHAKE_SUFFIX, message, 0, answer)) + +#define keccak_g(b, c, o, message)\ + (printf(" Testing Keccak[%i,%i,%i](%s): ", b, c, o, #message),\ + spec.bitrate = b, spec.capacity = c, spec.output = o,\ + test_digest_case(&spec, "", message, 0, answer)) + + + libkeccak_spec_t spec; + const char *answer; + + printf("Testing libkeccak_digest:\n"); + + + answer = "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"; + if (sha3(224, "")) return -1; + + answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; + if (sha3(256, "")) return -1; + + answer = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; + if (sha3(384, "")) return -1; + + answer = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6" + "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; + if (sha3(512, "")) return -1; + + + answer = "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"; + if (keccak(224, "")) return -1; + + answer = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"; + if (keccak(256, "")) return -1; + + answer = "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff"; + if (keccak(384, "")) return -1; + + answer = "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304" + "c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e"; + if (keccak(512, "")) return -1; + + + answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; + if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; + + answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; + if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; + + answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; + if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; + + answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; + if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; + + answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; + if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; + + answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; + if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; + + answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; + if (sha3(224, "chevalier slat's spindel representations")) return -1; + + answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; + if (sha3(224, "archery lexicographical equine veered")) return -1; + + answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; + if (sha3(224, "splay washbasin opposing there")) return -1; + + answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; + if (sha3(224, "faktum desist thundered klen")) return -1; + + + answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; + if (keccak_bits(256, "\x02", 2)) return -1; + + answer = "3a1108d4a90a31b85a10bdce77f4bfbdcc5b1d70dd405686f8bbde834aa1a410"; + if (keccak_bits(256, "\x03", 2)) return -1; + + answer = "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"; + if (keccak_bits(256, "\x0F", 4)) return -1; + + + answer = "3a1108d4a90a31b85a10bdce77f4bfbd"; + if (rawshake(256, 128, "")) return -1; + + answer = "46b9dd2b0ba88d13233b3feb743eeb24"; + if (rawshake_bits(256, 128, "\x03", 2)) return -1; + + answer = "46b9dd2b0ba88d13233b3feb743eeb24"; + if (shake(256, 128, "")) return -1; + + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6"; + if (keccak_g(1024, 1600 - 1024, 576, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5d"; + if (keccak_g(1024, 1600 - 1024, 1024, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" + "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" + "3478934b00aa6cd44aa7ae2cd0271d83fbab699b"; + if (keccak_g(1024, 1600 - 1024, 1600, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" + "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" + "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c"; + if (keccak_g(1024, 1600 - 1024, 1608, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" + "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" + "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c58351bf7d26586b9c32282f1ac6356" + "1981b79791d7ab2b6e01f5b8e6cf0cab8b2076fd82bd99df015a602cdda5684162fea982" + "0f5a441c4620f549fbaf4e818201f292dbf4f6c9f82af8aa80b4124984da6f65b2874e0e" + "f01d042c08e9aedbb6ce4c10526e38c1a4e8b108c4f14b066f9d42640687b55124b081da" + "a9f9ae4232f313740b4fb787545dc19e7778f7082b3fa5824d2400c012be1a6c5ade7149" + "e452d310752fa9ebb964ab36fde0c8f46f47a0e2c9b20f24e3cca904bbedaa7ea176f662" + "33cd2d95"; + if (keccak_g(1024, 1600 - 1024, 3200, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de9225351"; + if (keccak_g(1024, 1600 - 1024, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "e6f86ebc15b962f73f36f36fc8a84c3ae84b1c1023bfd4c5f1829389135aecc3"; + if (keccak_g(512, 1600 - 512, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "420b97fc88962c87ec2adaa8f48d74d9ff4ea7ae7d691f9c33b8713ca1d3d573"; + if (keccak_g(256, 1600 - 256, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "524790afbe4706d938b6f753e14104f556890e2a415e211b0564d60499db0333"; + if (keccak_g(512, 800 - 512, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "04a6b4ad08b3018eefba0fb756272d949ac0f71c26f836d31dd13b28b884aa0f"; + if (keccak_g(256, 800 - 256, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "d56f547791225e54460e6274ed31e57b7085820c11d65f1f322a16a3352c85ed"; + if (keccak_g(256, 400 - 256, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "ceec066a57b9b31a5a0661df7bafec4183a26d0ed81e50bc958471f84fa347a7"; + if (keccak_g(128, 400 - 128, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "b18f679c7105a72a993f70fa5adb3f17ef7ccffaffb4dc0f6fed74aa2f565194"; + if (keccak_g(128, 200 - 128, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "9b845c1ecc2b1b3a48ba42ef29ccc4b348da8ab15074a870d8e799ca33c15e4b"; + if (keccak_g(64, 200 - 64, 256, "capitol's kvistfri broadly raping")) return -1; + + + printf("\n"); + return 0; + #undef keccak_g #undef shake #undef rawshake_bits @@ -380,37 +372,38 @@ static int test_digest(void) * @param expected_answer The expected answer, must be lowercase * @return Zero on success, -1 on error */ -static int test_update_case(const libkeccak_spec_t* restrict spec, const char* restrict suffix, - const char* restrict msg, const char* restrict expected_answer) +static int +test_update_case(const libkeccak_spec_t *restrict spec, const char *restrict suffix, + const char *restrict msg, const char *restrict expected_answer) { - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - int ok; - - if (libkeccak_state_initialise(&state, spec)) - return perror("libkeccak_state_initialise"), -1; - if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - - if (libkeccak_update(&state, msg, strlen(msg))) - return perror("libkeccak_update"), -1; - if (libkeccak_digest(&state, NULL, 0, 0, suffix, hashsum)) - return perror("libkeccak_digest"), -1; - libkeccak_state_fast_destroy(&state); - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - free(hashsum); - free(hexsum); - - return ok - 1; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + int ok; + + if (libkeccak_state_initialise(&state, spec)) + return perror("libkeccak_state_initialise"), -1; + if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + + if (libkeccak_update(&state, msg, strlen(msg))) + return perror("libkeccak_update"), -1; + if (libkeccak_digest(&state, NULL, 0, 0, suffix, hashsum)) + return perror("libkeccak_digest"), -1; + libkeccak_state_fast_destroy(&state); + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + free(hashsum); + free(hexsum); + + return ok - 1; } @@ -421,51 +414,51 @@ static int test_update_case(const libkeccak_spec_t* restrict spec, const char* r */ static int test_update(void) { -#define sha3(output, message) \ - (printf(" Testing SHA3-"#output"(%s): ", #message), \ - libkeccak_spec_sha3(&spec, output), \ - test_update_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, answer)) - - libkeccak_spec_t spec; - const char* answer; - - printf("Testing libkeccak_update:\n"); - - - answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; - if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; - - answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; - if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; - - answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; - if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; - - answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; - if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; - - answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; - if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; - - answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; - if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; - - answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; - if (sha3(224, "chevalier slat's spindel representations")) return -1; - - answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; - if (sha3(224, "archery lexicographical equine veered")) return -1; - - answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; - if (sha3(224, "splay washbasin opposing there")) return -1; - - answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; - if (sha3(224, "faktum desist thundered klen")) return -1; - - - printf("\n"); - return 0; - +#define sha3(output, message)\ + (printf(" Testing SHA3-"#output"(%s): ", #message),\ + libkeccak_spec_sha3(&spec, output),\ + test_update_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, answer)) + + libkeccak_spec_t spec; + const char* answer; + + printf("Testing libkeccak_update:\n"); + + + answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; + if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; + + answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; + if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; + + answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; + if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; + + answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; + if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; + + answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; + if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; + + answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; + if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; + + answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; + if (sha3(224, "chevalier slat's spindel representations")) return -1; + + answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; + if (sha3(224, "archery lexicographical equine veered")) return -1; + + answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; + if (sha3(224, "splay washbasin opposing there")) return -1; + + answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; + if (sha3(224, "faktum desist thundered klen")) return -1; + + + printf("\n"); + return 0; + #undef sha3 } @@ -483,29 +476,29 @@ static int test_update(void) * @param expected_answer The hashum we expect, must be in lowercase hexadecimal * @return Zero on success, -1 on error */ -static int test_squeeze_case(libkeccak_state_t* restrict state, const libkeccak_spec_t* restrict spec, - long fast_squeezes, long squeezes, int fast_digest, char* restrict hashsum, - char* restrict hexsum, const char* restrict expected_answer) +static int test_squeeze_case(libkeccak_state_t *restrict state, const libkeccak_spec_t *restrict spec, + long fast_squeezes, long squeezes, int fast_digest, char* restrict hashsum, + char *restrict hexsum, const char *restrict expected_answer) { -#define message "withdrew hypothesis snakebird qmc2" - long i; - int ok; - - libkeccak_state_reset(state); - if (libkeccak_digest(state, message, strlen(message), 0, LIBKECCAK_SHA3_SUFFIX, fast_digest ? NULL : hashsum)) - return perror("libkeccak_digest"), -1; - - libkeccak_fast_squeeze(state, fast_squeezes); - for (i = fast_squeezes; i < squeezes; i++) - libkeccak_squeeze(state, hashsum); - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - return ok - 1; +#define message "withdrew hypothesis snakebird qmc2" + long i; + int ok; + + libkeccak_state_reset(state); + if (libkeccak_digest(state, message, strlen(message), 0, LIBKECCAK_SHA3_SUFFIX, fast_digest ? NULL : hashsum)) + return perror("libkeccak_digest"), -1; + + libkeccak_fast_squeeze(state, fast_squeezes); + for (i = fast_squeezes; i < squeezes; i++) + libkeccak_squeeze(state, hashsum); + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + return ok - 1; #undef message } @@ -515,60 +508,61 @@ static int test_squeeze_case(libkeccak_state_t* restrict state, const libkeccak_ * * @return Zero on success, -1 on error */ -static int test_squeeze(void) +static int +test_squeeze(void) { -#define answer1 "03fe12b4b51d56d96377d927e5cd498fc4bc3aee389b2f2ff8393aa5" -#define answer2 "0b8fb64ee5d8836956f49cbe4577afbc638c855c1d553452fc1eceb8" -#define answer3 "1e03b4cd9eef3892a7b5e865fce393c4bc90120d9aea84d0a0dff3b8" -#define answer4 "aac92fbfd22ce62e83ddaf2e61bd7bf696326e46d1327defa4530e20" - -#define run_test(fast_squeezes, squeezes, fast_digest) \ - test_squeeze_case(&state, &spec, fast_squeezes, squeezes, fast_digest, hashsum, hexsum, answer##squeezes) - - libkeccak_spec_t spec; - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - - libkeccak_spec_sha3(&spec, 224); - if (hashsum = malloc((spec.output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec.output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - if (libkeccak_state_initialise(&state, &spec)) - return perror("libkeccak_state_initialise"), -1; - - printf("Testing squeeze functions with slow initial digest:\n"); - printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 0); - printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 0); - printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 0); - printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 0); - printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 0); - printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 0); - printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 0); - printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 0); - printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 0); - printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 0); - printf("\n"); - - printf("Testing squeeze functions with fast initial digest:\n"); - printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 1); - printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 1); - printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 1); - printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 1); - printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 1); - printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 1); - printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 1); - printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 1); - printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 1); - printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 1); - printf("\n"); - - libkeccak_state_fast_destroy(&state); - free(hashsum); - free(hexsum); - return 0; - +#define answer1 "03fe12b4b51d56d96377d927e5cd498fc4bc3aee389b2f2ff8393aa5" +#define answer2 "0b8fb64ee5d8836956f49cbe4577afbc638c855c1d553452fc1eceb8" +#define answer3 "1e03b4cd9eef3892a7b5e865fce393c4bc90120d9aea84d0a0dff3b8" +#define answer4 "aac92fbfd22ce62e83ddaf2e61bd7bf696326e46d1327defa4530e20" + +#define run_test(fast_squeezes, squeezes, fast_digest)\ + test_squeeze_case(&state, &spec, fast_squeezes, squeezes, fast_digest, hashsum, hexsum, answer##squeezes) + + libkeccak_spec_t spec; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + + libkeccak_spec_sha3(&spec, 224); + if (hashsum = malloc((spec.output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec.output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + if (libkeccak_state_initialise(&state, &spec)) + return perror("libkeccak_state_initialise"), -1; + + printf("Testing squeeze functions with slow initial digest:\n"); + printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 0); + printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 0); + printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 0); + printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 0); + printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 0); + printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 0); + printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 0); + printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 0); + printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 0); + printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 0); + printf("\n"); + + printf("Testing squeeze functions with fast initial digest:\n"); + printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 1); + printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 1); + printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 1); + printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 1); + printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 1); + printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 1); + printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 1); + printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 1); + printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 1); + printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 1); + printf("\n"); + + libkeccak_state_fast_destroy(&state); + free(hashsum); + free(hexsum); + return 0; + #undef run_test #undef answer4 #undef answer3 @@ -587,38 +581,39 @@ static int test_squeeze(void) * @param expected_answer The hashum we expect, must be in lowercase hexadecimal * @return Zero on success, -1 on error */ -static int test_file(const libkeccak_spec_t* restrict spec, const char* restrict suffix, - const char* restrict filename, const char* restrict expected_answer) +static int +test_file(const libkeccak_spec_t *restrict spec, const char *restrict suffix, + const char *restrict filename, const char *restrict expected_answer) { - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - int ok, fd; - - printf("Testing libkeccak_generalised_sum_fd on %s: ", filename); - - if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - - if (fd = open(filename, O_RDONLY), fd < 0) - return perror("open"), -1; - - if (libkeccak_generalised_sum_fd(fd, &state, spec, suffix, hashsum)) - return perror("libkeccak_generalised_sum_fd"), close(fd), -1; - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - close(fd); - free(hashsum); - free(hexsum); - libkeccak_state_fast_destroy(&state); - return ok - 1; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + int ok, fd; + + printf("Testing libkeccak_generalised_sum_fd on %s: ", filename); + + if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + + if (fd = open(filename, O_RDONLY), fd < 0) + return perror("open"), -1; + + if (libkeccak_generalised_sum_fd(fd, &state, spec, suffix, hashsum)) + return perror("libkeccak_generalised_sum_fd"), close(fd), -1; + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + close(fd); + free(hashsum); + free(hexsum); + libkeccak_state_fast_destroy(&state); + return ok - 1; } @@ -629,39 +624,39 @@ static int test_file(const libkeccak_spec_t* restrict spec, const char* restrict * * @return Zero on success, 1 on failure or incorrectness */ -int main(void) +int +main(void) { - libkeccak_generalised_spec_t gspec; - libkeccak_spec_t spec; - - libkeccak_generalised_spec_initialise(&gspec); - if (libkeccak_degeneralise_spec(&gspec, &spec)) - return printf("libkeccak_degeneralise_spec failed with all members at automatic.\n"), 1; - - printf("Resolution of default specification:\n"); - printf(" bitrate: %li\n", gspec.bitrate); - printf(" capacity: %li\n", gspec.capacity); - printf(" output: %li\n", gspec.output); - printf(" state size: %li\n", gspec.state_size); - printf(" word size: %li\n", gspec.word_size); - if (gspec.word_size * 25 != gspec.state_size) return printf("Invalid information\n"), 1; - if (gspec.bitrate + gspec.capacity != gspec.state_size) return printf("Invalid information\n"), 1; - if (gspec.state_size != 1600) return printf("Incorrect information\n"), 1; - if (gspec.bitrate != gspec.output * 2) return printf("Incorrect information\n"), 1; - if (gspec.output != 512) return printf("Incorrect information\n"), 1; - printf("\n"); - - if (test_hex()) return 1; - if (test_state(&spec)) return 1; - if (test_digest()) return 1; - if (test_update()) return 1; - if (test_squeeze()) return 1; - - if (test_file(&spec, LIBKECCAK_SHA3_SUFFIX, "LICENSE", - "68dd720832a594c1986078d2d09ab21d80b9d66d98c52f2679e81699519e2f8a" - "3c970bb9c514206b574a944ffaa6466d546eb17f64f47c01ec053ab4ce35575a")) - return 1; + libkeccak_generalised_spec_t gspec; + libkeccak_spec_t spec; + + libkeccak_generalised_spec_initialise(&gspec); + if (libkeccak_degeneralise_spec(&gspec, &spec)) + return printf("libkeccak_degeneralise_spec failed with all members at automatic.\n"), 1; + + printf("Resolution of default specification:\n"); + printf(" bitrate: %li\n", gspec.bitrate); + printf(" capacity: %li\n", gspec.capacity); + printf(" output: %li\n", gspec.output); + printf(" state size: %li\n", gspec.state_size); + printf(" word size: %li\n", gspec.word_size); + if (gspec.word_size * 25 != gspec.state_size) return printf("Invalid information\n"), 1; + if (gspec.bitrate + gspec.capacity != gspec.state_size) return printf("Invalid information\n"), 1; + if (gspec.state_size != 1600) return printf("Incorrect information\n"), 1; + if (gspec.bitrate != gspec.output * 2) return printf("Incorrect information\n"), 1; + if (gspec.output != 512) return printf("Incorrect information\n"), 1; + printf("\n"); + + if (test_hex()) return 1; + if (test_state(&spec)) return 1; + if (test_digest()) return 1; + if (test_update()) return 1; + if (test_squeeze()) return 1; + + if (test_file(&spec, LIBKECCAK_SHA3_SUFFIX, ".testfile", + "a95484492e9ade0f1d28f872d197ff45d891e85e78f918643f41d524c5d6ab0f" + "17974dc08ec82870b132612dcbeb062213bf594881dc764d6078865a7c694c57")) + return 1; - return 0; + return 0; } - |