tthsum-1.3.1/CHANGES.txt0000664000175000017500000000763711701311175014243 0ustar walterwaltertthsum-1.3.1 [2012-01-05] (wdoekes) * Fix buffer overrun in tiger tests. Reported by Edward Sheldrake. tthsum-1.3.0 [2011-10-10] (wdoekes) * Force alignment on platforms that need it using a compile-time test. Thanks go out to pavelch for providing failing test cases and to Zoiah for lending me an ARM ;-) (I added a minimal autoconf.c as a faster alternative to proper autconf.) * Fix a rather serious problem with the big endian code. Non-trivial files over 1024 bytes would not have had proper hashes calculated. (Debian bug #517619) * New test cases and tweaks to existing tests. * Fix so compilation with -ansi works. * Fix another problem with alignment on an ARM with -O3 optimization. Thanks Héctor Orón for hooking me up with access to the debian ARM box. * Fix problems with debian packaging. (Debian bug #599173 and CPPFLAGS override) tthsum-1.2.1 [2009-12-29] (wdoekes) * Minor code and build system cleanup. tthsum-1.2.0 [2009-05-29] (wdoekes) * Changed -p output to print percentages instead of MiB counts. * Base32 decoding errors did not generate a valid error message. (Error code 0 conflicted with SUCCESS.) * Fixed that ctrlesctostr accepted strange BASE36 escape sequences. * Made getopt for Windows more compatible with POSIX getopt. * Fixed that including the tthsum specific texts.c is optional. * Changed some header inclusions to be more compliant with C specs and made the source a bit more strict (ANSI C compatible, C++ compatible). * Added a test suite to detect stupid bugs at compile time. (Like the next bug.) * Endianness was not properly detected on various architectures (see debian bug 517619; thanks Alan Curry for reporting). * Standardized UTF8 functions to behave as specified on Windows. * Corrected the need for a double EOF when reading from stdin. * Changed license from GPLv2 to GPLv3. Updated help texts (suggesting gmake on non-Linuxen, for instance). * Removed a bit of overhead on big endian platforms. tthsum-1.1.0 [2005-06-28] (wdoekes) * Converted tthsum to C (it was C++). * Updated makefiles, added NMakefile for Windows, run nmake /f NMakefile on windows. * Added BIG_ENDIAN support (tested on a SPARC). * Removed -b functionality. The asterisk that did nothing didn't make sense. * Made this Changelog a bit more readable. * Fixed a bug where incorrect hashes were generated when using the console as input file. (The reads did not generate a multiple of 1024 bytes.) * Added mmap(2) support (-m) (mapping 1.6MB at a time), default is read(2). YMMV. * Added -p, -w, -V options (show progress, warn about improper digest lines, show version). * Writing escaped and utf8-ified filenames to digest. tthsum-1.0.6 [2005-06-08] (wdoekes) * Removed all debian related stuff (debian/ dir, and Makefile entries). These will go into the debian diff, created by the future maintainer RISKO Gergely. * Added stuff TODO ;) tthsum-1.0.5 [2004-10-23] (wdoekes) * Corrected misuse of revision number as version number (thanks Jan "Yenya" Kasprzak), the debian rev-1 package will be the same as the "original" source (debian uses a different file naming scheme). * Moved tthsum.spec to rpm/ and added tgz/rpm/dists make options. tthsum-1.0-4 [2004-10-19] (wdoekes) * Added tthsum.spec file to build RPM packages (thanks Jan "Yenya" Kasprzak) * Added -fpermissive CXXFLAG to the Makefile to fix build issues on Fedora Core 3 test 3 x86_64 (thanks Jan "Yenya" Kasprzak) tthsum-1.0-3 [2004-07-22] (wdoekes) * Enabled large files support on *nix (#define _FILE_OFFSET_BITS 64) (thanks John Baeckstrand). tthsum-1.0-2 [2004-06-12] (wdoekes) * Ported to windows. * Added windows\make.cmd and windows\make_clean.cmd for use with MSVC.NET * Changed manpage to state that -b option does nothing, not even on windows. * Added man2html generated html manual. tthsum-1.0-1 [2004-05-29] (wdoekes) * Initial Release. * vim: set syntax=changelog: tthsum-1.3.1/COPYING.txt0000664000175000017500000010451311656447501014306 0ustar walterwalter GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is 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. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. 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. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. 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 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. Use with the GNU Affero General Public License. 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 Affero 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 special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 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 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 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. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". 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 GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . tthsum-1.3.1/Makefile0000664000175000017500000000452711656447501014101 0ustar walterwalter# tthsum makefile # # Makefile for GNU Make. .PHONY: all clean dists install manual tthsum uninstall test runtest ifeq ($(BIN),) BIN = $(DESTDIR)/usr/local/bin endif ifeq ($(MAN),) MAN = $(DESTDIR)/usr/local/man endif ifeq ($(DEBUG),) override CPPFLAGS += -DNDEBUG CFLAGS += -O3 #-fno-stack-protector #-march=native LDFLAGS += -O3 #-march=native else override CPPFLAGS += -DDEBUG CFLAGS += -g #-pg LDFLAGS += -g #-pg endif CC ?= gcc GZIP = gzip -9 -c RM = rm -rf override CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DUSE_TEXTS #-DUSE_MY_GETOPT CFLAGS += -Wall #-pedantic #-ansi LDFLAGS += -Wall BINS = obj-unix SHARES = share APPSRC = base32.c escape.c getopt.c read.c texts.c thex.c tiger.c \ tthsum.c utf8.c APPOBJ = $(patsubst %.c,$(BINS)/%.o, $(APPSRC)) APPENTRY = $(BINS)/main.o TSTSRC = $(APPSRC) base32_test.c endian_test.c escape_test.c getopt_test.c \ read_test.c texts_test.c thex_test.c tiger_test.c types_test.c \ utf8_test.c TSTOBJ = $(patsubst %.c,$(BINS)/%.o, $(TSTSRC)) TSTENTRY = $(BINS)/test.o # "autoconf" override CPPFLAGS += $(shell cat $(BINS)/autoconf.cppflags) all: tthsum manual test runtest install: tthsum manual test runtest install -d $(BIN) $(MAN)/man1 install $(BINS)/tthsum $(BIN) install -m644 $(SHARES)/tthsum.1.gz $(MAN)/man1 uninstall: $(RM) $(BIN)/tthsum $(RM) $(MAN)/man1/tthsum.1.gz tthsum: $(BINS)/tthsum manual: $(SHARES)/tthsum.1.gz test: $(BINS)/test runtest: test tthsum $(BINS)/test $(BINS)/tthsum $(BINS)/tthsum $(BINS)/test | $(BINS)/tthsum -cv dists: sh -c 'X=`basename \`pwd\`` ; for opts in "zcf ../$$X.tar.gz" \ "jcf ../$$X.tar.bz2" ; do tar $$opts --no-recursion -C.. \ `svn ls ../$$X | sed -e "s#^#$$X/#"` ; done' #sh -c 'X=`basename \`pwd\`` ; cp ../$$X.tar.gz /usr/src/rpm/SOURCES/' #rpm -bs rpm/tthsum.spec #rpm -bb rpm/tthsum.spec clean: $(RM) $(BINS) $(SHARES) $(BINS)/%.o: %.c @mkdir -p $(BINS) $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ $(BINS)/tthsum: $(APPOBJ) $(APPENTRY) $(SHARES)/tthsum.1.gz: tthsum.1 @mkdir -p $(SHARES) $(GZIP) $< > $@ $(BINS)/test: $(TSTOBJ) $(TSTENTRY) # "autoconf" $(BINS)/autoconf.cppflags: autoconf.c @mkdir -p $(BINS) $(CC) $(CFLAGS) -c autoconf.c -o $(BINS)/autoconf.o $(CC) $(LDFLAGS) $(BINS)/autoconf.o -o $(BINS)/autoconf $(BINS)/autoconf >$(BINS)/autoconf.cppflags $(APPOBJ): $(BINS)/autoconf.cppflags $(TSTOBJ): $(BINS)/autoconf.cppflags tthsum-1.3.1/NMakefile0000664000175000017500000000330511656447501014210 0ustar walterwalter# tthsum makefile # # Makefile for NMAKE that comes with Microsofts # cl.exe C/C++ compiler and link.exe linker. INSTALLDIR = $(WINDIR) CFLAGS = /Ox /Ot /GF /GL /nologo CPPFLAGS = /DUSE_TEXTS /DNDEBUG LD = link.exe LDFLAGS = /LIBPATH:$(BINS) /NOLOGO /LTCG /OPT:REF BINS = obj-win32 TTHSUM = $(BINS)\tthsum.exe TEST = $(BINS)\test.exe APP_OBJS = $(BINS)\base32.obj $(BINS)\escape.obj $(BINS)\getopt.obj \ $(BINS)\read.obj $(BINS)\texts.obj $(BINS)\thex.obj \ $(BINS)\tiger.obj $(BINS)\tthsum.obj $(BINS)\utf8.obj TST_OBJS = $(BINS)\base32_test.obj $(BINS)\endian_test.obj \ $(BINS)\escape_test.obj $(BINS)\getopt_test.obj \ $(BINS)\read_test.obj $(BINS)\texts_test.obj $(BINS)\thex_test.obj \ $(BINS)\tiger_test.obj $(BINS)\types_test.obj \ $(BINS)\utf8_test.obj LIBS = setargv.obj all: tthsum test runtest install: tthsum copy $(TTHSUM) "$(INSTALLDIR)" copy tthsum.html "$(INSTALLDIR)\tthsum.html" copy Changelog.txt "$(INSTALLDIR)\tthsum.txt" uninstall: IF EXIST "$(INSTALLDIR)\tthsum.exe" del "$(INSTALLDIR)\tthsum.exe" IF EXIST "$(INSTALLDIR)\tthsum.txt" del "$(INSTALLDIR)\tthsum.txt" IF EXIST "$(INSTALLDIR)\tthsum.html" del "$(INSTALLDIR)\tthsum.html" tthsum: $(TTHSUM) test: $(TEST) runtest: test tthsum $(BINS)\test.exe $(BINS)\tthsum.exe $(BINS)\tthsum.exe $(BINS)\test.exe \ | $(BINS)\tthsum -cv clean: del /q /s $(BINS)\ rmdir $(BINS) .c{$(BINS)}.obj:: @IF NOT EXIST "$(BINS)" mkdir $(BINS) $(CC) $(CPPFLAGS) $(CFLAGS) $< /c /Fo$(BINS)\ $(TTHSUM): $(APP_OBJS) $(BINS)\main.obj $(LD) $(LDFLAGS) $(APP_OBJS) $(BINS)\main.obj $(LIBS) /OUT:$(TTHSUM) $(TEST): $(APP_OBJS) $(TST_OBJS) $(BINS)\test.obj $(LD) $(LDFLAGS) $(APP_OBJS) $(TST_OBJS) $(BINS)\test.obj $(LIBS) \ /OUT:$(TEST) tthsum-1.3.1/README.txt0000664000175000017500000000262711656447501014136 0ustar walterwalter======================================================================== README (tthsum tiger tree hash creator/verifier) wjd, 2004-2009 ======================================================================== tthsum is an md5sum-alike program that works with Tiger/THEX hashes. Use it to calculate TTH checksums and to compare those with previously calculated sums (digests). For more information, see the man page or tthsum.html. Copyright: Walter Doekes, 2004,2005,2009 Licensing: GPLv3, see COPYING.txt for details. ------------------------------------------------------------------------ Building and installing ------------------------------------------------------------------------ On a standad Linux distro you run `make' from the command line; on a standard BSD run `gmake' to get GNU make; on Windows run `nmake /f NMakefile' from a shell that has cl.exe and link.exe in its path and has the appropriate environment variables set. Run `(g)make install' or `nmake /f NMakefile install' (on anyOS or Windows respectively) to install the files in the locations specified in the makefiles. ------------------------------------------------------------------------ Getting tthsum ------------------------------------------------------------------------ The latest version of tthsum can be found on: http://tthsum.devs.nu/ ======================================================================== tthsum-1.3.1/TODO.txt0000664000175000017500000000206011656447501013735 0ustar walterwalter======================================================================== TODO (tthsum tiger tree hash creator/verifier) wjd, 2004-2011 ======================================================================== Below is a list of possible improvements to tthsum. ------------------------------------------------------------------------ Wishlist ------------------------------------------------------------------------ + Provide a way to create digests of partial files. (Actually utilizing the properties of the Merkle tree.) + Enable selection of other hash methods, e.g. tiger4/192 (4 pass). (If we abstract the tiger_bp function away from the thex unit, check that passing function pointers does not decrease the hashing speed further.) + Optimize tthsum for common platforms. Unfortunately I know too little about either hashing functions or getting the most out of the CPU. So this is a bit out of my league. (The -march gcc option does not seem to be of much use.) ======================================================================== tthsum-1.3.1/autoconf.c0000664000175000017500000000425411656447501014420 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "types.h" #include #include #include #include #include /* The tiger_bp function uses unaligned 64 bit memory access on little * endian platforms. Tests on my x86_64 incur a 3.5% performance penalty * when we force aligned access. However, some platforms need alignment * to function properly (like the ARM). * * I tested doing 1024 byte reads on memory aligned such that it was * properly aligned for the tiger_bp function, but that caused the * system time to double: 6% performance penalty. */ static void conf_alignment() { /* Because it's hard to continue execution after a SIGBUS, we do * the misalignment check from a child process: this way both a * SIGBUS and a value mismatch will add the -DREQUIRE_ALIGNMENT * preprocessor flag. */ pid_t pid = fork(); /* child */ if (pid == 0) { uint64_t buf64[3]; uint8_t *p; memcpy(buf64, "AAAAAAA" "BBBBBBBB" "CCCCCCCC", 24); /* 7+8+8+1 */ p = (uint8_t*)&buf64[0] + 7; if (*((uint64_t*)p) != _ULL(0x4242424242424242)) _exit(1); _exit(0); /* parent */ } else if (pid > 0) { int status; waitpid(pid, &status, 0); if (status != 0) printf("-DREQUIRE_ALIGNMENT "); /* error */ } else { perror("fork"); } } int main() { conf_alignment(); return 0; } tthsum-1.3.1/base32.c0000664000175000017500000001053111656447501013654 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "base32.h" #include "endian.h" #include #if BYTE_ORDER == BIG_ENDIAN # include # include #endif /* BYTE_ORDER == BIG_ENDIAN */ #ifdef USE_TEXTS # include "texts.h" #endif static const int8_t base32_table[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,26,27,28,29,30,31,-1,-1,-1,-1,-1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; static const unsigned char base32_alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; int uint64tobase32(char* dest, const uint64_t* src, unsigned len) { #if BYTE_ORDER == BIG_ENDIAN int i; uint8_t* tmp; len *= 8; if ((tmp = (uint8_t*)malloc(len)) == NULL) { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ return -1; } for (i = 0; i < len; ++i) tmp[i ^ 7] = ((uint8_t*)src)[i]; i = uint8tobase32(dest, tmp, len); free(tmp); return i; #else /* BYTE_ORDER != BIG_ENDIAN */ return uint8tobase32(dest, (const uint8_t*)src, len * 8); #endif /* BYTE_ORDER != BIG_ENDIAN */ } int uint8tobase32(char* dest, const uint8_t* src, unsigned len) { unsigned index = 0; uint8_t word; const uint8_t* srce = src + len; while (src != srce) { /* Spanning byte boundary? */ if (index > 3) { word = (*src & (0xFF >> index)); index = (index + 5) % 8; word <<= index; if (src + 1 != srce) word |= *(src + 1) >> (8 - index); ++src; } else { word = (*src >> (8 - (index + 5))) & 0x1F; index = (index + 5) % 8; if (index == 0) ++src; } assert(word < 32); *dest++ = base32_alpha[word]; } *dest = '\0'; return 0; } int base32touint64(uint64_t* dest, const char* src, unsigned len) { #if BYTE_ORDER == BIG_ENDIAN int ret, i; uint8_t* tmp; len *= 8; if ((tmp = (uint8_t*)malloc(len)) == NULL) { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ return -1; } memset(tmp, 0, len); /* dest must be initialized to zeroes */ ret = base32touint8(tmp, src, len); for (i = 0; i < len; ++i) ((uint8_t*)dest)[i ^ 7] = tmp[i]; free(tmp); return ret; #else /* BYTE_ORDER != BIG_ENDIAN */ return base32touint8((uint8_t*)dest, src, len * 8); #endif /* BYTE_ORDER != BIG_ENDIAN */ } int base32touint8(uint8_t* dest, const char* src, unsigned len) { unsigned index = 0; int8_t tmp; const uint8_t* deste = dest + len; for (; dest != deste; ++src) { if ((tmp = base32_table[(unsigned)*src]) == -1) { #ifdef USE_TEXTS set_error("base32touint8", BASE32_INVALID_CHARACTER); #endif /* USE_TEXTS */ return -1; } if (index <= 3) { index = (index + 5) % 8; if (index == 0) *dest++ |= tmp; else *dest |= tmp << (8 - index); } else { index = (index + 5) % 8; *dest++ |= (tmp >> index); *dest |= tmp << (8 - index); } } return 0; } tthsum-1.3.1/base32.h0000664000175000017500000000461011656447501013662 0ustar walterwalter#ifndef INCLUDED_BASE32_H #define INCLUDED_BASE32_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Conversion routines to and from BASE32. */ #include "types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * Convert an octet-stream to base32. * The octet-stream is supplied through src, the size of the octet-stream * through len. * The base32 will be put in dest, along with a terminating zero, make * sure there is room for ceil(len*8/5)+1 characters. */ int uint8tobase32(char* dest, const uint8_t* src, unsigned len); /** * Convert an uint64_t-stream to base32. * See uint8tobase32(). dest must be at least ceil(len*8*8/5)+1 characters * long. * Use this if you're feeding 64bit numbers into the stream. If you use the * 8bit equivalent, BIG_ENDIAN machines will get things wrong. * This may actually fail if the malloc fails. */ int uint64tobase32(char* dest, const uint64_t* src, unsigned len); /** * Convert a base32 octet-stream to exactly len uint8's. * Make sure your dest memory is initialized to zero! * If the conversion fails (due to invalid characters in src), it will return * -1 instead of 0. */ int base32touint8(uint8_t* dest, const char* src, unsigned len); /** * Convert a base32 octet-stream to exactly len uint64's. * Make sure your dest memory is initialized to zero! * If the conversion fails (due to invalid characters in src), it will return * -1 instead of 0. */ int base32touint64(uint64_t* dest, const char* src, unsigned len); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_BASE32_H */ tthsum-1.3.1/base32_test.c0000664000175000017500000001453311656447501014721 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "base32.h" #include "test.h" #include #ifdef USE_TEXTS # include "texts.h" #else /* !USE_TEXTS */ # define get_error() "Fail" #endif /* !USE_TEXTS */ static int help_cmp_symmetric8(const char* name, const uint8_t* uint8, unsigned uint8len, const char* base32, int should_fail) { uint8_t uint8buf[2048]; char base32buf[2048]; memset(uint8buf, 0, 2048); memset(base32buf, 85, 2048); if (uint8len >= 1024 || strlen(base32) >= 2048) FAIL3("Test values too large: \"%s\" is %u and %u bytes", name, uint8len, (unsigned)strlen(base32)); if (uint8tobase32(base32buf, uint8, uint8len) != 0) FAIL2("uint8tobase32 failed on \"%s\": %s", name, get_error()); if (base32touint8(uint8buf, base32, uint8len) != 0) FAIL2("base32touint8 failed on \"%s\": %s", name, get_error()); if ((memcmp(uint8, uint8buf, uint8len) != 0 || strcmp(base32, base32buf) != 0) == !should_fail) FAIL2("Values %sdiffer for \"%s\"", should_fail ? "do NOT " : "", name); return 0; } static int help_cmp_symmetric64(const char* name, const uint64_t* uint64, unsigned uint64len, const char* base32, int should_fail) { uint64_t uint64buf[2048]; char base32buf[2048]; memset(uint64buf, 0, 2048); memset(base32buf, 85, 2048); if (uint64len >= 1024 / 8 || strlen(base32) >= 2048) FAIL3("Test values too large: \"%s\" is %u*8 and %u bytes", name, uint64len, (unsigned)strlen(base32)); if (uint64tobase32(base32buf, uint64, uint64len) != 0) FAIL2("uint64tobase32 failed on \"%s\": %s", name, get_error()); if (base32touint64(uint64buf, base32, uint64len) != 0) FAIL2("base32touint64 failed on \"%s\": %s", name, get_error()); if ((memcmp(uint64, uint64buf, uint64len) != 0 || strcmp(base32, base32buf) != 0) == !should_fail) FAIL2("Values %sdiffer for \"%s\"", should_fail ? "do NOT " : "", name); return 0; } static int help_cmp_symmetric(const char* string, const char* base32) { return help_cmp_symmetric8(string, (const uint8_t*)string, strlen(string), base32, 0); } static int help_not_cmp_symmetric(const char* string, const char* base32) { return help_cmp_symmetric8(string, (const uint8_t*)string, strlen(string), base32, 1); } static int help_cmp_decode8(const char* name, const char* base32, const uint8_t* uint8, unsigned uint8len, int should_fail) { uint8_t uint8buf[2048]; memset(uint8buf, 0, 2048); if (uint8len > 1024) FAIL2("Test value too large: \"%s\" is %u bytes", name, uint8len); if (base32touint8(uint8buf, base32, uint8len) != 0) FAIL1("base32touint8 failed on \"%s\"", name); if (memcmp(uint8, uint8buf, uint8len) == !should_fail) FAIL2("Values %sdiffer for \"%s\"", should_fail ? "do NOT " : "", name); return 0; } static int help_cmp_decode(const char* base32, const char* string) { return help_cmp_decode8(base32, base32, (const uint8_t*)string, strlen(string), 0); } static int test_bidirectional_rfc4648() { return help_cmp_symmetric("", "") + help_cmp_symmetric("f", "MY") + help_cmp_symmetric("fo", "MZXQ") + help_cmp_symmetric("foo", "MZXW6") + help_cmp_symmetric("foob", "MZXW6YQ") + help_cmp_symmetric("fooba", "MZXW6YTB") + help_cmp_symmetric("foobar", "MZXW6YTBOI"); } static int test_not_bidirectional_rfc4648() { return help_not_cmp_symmetric("", "a") + help_not_cmp_symmetric("g", "MY") + help_not_cmp_symmetric("go", "MZXQ") + help_not_cmp_symmetric("goo", "MZXW6") + help_not_cmp_symmetric("fooB", "MZXW6YQ") + help_not_cmp_symmetric("fooBa", "MZXW6YTB") + help_not_cmp_symmetric("fooBar", "MZXW6YTBOI") + help_not_cmp_symmetric("fooba", "MZXW6YTBOI") + help_not_cmp_symmetric("foob", "MZXW6YTB") + help_not_cmp_symmetric("foo", "MZXW6YQ"); } static int test_unidirectional_rfc4648() { return help_cmp_decode("====", "") + help_cmp_decode("my====", "f") + help_cmp_decode("mY", "f") + help_cmp_decode("mZxW6yTbOi====", "foobar"); } static int test_decode_success() { uint8_t buf[256]; return base32touint8(buf, "AA", 1) || base32touint8(buf, "77", 1) || base32touint8(buf, "777", 1) || base32touint8(buf, "7777", 2) || base32touint8(buf, "77777", 3) || base32touint8(buf, "AAAAAA", 3) || base32touint8(buf, "CCCCCCC", 4) || base32touint8(buf, "BBBBBBBB", 5) || base32touint8(buf, "ABCDEFGH", 5); } static int test_decode_fail() { uint8_t buf[256]; return !base32touint8(buf, "A", 1) || !base32touint8(buf, "77", 2) || !base32touint8(buf, "ABCDEFGH", 6); } #define C(val) ((const uint8_t*)val) static int test_misc_binary() { return help_cmp_symmetric8("\\0", C("\0"), 1, "AA", 0) + help_cmp_symmetric8("\\0\\0", C("\0\0"), 2, "AAAA", 0) + help_cmp_symmetric8("\\xff", C("\xff"), 1, "74", 0) + help_cmp_symmetric8("\\xff\\0\\xff", C("\xff\0\xff"), 3, "74AP6", 0); } #undef C static int test_misc_binary64() { int ret = 0; uint64_t buf[16]; buf[0] = _ULL(0x8b630e030ad09e5d); buf[1] = _ULL(0x0e90fb246a3a75db); buf[2] = _ULL(0xb6256c3ee7b8635a); ret += help_cmp_symmetric64("test64:1", buf, 3, "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ", 0); ++buf[2]; ret += help_cmp_symmetric64("test64:2", buf, 3, "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ", 1); return ret; } TESTS(base32_test) TEST(test_bidirectional_rfc4648); TEST(test_not_bidirectional_rfc4648); TEST(test_unidirectional_rfc4648); TEST(test_decode_success); TEST(test_decode_fail); TEST(test_misc_binary); TEST(test_misc_binary64); ENDTESTS tthsum-1.3.1/endian.h0000664000175000017500000000407011656447501014041 0ustar walterwalter#ifndef INCLUDED_ENDIAN_H #define INCLUDED_ENDIAN_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Get byte order (endianness) for the host platform. */ /* Try to get BYTE_ORDER, BIG_ENDIAN and LITTLE_ENDIAN */ #if defined(__linux) # include # ifndef BIG_ENDIAN # define BIG_ENDIAN __BIG_ENDIAN # endif # ifndef LITTLE_ENDIAN # define LITTLE_ENDIAN __LITTLE_ENDIAN # endif # ifndef BYTE_ORDER # define BYTE_ORDER __BYTE_ORDER # endif #elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__OpenBSD__) /* sys/types.h includes machine/endian.h */ # include # define LITTLE_ENDIAN _LITTLE_ENDIAN # define BIG_ENDIAN _BIG_ENDIAN #endif /* !__*BSD__ */ /* Test the values and try to set them by hand on failure */ #if LITTLE_ENDIAN == BIG_ENDIAN \ || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) \ || !defined(BIG_ENDIAN) || !defined(LITTLE_ENDIAN) # undef BYTE_ORDER # undef BIG_ENDIAN # undef LITTLE_ENDIAN # define BIG_ENDIAN 4321 # define LITTLE_ENDIAN 1234 # if defined(__alpha) || defined(__i386__) || defined(__vax__) \ || defined(_WIN32) # define BYTE_ORDER LITTLE_ENDIAN # else # define BYTE_ORDER BIG_ENDIAN # endif #endif #endif /* INCLUDED_ENDIAN_H */ tthsum-1.3.1/endian_test.c0000664000175000017500000000677411656447501015110 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009,2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "endian.h" #include "test.h" #include "types.h" static int test_defines() { #ifndef BYTE_ORDER FAIL("BYTE_ORDER is not defined"); #endif #ifndef BIG_ENDIAN FAIL("BIG_ENDIAN is not defined"); #endif #ifndef LITTLE_ENDIAN FAIL("LITTLE_ENDIAN is not defined"); #endif #if BIG_ENDIAN == LITTLE_ENDIAN FAIL("BIG_ENDIAN == LITTLE_ENDIAN"); #endif #if BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN FAIL("BYTE_ORDER not in (BIG_ENDIAN, LITTLE_ENDIAN)"); #endif return 0; } static int test_endian8() { uint8_t val8 = 0x1f; char val = 0x7f; if ((uint8_t)(val8 << 4) != 0xf0) FAIL("The unsigned 8bit type has too many bits"); if ((char)(val >> 4) != 0x07) FAIL("The char type is broken"); val = (char)0xf0; if (((signed char)val >> 2) != -4) FAIL("The char type is broken"); return 0; } static int test_endian16() { uint16_t val16 = 0x4321; uint8_t *p = (uint8_t*)&val16; short val = 0x4321; char *q = (char*)&val; #if BYTE_ORDER == BIG_ENDIAN if (p[0] != 0x43 || p[1] != 0x21) FAIL("Big endian check fails on 16 bit numbers"); if (q[0] != 0x43 || q[1] != 0x21) FAIL("Big endian check fails on shorts"); #else /* BYTE_ORDER != BIG_ENDIAN */ if (p[0] != 0x21 || p[1] != 0x43) FAIL("Little endian check fails on 16 bit numbers"); if (q[0] != 0x21 || q[1] != 0x43) FAIL("Little endian check fails on shorts"); #endif /* BYTE_ORDER != BIG_ENDIAN */ return 0; } static int test_endian32() { uint32_t val32 = 0x87654321; uint8_t *p = (uint8_t*)&val32; #if BYTE_ORDER == BIG_ENDIAN if (p[0] != 0x87 || p[1] != 0x65 || p[2] != 0x43 || p[3] != 0x21) FAIL("Big endian check fails on 32 bit numbers"); #else /* BYTE_ORDER != BIG_ENDIAN */ if (p[0] != 0x21 || p[1] != 0x43 || p[2] != 0x65 || p[3] != 0x87) FAIL("Little endian check fails on 32 bit numbers"); #endif /* BYTE_ORDER != BIG_ENDIAN */ return 0; } static int test_endian64() { uint64_t val64 = _ULL(0x0fedcba987654321); uint8_t *p = (uint8_t*)&val64; #if BYTE_ORDER == BIG_ENDIAN if (p[0] != 0x0f || p[1] != 0xed || p[2] != 0xcb || p[3] != 0xa9 || p[4] != 0x87 || p[5] != 0x65 || p[6] != 0x43 || p[7] != 0x21) FAIL("Big endian check fails on 64 bit numbers"); #else /* BYTE_ORDER != BIG_ENDIAN */ if (p[0] != 0x21 || p[1] != 0x43 || p[2] != 0x65 || p[3] != 0x87 || p[4] != 0xa9 || p[5] != 0xcb || p[6] != 0xed || p[7] != 0x0f) FAIL("Little endian check fails on 64 bit numbers"); #endif /* BYTE_ORDER != BIG_ENDIAN */ return 0; } TESTS(endian_test) TEST(test_defines); TEST(test_endian8); TEST(test_endian16); TEST(test_endian32); TEST(test_endian64); ENDTESTS tthsum-1.3.1/escape.c0000664000175000017500000000524311656447501014041 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "escape.h" #include #ifdef USE_TEXTS # include "texts.h" #endif void strtoctrlesc(char* dest, const char* src) { while (*src != '\0') { if (0) { /* the optimizer will take care of this */ #define ELIF(ctrl, ch) } else if (*src == ctrl) { *dest++ = '\\'; *dest++ = ch ELIF('\a', 'a'); ELIF('\b', 'b'); ELIF('\t', 't'); ELIF('\n', 'n'); ELIF('\v', 'v'); ELIF('\f', 'f'); ELIF('\r', 'r'); ELIF('\\', '\\'); #undef ELIF } else if ((unsigned char)*src < 0x20) { sprintf(dest, "\\x%02hx", (short)*src); /* %hhx is not C90 */ dest += 4; } else { *dest++ = *src; } ++src; } *dest = '\0'; } int ctrlesctostr(char* dest, const char* src) { while (*src != '\0') { if (*src == '\\') { ++src; if (0) { /* the optimizer will take care of this */ #define ELIF(ch, ctrl) } else if (*src == ch) { *dest = ctrl ELIF('a', '\a'); ELIF('b', '\b'); ELIF('t', '\t'); ELIF('n', '\n'); ELIF('v', '\v'); ELIF('f', '\f'); ELIF('r', '\r'); ELIF('\\', '\\'); } else if (*src == 'x') { int i; *dest = 0; for (i = 0; i < 2; ++i) { ++src; if ((unsigned char)*src >= '0' && (unsigned char)*src <= '9') *dest += *src - '0'; else if ((unsigned char)*src >= 'A' && (unsigned char)*src <= 'F') *dest += *src - 'A' + 10; else if ((unsigned char)*src >= 'a' && (unsigned char)*src <= 'f') *dest += *src - 'a' + 10; else { #ifdef USE_TEXTS set_error("ctrlesctostr", ESCAPE_INVALID_ESCAPE); #endif /* USE_TEXTS */ return -1; } if (i == 0) *dest <<= 4; } } else { #ifdef USE_TEXTS set_error("ctrlesctostr", ESCAPE_INVALID_ESCAPE); #endif /* USE_TEXTS */ return -1; } } else { *dest = *src; } ++dest; ++src; } *dest = '\0'; return 0; } tthsum-1.3.1/escape.h0000664000175000017500000000323611656447501014046 0ustar walterwalter#ifndef INCLUDED_ESCAPE_H #define INCLUDED_ESCAPE_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Conversion routines to and from \xNN escaping for non-printable characters * (0x00 through 0x1F). */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * Escape all characters below 0x20 and the backslash in a C-string. * The destination dest must be at least 4*strlen(src)+1 characters long. */ void strtoctrlesc(char* dest, const char* src); /** * Unescape a string escaped by strtoctrlesc. * The destination dest must be at least strlen(src)+1 characters long. * Returns 0 on success and -1 when an invalid escape sequence is encountered * (and the state of dest will be undefined). */ int ctrlesctostr(char* dest, const char* src); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_ESCAPE_H */ tthsum-1.3.1/escape_test.c0000664000175000017500000001040711656447501015076 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "escape.h" #include "test.h" #include "texts.h" #include static int help_cmp_symmetric(const char* str, const char* escaped, int should_fail) { char strbuf[2048]; char escapedbuf[2048]; if (strlen(str) >= 512 || strlen(escaped) >= 2048) FAIL3("Test values too large: \"%s\" is %u and %u bytes", escaped, (unsigned)strlen(str), (unsigned)strlen(escaped)); strtoctrlesc(escapedbuf, str); if (ctrlesctostr(strbuf, escaped) != 0) FAIL2("ctrlesctostr failed on \"%s\": %s", escaped, get_error()); if ((strcmp(strbuf, str) != 0 || strcmp(escapedbuf, escaped) != 0) == !should_fail) FAIL2("Values %sdiffer for \"%s\"", should_fail ? "do NOT " : "", escaped); return 0; } static int help_cmp_unescape(const char* escaped, const char* result, int should_fail) { char resultbuf[2048]; if (strlen(escaped) >= 2048) FAIL2("Test value too large: \"%s\" is %u bytes", escaped, (unsigned)strlen(escaped)); if (ctrlesctostr(resultbuf, escaped) != 0) FAIL2("ctrlesctostr failed on \"%s\": %s", escaped, get_error()); if (strcmp(resultbuf, result) == !should_fail) FAIL2("Values %sdiffer for \"%s\"", should_fail ? "do NOT " : "", escaped); return 0; } static int test_bidirectional_success() { return help_cmp_symmetric("", "", 0) + help_cmp_symmetric("ABC", "ABC", 0) + help_cmp_symmetric("\xff ABC \x80\x81", "\xff ABC \x80\x81", 0) + help_cmp_symmetric( "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\\x01\\x02\\x03\\x04\\x05\\x06\\a\\b\\t\\n\\v\\f\\r\\x0e\\x0f", 0) + help_cmp_symmetric( "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e" "\x1f", "\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19" "\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f", 0); } static int test_bidirectional_fail() { return help_cmp_symmetric(" ", "", 1) + help_cmp_symmetric("ABC", "ABCD", 1) + help_cmp_symmetric("\n", "\\x0a", 1) + help_cmp_symmetric("\r\n", "\\n\\n", 1) + help_cmp_symmetric("\0", "\\x00", 1); /* \0 is not seen */ } static int test_unidirectional_success() { return help_cmp_unescape("\\x0d\\n", "\r\n", 0) + help_cmp_unescape("abcdef", "abcdef", 0) + help_cmp_unescape("abc\\x0a\\x0d\\t", "abc\n\r\t", 0) + help_cmp_unescape("\\x00foobar", "", 0) /* leading \0 */ + help_cmp_unescape("\\\\x80\x81\\xff", "\\x80\x81\xff", 0); } static int test_unidirectional_fail() { return help_cmp_unescape("\\x0d\\n", "\\x0d\n", 1) + help_cmp_unescape("abcdef", "abcdefg", 1) + help_cmp_unescape("abc\\x0a\\x0d\\t", "abc\\n\\r\\t", 1) + help_cmp_unescape("\\x00foobar", "foobar", 1) + help_cmp_unescape("\\\\x80\x81\\xff", "\x80\x81\xff", 1); } static int test_decode_success() { char buf[256]; return ctrlesctostr(buf, "\\x11") || ctrlesctostr(buf, "abc\\x00def") || ctrlesctostr(buf, "\\x0a\\n\\r\\x0d") || ctrlesctostr(buf, "\a\b\t\v\r\n") || ctrlesctostr(buf, "\\x1A\\x1a"); } static int test_decode_fail() { char buf[256]; return !ctrlesctostr(buf, "\\x1") || !ctrlesctostr(buf, "\\0") || !ctrlesctostr(buf, "\\0\\1\\2") || !ctrlesctostr(buf, "\\x1g") || !ctrlesctostr(buf, "\\g") || !ctrlesctostr(buf, "\\N") || !ctrlesctostr(buf, "\\x1G"); } TESTS(escape_test) TEST(test_bidirectional_success); TEST(test_bidirectional_fail); TEST(test_unidirectional_success); TEST(test_unidirectional_fail); TEST(test_decode_success); TEST(test_decode_fail); ENDTESTS tthsum-1.3.1/getopt.c0000664000175000017500000000726611656447501014112 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "getopt.h" #ifdef USE_MY_GETOPT # include # include char* optarg; /* option argument */ int optind = 0; /* argv index */ int opterr = 1; /* print errors on stderr */ int optopt = 0; /* the character found for '?' characters */ static int optindind = 0; /* letter-index for options at optind */ int getopt(int argc, char* const argv[], const char* optstring) { /* if optindind is set, we're looking at an option at optind */ if (optindind != 0) { int ret; const char* p = strchr(optstring, argv[optind][optindind]); /* unknown option */ if (p == NULL) { ret = '?'; optopt = argv[optind][optindind]; if (argv[optind][optindind + 1] != '\0') { ++optindind; } else { optindind = 0; ++optind; } if (opterr) fprintf(stderr, "%s: invalid option -- %c\n", argv[0], optopt); return '?'; /* with-argument option */ } else if (p[1] == ':') { /* GNU extension: double colon means arg is optional */ ret = argv[optind][optindind]; /* argument is attached to option */ if (argv[optind][optindind + 1] != '\0') { optarg = argv[optind] + optindind + 1; optindind = 0; ++optind; /* argument is not attached and optional (GNU extension) */ } else if (p[2] == ':') { optarg = NULL; optindind = 0; ++optind; /* argument is not optional and loose */ } else { if (optind + 1 == argc) { optopt = ret; if (opterr) fprintf(stderr, "%s: option requires an argument" " -- %c\n", argv[0], optopt); ret = '?'; } else { ++optind; optarg = argv[optind]; } } optindind = 0; ++optind; /* correct non-argument option */ } else { ret = argv[optind][optindind]; if (argv[optind][optindind + 1] != '\0') { ++optindind; } else { optindind = 0; ++optind; } } return ret; } /* if optind is zero, we haven't run yet */ if (optind <= 0) { optind = 1; optindind = 0; } /* done? */ if (optind >= argc) return -1; /* end of options? */ if (argv[optind][0] == '-' && argv[optind][1] == '-' && argv[optind][2] == '\0') { ++optind; return -1; } /* not an option? */ if (argv[optind][0] != '-') { /* find option and move it to front */ const char** mut_argv = (const char**)argv; int i; for (i = optind + 1; i < argc; ++i) { if (argv[i][0] == '-') { if (argv[i][1] == '\0') continue; if (argv[i][1] == '-' && argv[i][2] == '\0') continue; /* found, move back */ for (; i > optind; --i) { const char* tmp; tmp = mut_argv[i]; mut_argv[i] = mut_argv[i - 1]; mut_argv[i - 1] = tmp; } break; } } if (i == argc) return -1; } /* we're here, so we have an option */ optindind = 1; return getopt(argc, argv, optstring); } #endif /* !USE_MY_GETOPT */ tthsum-1.3.1/getopt.h0000664000175000017500000000415011656447501014104 0ustar walterwalter#ifndef INCLUDED_GETOPT_H #define INCLUDED_GETOPT_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * A portable getopt implementation, selecting the native version if * available. */ #if defined(USE_MY_GETOPT) /* We'll use mine */ #elif defined(_WIN32) # define USE_MY_GETOPT #elif defined(__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) # define USE_BSD_GETOPT #elif _POSIX_C_SOURCE < 200112 # define USE_MY_GETOPT #elif defined(POSIXLY_CORRECT) # define USE_BSD_GETOPT #endif #ifdef USE_MY_GETOPT #include "types.h" #ifdef __cplusplus extern "C" { #endif /** * A simplified getopt, works just like POSIX getopt, and implements * the GNU double-colon for optional arguments. */ int getopt(int argc, char* const argv[], const char* optstring); /** * Option argument for argument-having options. Do not try to modify * this string as it should be (const char*) but isn't because we try * to be compatible with POSIX getopt. */ extern char *optarg; /** * External getopt globals: non-option index, enable/disable errors * on stderr, invalid option character. */ extern int optind, opterr, optopt; #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #else /* !USE_MY_GETOPT */ #include #endif /* !USE_MY_GETOPT */ #endif /* INCLUDED_GETOPT_H */ tthsum-1.3.1/getopt_test.c0000664000175000017500000001062111656447501015136 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "getopt.h" #include "test.h" #include static int argc; static const char* argv[64]; static void reset_getopt(const char* const args[]) { for (argc = 0; args[argc]; ++argc) argv[argc] = args[argc]; #if !defined(USE_MY_GETOPT) \ && (defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) optind = 1; optreset = 1; #else /* USE_MY_GETOPT || !__*BSD__ */ optind = 0; optopt = '\0'; #endif /* USE_MY_GETOPT || !__*BSD__ */ opterr = 1; } static int test_getopt_counts_and_order() { const char* const args[] = { #ifdef USE_BSD_GETOPT /* BSD getopt semantics means that no options are allowed after * non-options. (Also available through POSIXLY_CORRECT.) */ "test_getopt", "-o", "-4", "-ghi", "abc.txt", "De\xff.txt", 0 #else /* !USE_BSD_GETOPT */ "test_getopt", "abc.txt", "-o", "-4", "De\xff.txt", "-ghi", 0 #endif /* !USE_BSD_GETOPT */ }; int ret; int good_option_count = 0; int bad_option_count = 0; reset_getopt(args); opterr = 0; while ((ret = getopt(argc, (char* const*)argv, "Vbg")) >= 0) { switch(ret) { case 'g': /* expected good option */ TEST_PASS(good_option_count == 0 && bad_option_count == 2, "getopt returned option 'g' too soon or too late"); ++good_option_count; break; case '?': /* expected bad options */ if ((optopt == 'o' && bad_option_count == 0) || (optopt == '4' && bad_option_count == 1) || (optopt == 'h' && bad_option_count == 2) || (optopt == 'i' && bad_option_count == 3)) { ++bad_option_count; break; } FAIL3("getopt returned unexpected bad option character: %c (%i/%i)", optopt, good_option_count, bad_option_count); default: FAIL3("getopt returned unexpected option character: %c (%i/%i)", ret, good_option_count, bad_option_count); } } TEST_PASS(good_option_count == 1, "got too many or too few good options"); TEST_PASS(bad_option_count == 4, "got too many or too few bad options"); TEST_PASS1(optind + 2 == argc, "%i arguments found", argc - optind); TEST_PASS1(strcmp(argv[optind], "abc.txt") == 0, "abc.txt != %s", argv[optind]); TEST_PASS(strcmp(argv[optind+1], "De\xff.txt") == 0, "De?.txt mismatch"); return 0; } static int test_getopt_missing_argument() { const char* const args[] = {"test_getopt", "-o", 0}; int ret; reset_getopt(args); opterr = 0; while ((ret = getopt(argc, (char* const*)argv, "o:")) >= 0) { switch(ret) { case 'o': FAIL("getopt returned 'o' even though we lack arguments"); case '?': if (optopt == 'o') /* missing option argument */ break; default: FAIL2("fell through switch: ret=%i optopt=%i", ret, optopt); } } return 0; } static int test_getopt_double_dash() { const char* const args[] = {"test_getopt", "-o", "--", "-o", "--", 0}; int ret; int opts = 0; reset_getopt(args); opterr = 0; while ((ret = getopt(argc, (char* const*)argv, "o")) >= 0) { switch(ret) { case 'o': case '?': ++opts; break; default: FAIL2("fell through switch: ret=%i optopt=%i", ret, optopt); } } TEST_PASS(opts == 1, "got too many or too few options"); TEST_PASS1(optind + 2 == argc, "%i arguments found", argc - optind); TEST_PASS1(strcmp(argv[optind], "-o") == 0, "-o != %s", argv[optind]); TEST_PASS1(strcmp(argv[optind+1], "--") == 0, "-- != %s", argv[optind+1]); return 0; } TESTS(getopt_test) TEST(test_getopt_counts_and_order); TEST(test_getopt_missing_argument); TEST(test_getopt_double_dash); ENDTESTS tthsum-1.3.1/main.c0000664000175000017500000000761111701311371013510 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009,2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "getopt.h" #include "tthsum.h" #include #include #include static void help(int error); static void version(); int main(int argc, char* const argv[]) { const char* stdin_file[] = {NULL, NULL}; struct tthsum_options opt; int ret; int digest = 0; int quit = 0; char* cp; memset(&opt, 0, sizeof(struct tthsum_options)); /* set up proper locale */ if ((cp = setlocale(LC_CTYPE, "")) == NULL && (cp = setlocale(LC_CTYPE, "C")) == NULL) fprintf(stderr, "tthsum: warning: Check your locale settings " "(the LANG and/or LC_CTYPE environment variables).\n"); if (cp && strcmp(cp, "C") != 0 && strcmp(cp, "POSIX") != 0) opt.has_locale = 1; /* read options */ while ((ret = getopt(argc, argv, "bchmpvVw")) >= 0) { switch(ret) { case 'b': /* md5sum compatibility, don't do anything special, * as we always do "binary" mode */ break; case 'c': digest = 1; break; case 'm': opt.use_mmap = 1; break; case 'p': opt.progress_every_mib = 10; break; case 'v': opt.verbose = 1; break; case 'w': opt.warn = 1; break; case 'V': version(); quit = 1; break; case 'h': help(0); quit = 1; break; case '?': help(1); return 2; default: /* shouldn't happen */ return -1; } } if (quit) return 0; /* check digest? */ if (digest) { /* only accept one digest file */ if (optind > argc + 1) { help(1); return 2; } if (optind == argc) ret = tthsum_check_digest(NULL, &opt); else ret = tthsum_check_digest(argv[optind], &opt); /* generate digest? */ } else { if (optind == argc) { ret = tthsum_generate_roots(stdin_file, 1, &opt); } else { ret = tthsum_generate_roots((const char**)argv + optind, argc - optind, &opt); } } /* done */ return ret == 0 ? 0 : 1; } static void help(int error) { fprintf(error ? stderr : stdout, "usage: tthsum [-bhmpvVw] [-c [file]] | [file...]\n" "Generates or checks TTH Message Digests (root of the Tiger/THEX hash tree)\n" " -b md5sum compatibility option (does absolutely nothing)\n" " -c check message digests (default is generate)\n" " -h show the small help and exit\n" " -m use mmap for reading files\n" " -p show the hashing progress\n" " -v verbose, print file names when checking a digest\n" " -V print the version and exit\n" " -w warn on improperly formatted lines checking a digest\n" ); fprintf(error ? stderr : stdout, "The input for -c should be the list of message digests and file names\n" "that is printed on stdout by this program when it generates digests.\n" "If you don't specify a file, input will be read from stdin.\n" ); } static void version() { printf( "tthsum 1.3.1\n" "\n" "Copyright 2004,2005,2009,2011,2012 Walter Doekes.\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" ); } tthsum-1.3.1/read.c0000664000175000017500000003164011656447501013514 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "read.h" #include #include #include #include #include #include #include #ifdef _WIN32 # define STDIN_FILENO fileno(stdin) /* fileno is in */ # define WINDOWS_LEAN_AND_MEAN # include #else /* !_WIN32 */ # include # include # include # define O_BINARY 0 #endif /* !_WIN32 */ #ifdef USE_TEXTS # include "texts.h" #endif #define DEFAULT_BLOCK_SIZE 8192 /* must be a multiple of 1024 */ enum rofile_type { MEM, MMAP, SYS }; struct rofile_mem { char* buf; const char* cur; unsigned left; }; struct rofile_mmap { #ifdef _WIN32 HANDLE fd; HANDLE map; LPVOID view; #else /* !_WIN32 */ int fd; void* map; unsigned last; #endif /* !_WIN32 */ uint64_t off; uint64_t left; }; struct rofile_sys { int fd; int close_fd; /* close fd afterwards */ #ifdef _WIN32 int fdmode; /* original fd mode (bin/txt) */ #endif /* _WIN32 */ int done; char* buf; }; struct rofile { enum rofile_type rof_type; unsigned rof_blocksize; uint64_t rof_filesize; union { struct rofile_mem rof_mem; struct rofile_mmap rof_mmap; struct rofile_sys rof_sys; } u; /* ansi does not allow anonymous unions */ }; _INLINE static void close_or_warn(int fd) { /* Send warning to stderr but ignore failure... * After all, we did only read bytes, not write any. */ if (close(fd) != 0) perror("rofclose: closing fd failed"); } struct rofile* rofopen_mem(const char* data, unsigned length) { struct rofile* rf = NULL; rf = (struct rofile*)malloc(sizeof(struct rofile)); if (rf != NULL) { rf->rof_type = MEM; rf->rof_blocksize = DEFAULT_BLOCK_SIZE; rf->rof_filesize = length; rf->u.rof_mem.buf = (char*)malloc(length); if (rf->u.rof_mem.buf != NULL) { memcpy(rf->u.rof_mem.buf, data, length); rf->u.rof_mem.cur = rf->u.rof_mem.buf; rf->u.rof_mem.left = length; return rf; } else { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ } free(rf); } else { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ } return NULL; } struct rofile* rofopen_mmap(const char* filename) { struct rofile* rf = NULL; #ifdef _WIN32 SYSTEM_INFO si; LARGE_INTEGER li; rf = (struct rofile*)malloc(sizeof(struct rofile)); if (rf == NULL) { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ return NULL; } rf->rof_type = MMAP; GetSystemInfo(&si); /* 0x1000000 = 2^24 = 1.6MiB */ rf->rof_blocksize = 0x1000000 - (0x1000000 % si.dwAllocationGranularity); rf->u.rof_mmap.fd = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (rf->u.rof_mmap.fd != INVALID_HANDLE_VALUE) { if (GetFileSizeEx(rf->u.rof_mmap.fd, &li) == TRUE) { rf->rof_filesize = (uint64_t)li.QuadPart; rf->u.rof_mmap.left = rf->rof_filesize; rf->u.rof_mmap.off = 0; rf->u.rof_mmap.view = NULL; /* windows fails to map empty files :-/ */ if (rf->rof_filesize != 0) { rf->u.rof_mmap.map = CreateFileMapping(rf->u.rof_mmap.fd, NULL, PAGE_READONLY, 0, 0, NULL); if (rf->u.rof_mmap.map != NULL) return rf; #ifdef USE_TEXTS else set_error("CreateFileMapping", -1); #endif /* USE_TEXTS */ } else { rf->u.rof_mmap.map = NULL; return rf; } #ifdef USE_TEXTS } else { set_error("GetFileSizeEx", -1); #endif /* USE_TEXTS */ } CloseHandle(rf->u.rof_mmap.fd); #ifdef USE_TEXTS } else { set_error("CreateFile", -1); #endif /* USE_TEXTS */ } #else /* !_WIN32 */ struct stat st; rf = (struct rofile*)malloc(sizeof(struct rofile)); if (rf != NULL) { rf->rof_type = MMAP; rf->u.rof_mmap.fd = open(filename, O_RDONLY | O_BINARY); if (rf->u.rof_mmap.fd != -1) { if (fstat(rf->u.rof_mmap.fd, &st) != -1) { rf->rof_filesize = rf->u.rof_mmap.left = (uint64_t)st.st_size; /* 0x1000000 = 2^24 = 1.6MiB */ rf->rof_blocksize = 0x1000000; #if defined(_BSD_SOURCE) || _XOPEN_SOURCE >= 500 rf->rof_blocksize -= 0x1000000 % getpagesize(); #endif /* _BSD_SOURCE || _XOPEN_SOURCE >= 500 */ rf->u.rof_mmap.off = 0; rf->u.rof_mmap.map = NULL; return rf; #ifdef USE_TEXTS } else { set_error("fstat", -1); #endif /* USE_TEXTS */ } close_or_warn(rf->u.rof_mmap.fd); #ifdef USE_TEXTS } else { set_error("open", -1); #endif /* USE_TEXTS */ } } #endif /* !_WIN32 */ free(rf); return NULL; } struct rofile* rofopen_sysfd(int fd) { struct rofile *rf = NULL; #ifdef _WIN32 int old_fdmode; if ((old_fdmode = setmode(fd, O_BINARY)) == -1) { #ifdef USE_TEXTS set_error("fdmode", -1); #endif /* USE_TEXTS */ return NULL; } #endif /* _WIN32 */ if ((rf = (struct rofile*)malloc(sizeof(struct rofile))) != NULL) { rf->rof_type = SYS; rf->rof_blocksize = DEFAULT_BLOCK_SIZE; rf->rof_filesize = (uint64_t)-1; /* the "unknown" size */ rf->u.rof_sys.fd = fd; rf->u.rof_sys.close_fd = 0; #ifdef _WIN32 rf->u.rof_sys.fdmode = old_fdmode; #endif /* _WIN32 */ rf->u.rof_sys.done = 0; if ((rf->u.rof_sys.buf = (char*)malloc(rf->rof_blocksize)) != NULL) { return rf; } else { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ } free(rf); } else { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ } #ifdef _WIN32 if (old_fdmode != O_BINARY) setmode(fd, old_fdmode); #endif /* _WIN32 */ return NULL; } struct rofile* rofopen_sysfd_stdin() { return rofopen_sysfd(STDIN_FILENO); } struct rofile* rofopen_sysfile(const char* filename) { int fd; if ((fd = open(filename, O_RDONLY | O_BINARY)) >= 0) { struct rofile* rf; if ((rf = rofopen_sysfd(fd)) != NULL) { struct stat st; if (fstat(fd, &st) == 0) rf->rof_filesize = (uint64_t)st.st_size; rf->u.rof_sys.close_fd = 1; return rf; } close_or_warn(fd); } else { #ifdef USE_TEXTS set_error("open", -1); #endif /* USE_TEXTS */ } return NULL; } _INLINE static int rofread_mem(const char** next, unsigned* size, struct rofile* rf) { if (rf->u.rof_mem.left == 0) return 0; if (rf->u.rof_mem.left >= rf->rof_blocksize) *size = rf->rof_blocksize; else *size = rf->u.rof_mem.left; *next = rf->u.rof_mem.cur; rf->u.rof_mem.cur += *size; rf->u.rof_mem.left -= *size; return 1; } _INLINE static int rofread_mmap(const char** next, unsigned* size, struct rofile* rf) { #ifdef _WIN32 unsigned mapped_size; #endif /* _WIN32 */ if (rf->u.rof_mmap.left == 0) return 0; #ifdef _WIN32 if (rf->u.rof_mmap.view) UnmapViewOfFile(rf->u.rof_mmap.view); mapped_size = rf->u.rof_mmap.left < (uint64_t)rf->rof_blocksize ? (unsigned)rf->u.rof_mmap.left : rf->rof_blocksize; rf->u.rof_mmap.view = MapViewOfFile(rf->u.rof_mmap.map, FILE_MAP_READ, rf->u.rof_mmap.off >> 32, (DWORD)rf->u.rof_mmap.off, mapped_size); if (rf->u.rof_mmap.view == NULL) { #ifdef USE_TEXTS set_error("MapViewOfFile", -1); #endif /* USE_TEXTS */ return -1; } *next = rf->u.rof_mmap.view; rf->u.rof_mmap.off += mapped_size; rf->u.rof_mmap.left -= mapped_size; *size = mapped_size; #else /* !_WIN32 */ if (rf->u.rof_mmap.map) munmap(rf->u.rof_mmap.map, rf->u.rof_mmap.last); rf->u.rof_mmap.last = rf->u.rof_mmap.left < (uint64_t)rf->rof_blocksize ? (unsigned)rf->u.rof_mmap.left : rf->rof_blocksize; rf->u.rof_mmap.map = mmap(0, rf->u.rof_mmap.last, PROT_READ, MAP_SHARED, rf->u.rof_mmap.fd, (off_t)rf->u.rof_mmap.off); if (rf->u.rof_mmap.map == MAP_FAILED) { #ifdef USE_TEXTS set_error("mmap", -1); #endif /* USE_TEXTS */ rf->u.rof_mmap.map = NULL; return -1; } #ifdef _BSD_SOURCE madvise(rf->u.rof_mmap.map, rf->u.rof_mmap.last, MADV_SEQUENTIAL | MADV_WILLNEED); #endif /* _BSD_SOURCE */ *next = (const char*)rf->u.rof_mmap.map; rf->u.rof_mmap.off += rf->u.rof_mmap.last; rf->u.rof_mmap.left -= rf->u.rof_mmap.last; *size = rf->u.rof_mmap.last; #endif /* !_WIN32 */ return 1; } _INLINE static int rofread_sys(const char** next, unsigned* size, struct rofile* rf) { unsigned len = 0; if (rf->u.rof_sys.done) return 0; *next = rf->u.rof_sys.buf; do { int ret; if ((ret = (int)read(rf->u.rof_sys.fd, rf->u.rof_sys.buf + len, rf->rof_blocksize - len)) < 0) { #ifdef _WIN32 /* MSDN says: * _read returns the number of bytes read, which may be less than * count if there are fewer than count bytes left in the file or if * the file was opened in text mode [snip] (nothing about EINTR) */ #else /* !_WIN32 */ /* man 2 read says: * It is not an error if this number is smaller than the number of * bytes requested; this may happen for example because fewer bytes * are actually available right now (maybe because we were close to * end-of-file, or because we are reading from a pipe, or from a * terminal), or because read() was interrupted by a signal. */ if (errno == EINTR) continue; #endif /* !_WIN32 */ #ifdef USE_TEXTS set_error("read", -1); #endif /* USE_TEXTS */ return -1; } else if (ret == 0) { rf->u.rof_sys.done = 1; if (len == 0) return 0; break; } else { len += ret; } } while (len < rf->rof_blocksize); *size = len; return 1; } _INLINE static void rofclose_mem(struct rofile* rf) { free(rf->u.rof_mem.buf); free(rf); } _INLINE static void rofclose_mmap(struct rofile* rf) { #ifdef _WIN32 if (rf->u.rof_mmap.view) UnmapViewOfFile(rf->u.rof_mmap.view); if (rf->u.rof_mmap.map) CloseHandle(rf->u.rof_mmap.map); CloseHandle(rf->u.rof_mmap.fd); #else /* !_WIN32 */ if (rf->u.rof_mmap.map) munmap(rf->u.rof_mmap.map, rf->u.rof_mmap.last); close_or_warn(rf->u.rof_mmap.fd); #endif /* !_WIN32 */ free(rf); } _INLINE static void rofclose_sys(struct rofile* rf) { free(rf->u.rof_sys.buf); if (rf->u.rof_sys.close_fd) close_or_warn(rf->u.rof_sys.fd); #ifdef _WIN32 else if (rf->u.rof_sys.fdmode != O_BINARY) /* Ignore return value.. we can't do anything about it anyway */ setmode(rf->u.rof_sys.fd, rf->u.rof_sys.fdmode); #endif /* _WIN32 */ free(rf); } void rofinfo(unsigned* blocksize, uint64_t* filesize, struct rofile* stream) { *blocksize = stream->rof_blocksize; *filesize = stream->rof_filesize; } int rofread(const char** next, unsigned* size, struct rofile* stream) { /* I assume sysread will be the most used case, check it first */ if (stream->rof_type == SYS) return rofread_sys(next, size, stream); else if (stream->rof_type == MMAP) return rofread_mmap(next, size, stream); else if (stream->rof_type == MEM) return rofread_mem(next, size, stream); return -1; } void rofclose(struct rofile* stream) { if (stream->rof_type == MEM) rofclose_mem(stream); else if (stream->rof_type == MMAP) rofclose_mmap(stream); else if (stream->rof_type == SYS) rofclose_sys(stream); } char* rof_readall(struct rofile* stream, unsigned* length) { int ret; const char* next; char* buf; size_t memsize = 4096, written = 0; unsigned left, blocksize, readsize; uint64_t filesize; if (stream == NULL) return NULL; rofinfo(&blocksize, &filesize, stream); if (filesize != (uint64_t)-1) { memsize = (size_t)filesize; /* Special files may return 0 but contain more data */ if (memsize == 0) memsize = 8; } left = (unsigned)memsize; if ((buf = (char*)malloc(memsize)) == NULL) { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ return NULL; } while ((ret = rofread(&next, &readsize, stream)) > 0) { while (readsize > left) { char* newbuf = NULL; memsize <<= 1; if ((ssize_t)memsize > 0) /* Catch overflow */ newbuf = (char*)realloc(buf, memsize); else errno = ENOMEM; if (newbuf == NULL) { #ifdef USE_TEXTS set_error("realloc", -1); #endif /* USE_TEXTS */ free(buf); return NULL; } buf = newbuf; left = memsize - written; } memcpy(buf + written, next, readsize); written += readsize; left -= readsize; } if (ret == -1) { free(buf); return NULL; } *length = written; return buf; } tthsum-1.3.1/read.h0000664000175000017500000000600611656447501013517 0ustar walterwalter#ifndef INCLUDED_READ_H #define INCLUDED_READ_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Functions to read streams of data, usually from files. It exposes * an opaque rofile struct that you can pass around without having to * worry about what type of thing it is you're reading. Features: the * read operations guarantee to return multiples of 1024 bytes, except * for the last read (at EOF). */ #include "types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * The read-only file stream object, forward declaration of opaque object. */ struct rofile; /** * Construct a rofile object from in-memory data. */ struct rofile* rofopen_mem(const char* data, unsigned length); /** * Construct a rofile object from a file. The reads will use native memory * map functions. */ struct rofile* rofopen_mmap(const char* filename); /** * Construct a rofile object from an open file descriptor. The reads will use * the read(2) syscall. */ struct rofile* rofopen_sysfd(int fd); /** * A shortcut to rofopen_sysfd which opens stdin. */ struct rofile* rofopen_sysfd_stdin(); /** * Construct a rofile object from a file. The reads will use the read(2) * syscall. */ struct rofile* rofopen_sysfile(const char* filename); /** * Get info from the rofile struct. The blocksize specifies the sizes you'll * get with rofread, except for the last read. */ void rofinfo(unsigned* blocksize, uint64_t* filesize, struct rofile* stream); /** * Get the next block of data. Returns 1 when there is data, 0 when there is * not and -1 if an error occurred. rofread will _always_ return blocksize * data, unless the file reaches EOF. */ int rofread(const char** next, unsigned* size, struct rofile* stream); /** * Close the file opened with one of the rofopen functions. */ void rofclose(struct rofile* stream); /** * Read the entire contents of the rofile and close it afterwards. Returns the * contents as a malloc'ed string or NULL on failure. It will accept a NULL as * argument so you can safely use one of the rofopen functions as argument. */ char* rof_readall(struct rofile* stream, unsigned* length); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_READ_H */ tthsum-1.3.1/read_test.c0000664000175000017500000001652611656447501014561 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "read.h" #include "test.h" #include #include #include #include #include #ifndef _WIN32 # include # define O_BINARY 0 #endif /* !_WIN32 */ static const char test_data_src[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus in erat. " "Vivamus lorem felis, tempor a, aliquet a, pretium id, lectus. Maecenas semper" " blandit sem. Aenean faucibus interdum metus. Curabitur quis nulla. Curabitur" " risus massa, commodo sit amet, adipiscing quis, aliquam eu, dolor. Donec nec" " libero. Cras ipsum ante, ultricies in, euismod quis, lobortis ut, turpis. " "Aliquam purus quam, hendrerit et, luctus et, lobortis porttitor, ipsum. " "Mauris ut urna sit amet tellus pretium ullamcorper. Praesent non ante. " "\xff\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\xff\xfe\xfd\xfc\xfb\x84\x83\x82\x81\x80\x7f\x7e\x7d\x7c\x7b\x7a" "123\r\n456\r789\n101"; static char test_data[2048] = {0}; static unsigned test_data_len = 0; static char test_filename[512] = {0}; static int is_multiple_of_two(unsigned len) { unsigned previous = len << 1; while (previous == len << 1) { previous = len; len >>= 1; } return len == 0; } static void init_test_data(const char* src, unsigned length) { test_data[0] = test_data[sizeof(test_data)-1] = '\0'; test_data_len = length; if (test_data_len >= sizeof(test_data)) { fprintf(stderr, "read_test: please increase test_data size\n"); return; } memcpy(test_data, test_data_src, test_data_len); } static void init_test_filename() { #if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || _XOPEN_SOURCE >= 500 int fd; strcpy(test_filename, "test_read.XXXXXX"); if ((fd = mkstemp(test_filename)) < 0) { perror("read_test: error running mkstemp"); test_filename[0] = '\0'; return; } close(fd); #else strcpy(test_filename, "tempfile.bin"); /* XXX not a proper name, no? */ #endif } static void init_test_file(const char* data, unsigned data_len) { FILE* fp; if ((fp = fopen(test_filename, "wb")) == NULL) { perror("read_test: error fopen'ing test_filename for writing"); return; } if (fwrite(data, sizeof(char), data_len, fp) != data_len) { perror("read_test: error fwrite'ing to test_filename"); fclose(fp); return; } if (fflush(fp) != 0) { perror("read_test: error fflush'ing test_filename"); fclose(fp); return; } if (fclose(fp) != 0) perror("read_test: error fclose'ing test_filename"); } static void set_up_file(const char* data, unsigned length) { init_test_filename(); init_test_file(data, length); } static void set_up_file_lorem() { init_test_data(test_data_src, strlen(test_data_src)); /* Cheat a bit: we replace the first \xff in test_data with \x00 */ { char* p = strchr(test_data, '\xff'); if (p == NULL) { fprintf(stderr, "read_test: expected to find \\xff to replace\n"); return; } *p = '\0'; } init_test_filename(); init_test_file(test_data, test_data_len); } static void tear_down_file() { if (test_filename[0] != '\0') { unlink(test_filename); test_filename[0] = '\0'; } } static int test_read(const char* type, struct rofile* rf, const char* compare, unsigned compare_len) { int ret, last_read; unsigned blocksize, getsize; uint64_t filesize; const char *data_p; if (rf == NULL) FAIL1("%s open failed!", type); rofinfo(&blocksize, &filesize, rf); TEST_PASS2(filesize == (uint64_t)compare_len, "File size mismatch: " "expected %u, got %" PRIu64 "\n", compare_len, filesize); TEST_PASS1(is_multiple_of_two(blocksize), "Expected multiple of two for " "block size, got %u", blocksize); last_read = 0; do { if ((ret = rofread(&data_p, &getsize, rf)) < 0) FAIL1("%s's read returned -1", type); if (ret == 0) break; /* We test that all reads are exactly blocksize except the last read. */ if (getsize < blocksize) { TEST_PASS(!last_read, "Previous block returned was too small while not at EOF"); last_read = 1; } TEST_PASS(memcmp(compare, data_p, getsize) == 0, "Data mismatch!"); compare += getsize; } while (ret); return 0; } static int test_readall(const char* type, struct rofile* rf, const char* compare, unsigned compare_len) { unsigned length; char* all = rof_readall(rf, &length); TEST_PASS2(all != NULL, "%s readall returned NULL, rf is %p", type, (const void*)rf); if (rf == NULL) { free(all); FAIL1("%s open returned NULL", type); } if (length != compare_len) { free(all); FAIL3("%s file length %u != %u", type, length, compare_len); } if (memcmp(all, compare, length) != 0) { free(all); FAIL1("%s data mismatch", type); } free(all); return 0; } static int test_read_file(const char* filename, const char* data, unsigned length) { struct rofile* rf = NULL; int i, ret = 0; for (i = 0; i < 6; ++i) { switch (i) { case 0: ret += test_read("rofopen_mem", (rf = rofopen_mem(data, length)), data, length); break; case 1: ret += test_readall("rofopen_mem", (rf = rofopen_mem(data, length)), data, length); break; case 2: ret += test_read("rofopen_mmap", (rf = rofopen_mmap(filename)), data, length); break; case 3: ret += test_readall("rofopen_mmap", (rf = rofopen_mmap(filename)), data, length); break; case 4: ret += test_read("rofopen_sysfile", (rf = rofopen_sysfile(filename)), data, length); break; case 5: ret += test_readall("rofopen_sysfile", (rf = rofopen_sysfile(filename)), data, length); break; } if (rf != NULL) rofclose(rf); } return ret; } static int test_read_file_lorem() { int ret; set_up_file_lorem(); ret = test_read_file(test_filename, test_data, test_data_len); tear_down_file(); return ret; } static int test_read_file_85s() { unsigned len = 3 * 16 * 1024 * 1024 - 123; char* data; int ret; if ((data = (char*)malloc(len)) == NULL) FAIL("not enough memory"); memset(data, 85, len); data[0] = '\0'; data[len - 1] = '\xff'; set_up_file(data, len); ret = test_read_file(test_filename, data, len); tear_down_file(); free(data); return ret; } static int test_readall_properties() { unsigned unused; TEST_PASS(rof_readall(NULL, &unused) == NULL, "rof_readall should return NULL when rf is NULL"); return 0; } TESTS(read_test) TEST(test_read_file_lorem); TEST(test_read_file_85s); TEST(test_readall_properties); ENDTESTS tthsum-1.3.1/test.c0000664000175000017500000000474311656447501013564 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include extern int base32_test(unsigned*, unsigned*); extern int endian_test(unsigned*, unsigned*); extern int escape_test(unsigned*, unsigned*); extern int getopt_test(unsigned*, unsigned*); extern int read_test(unsigned*, unsigned*); #ifdef USE_TEXTS extern int texts_test(unsigned*, unsigned*); #endif /* !USE_TEXTS */ extern int thex_test(unsigned*, unsigned*); extern int tiger_test(unsigned*, unsigned*); extern int types_test(unsigned*, unsigned*); extern int utf8_test(unsigned*, unsigned*); int main() { unsigned success = 0; unsigned failure = 0; printf("============================================\n"); printf(" RUNNING TESTS\n"); printf("--------------------------------------------\n"); printf(" Language\n--------------------------------------------\n"); endian_test(&success, &failure); types_test(&success, &failure); printf("--------------------------------------------\n"); printf(" Util\n--------------------------------------------\n"); base32_test(&success, &failure); escape_test(&success, &failure); getopt_test(&success, &failure); read_test(&success, &failure); utf8_test(&success, &failure); printf("--------------------------------------------\n"); printf(" App\n--------------------------------------------\n"); #ifdef USE_TEXTS texts_test(&success, &failure); #endif /* USE_TEXTS */ tiger_test(&success, &failure); thex_test(&success, &failure); printf("--------------------------------------------\n"); printf(" Tests completed: %u succeeded, %u failed\n", success, failure); printf("============================================\n"); if (failure) return 1; return 0; } tthsum-1.3.1/test.h0000664000175000017500000000447511656447501013573 0ustar walterwalter#ifndef INCLUDED_TEST_H #define INCLUDED_TEST_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Utility macros for the test suite. You'll find some duplicate code * below because macro varargs are not portable. */ #include #define TESTS(title) \ void title(unsigned* success, unsigned *failure) { \ printf("+ " #title ": "); #define TEST(func) \ do { \ if (func() == 0) { \ printf("."); \ ++*success; \ } else { \ printf("F"); \ ++*failure; \ } \ } while (0) #define ENDTESTS \ printf("\n"); \ } #define FAIL(msg) \ do { \ fprintf(stderr, ">>> %s:%i: " msg "\n", __FILE__, __LINE__); \ return 1; \ } while(0) #define FAIL1(msg, a) \ do { \ fprintf(stderr, ">>> %s:%i: " msg "\n", __FILE__, __LINE__, a); \ return 1; \ } while(0) #define FAIL2(msg, a, b) \ do { \ fprintf(stderr, ">>> %s:%i: " msg "\n", __FILE__, __LINE__, a, b); \ return 1; \ } while(0) #define FAIL3(msg, a, b, c) \ do { \ fprintf(stderr, ">>> %s:%i: " msg "\n", __FILE__, __LINE__, a, b, c); \ return 1; \ } while(0) #define TEST_PASS(test, msg) \ do { \ if (!(test)) \ FAIL(msg); \ } while(0) #define TEST_PASS1(test, msg, a) \ do { \ if (!(test)) \ FAIL1(msg, a); \ } while(0) #define TEST_PASS2(test, msg, a, b) \ do { \ if (!(test)) \ FAIL2(msg, a, b); \ } while(0) #define TEST_PASS3(test, msg, a, b, c) \ do { \ if (!(test)) \ FAIL3(msg, a, b, c); \ } while(0) #endif /* INCLUDED_TEST_H */ tthsum-1.3.1/texts.c0000664000175000017500000000646711656447501013761 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "texts.h" #include #ifdef _WIN32 # define WINDOWS_LEAN_AND_MEAN # include #else /* !_WIN32 */ # include # include # include #endif /* !_WIN32 */ static int last_error = 0; static int last_error_os = 0; static const char* last_error_context = 0; static char last_error_buf[512]; static const char* texts[] = { /* ERROR_FIRST */ "No error yet", /* BASE32_INVALID_CHARACTER */ "Invalid character encountered in BASE32 stream", /* ESCAPE_INVALID_ESCAPE */ "Invalid escape sequence encountered", /* TEXTS_UNKNOWN_ERROR */ "Unknown error", /* THEX_INVALID_BLOCK_SIZE */ "The read operation isn't supplying multiples of 1024", /* TTHSUM_FILENAME_TOO_LARGE */ "File name is too long", /* TTHSUM_LINE_CORRUPT */ "Improperly formatted line", /* TTHSUM_MISMATCHED_TTH */ "TTH check failed for", /* UTF8_INVALID_UNICODE */ "Invalid character encountered in UNICODE stream", /* UTF8_INVALID_UTF8 */ "Invalid character encountered in UTF8 stream", /* UTF8_OVERLONG_UTF8 */ "Overlong character encountered in UTF8 stream" /* ERROR_LAST */ }; void set_error(char const* context, int error) { assert(strlen(context) < 32); if (error == -1) { #ifdef _WIN32 last_error = GetLastError(); #else /* !_WIN32 */ last_error = errno; #endif /* !_WIN32 */ last_error_os = 1; } else { last_error = error; last_error_os = 0; } last_error_context = context; } const char* get_error() { if (!last_error_os) { return texts[last_error]; } else { #ifdef _WIN32 DWORD w; int i; i = sprintf(last_error_buf, "%s: ", last_error_context); if ((w = FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD)last_error, 0, last_error_buf + i, 480 - i, NULL) ) != 0) { /* 32 is more than enough for " (int)" */ if (w >= 2) sprintf(last_error_buf + i + w - 2, " (0x%x)", last_error); } else { sprintf(last_error_buf + i, ": %s (0x%x)", get_text(TEXTS_UNKNOWN_ERROR), (unsigned)last_error); } #else /* !_WIN32 */ /* Avoid snprintf because it's not C90 */ /* XXX this needs overflow checks! use strncpy and such! */ /* was snprintf(last_error_buf, 511, ...) */ sprintf(last_error_buf, "%s: %s (%i)", last_error_context, strerror(last_error), last_error); #endif /* !_WIN32 */ return last_error_buf; } } const char* get_text(enum text_id id) { return texts[id]; } tthsum-1.3.1/texts.h0000664000175000017500000000424311656447501013754 0ustar walterwalter#ifndef INCLUDED_TEXTS_H #define INCLUDED_TEXTS_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Help and error texts for the tthsum application and the units that * tthsum consists of. Using texts is entirely optional: unless you * define USE_TEXTS, no tthsum unit will try to call any of these * functions. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * The texts by id. If messages are to be translated, only the texts unit will * have to be modified. */ enum text_id { ERROR_FIRST, BASE32_INVALID_CHARACTER, ESCAPE_INVALID_ESCAPE, TEXTS_UNKNOWN_ERROR, THEX_INVALID_BLOCK_SIZE, TTHSUM_FILENAME_TOO_LARGE, TTHSUM_LINE_CORRUPT, TTHSUM_MISMATCHED_TTH, UTF8_INVALID_UNICODE, UTF8_INVALID_UTF8, UTF8_OVERLONG_UTF8, ERROR_LAST }; /** * Set the last error: context is a short string specifying which function * caused the error, error defines what the error was. Specify the error by * text_id or -1 if you want to get the native OS-error message (from a library * call). */ void set_error(const char* context, int error); /** * Get the set error as a descriptive message including the context. */ const char* get_error(); /** * Get a specific text. */ const char* get_text(enum text_id id); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_TEXTS_H */ tthsum-1.3.1/texts_test.c0000664000175000017500000000404611656447501015007 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "texts.h" #include "test.h" #include #include #include static int test_texts_initial() { set_error("some context", ERROR_FIRST); /* reset errors */ TEST_PASS(strcmp(get_error(), "No error yet") == 0, "No-error-yet text is wrong"); return 0; } static int test_texts_enum() { int tid; for (tid = ERROR_FIRST; tid != ERROR_LAST; ++tid) { set_error("another context", tid); TEST_PASS1(strcmp(get_error(), get_text((enum text_id)tid)) == 0, "Error text mismatch for text id %i", tid); } return 0; } static int test_texts_oserror() { open("", O_RDONLY); set_error("yet another context", -1); #ifdef _WIN32 TEST_PASS1(strcmp(get_error(), "yet another context: " "The system cannot find the path specified. (0x3)") == 0, "OS error text mismatch, got: \"%s\"", get_error()); #else /* !_WIN32 */ TEST_PASS1(strcmp(get_error(), "yet another context: " "No such file or directory (2)") == 0, "OS error text mismatch, got: \"%s\"", get_error()); #endif /* !_WIN32 */ return 0; } TESTS(texts_test) TEST(test_texts_initial); TEST(test_texts_enum); TEST(test_texts_oserror); ENDTESTS tthsum-1.3.1/thex.c0000664000175000017500000001043211656447501013545 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009,2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "thex.h" #include "endian.h" #include "read.h" #include "tiger.h" #include #include #ifdef USE_TEXTS # include "texts.h" #endif /* USE_TEXTS */ #define TWO_HASH_OCTETS (2*3*8) static unsigned get_progress_mask(uint64_t filesize) { unsigned bit = 2; for (filesize >>= 18; filesize != 0; filesize >>= 1) bit <<= 1; return bit - 1; } int thex_tiger_root(struct rofile* stream, uint64_t* result, void (*progress_func)(uint64_t,uint64_t)) { int ret; unsigned progress_mask = 0x7fff; /* Read data */ unsigned blocksize; uint64_t filesize; /* Tiger data */ uint64_t data[128]; /* with 128, we have enough room for a 2^137B file */ uint64_t leafcount = 0; unsigned pos = 0; /* Assert that the blocksize is a multiple of 1024 */ rofinfo(&blocksize, &filesize, stream); if (blocksize % 1024 != 0) { #ifdef USE_TEXTS set_error("thex_tiger_root", THEX_INVALID_BLOCK_SIZE); #endif /* USE_TEXTS */ return -1; } /* Get number progress_func mask to check against leafcount */ if (filesize != (uint64_t)-1) progress_mask = get_progress_mask(filesize); #if 0 /* 4gb == 2^42, requires 33 blocks */ if (filesize >= 1024) tthblocks = (int)ceil(log((double)filesize / 1024.0) / log(2)) + 1; else tthblocks = 1; printf("fs = %lli, tths = %u\r\n", filesize, tthblocks); data = (uint64_t*)malloc(tthblocks * 3 * sizeof(uint64_t)); #endif while (1) { const char* p; unsigned size; /* Read block of data */ ret = rofread(&p, &size, stream); if (ret <= 0) break; /* Iterate over our fetched block of data */ while (1) { unsigned i; tiger_bp(0x00, p, size < 1024 ? size : 1024, data + pos); /* Print progress */ if (progress_func && ((unsigned)leafcount & progress_mask) == 0) { progress_func(leafcount * 1024, filesize); } /* Merge backwards */ ++leafcount; for (i = 2; (unsigned)leafcount % i == 0; i *= 2) { #if BYTE_ORDER == BIG_ENDIAN uint8_t temp[TWO_HASH_OCTETS]; int j; pos -= 3; for (j = 0; j < TWO_HASH_OCTETS; ++j) temp[j ^ 7] = ((uint8_t*)(data + pos))[j]; tiger_bp(0x01, &temp[0], TWO_HASH_OCTETS, data + pos); #else /* BYTE_ORDER != BIG_ENDIAN */ uint64_t temp[3]; pos -= 3; tiger_bp(0x01, data + pos, TWO_HASH_OCTETS, temp); data[pos] = temp[0]; data[pos + 1] = temp[1]; data[pos + 2] = temp[2]; #endif /* BYTE_ORDER != BIG_ENDIAN */ } pos += 3; if (size <= 1024) break; size -= 1024; p += 1024; } } if (progress_func) progress_func(leafcount, filesize); /* Did some error occur? */ if (ret == -1) return ret; if (pos == 0) { /* Nothing written, create the single leaf root */ tiger_bp(0x00, (const void*)0, 0, data); } else { /* Merge backwards */ pos -= 3; while (pos != 0) { #if BYTE_ORDER == BIG_ENDIAN uint8_t temp[TWO_HASH_OCTETS]; int j; pos -= 3; for (j = 0; j < TWO_HASH_OCTETS; ++j) temp[j ^ 7] = ((const uint8_t*)(data + pos))[j]; tiger_bp(0x01, &temp[0], TWO_HASH_OCTETS, data + pos); #else /* BYTE_ORDER != BIG_ENDIAN */ uint64_t temp[3]; pos -= 3; tiger_bp(0x01, data + pos, TWO_HASH_OCTETS, temp); data[pos] = temp[0]; data[pos + 1] = temp[1]; data[pos + 2] = temp[2]; #endif /* BYTE_ORDER != BIG_ENDIAN */ } } /* Done, return success */ result[0] = data[0]; result[1] = data[1]; result[2] = data[2]; return 0; } tthsum-1.3.1/thex.h0000664000175000017500000000261111656447501013552 0ustar walterwalter#ifndef INCLUDED_THEX_H #define INCLUDED_THEX_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Calculates the root of the merkle hash tree. */ #include "read.h" #include "types.h" #ifdef __cplusplus extern "C" { #endif /** * Calculate the THEX/Tiger (TTH) root of the specified file. * The root hash will be placed in res which must be at least 3 uint64_t's * long. */ int thex_tiger_root(struct rofile* stream, uint64_t* result, void (*progress_func)(uint64_t,uint64_t)); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_THEX_H */ tthsum-1.3.1/thex_test.c0000664000175000017500000001252111656447501014605 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009,2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "thex.h" #include "base32.h" #include "test.h" #include static int thex_cmp(struct rofile* stream, const char* base32) { /* Don't forget to zero out cmpres/tstres */ uint64_t cmpres[3] = {_ULL(0), _ULL(0), _ULL(0)}; uint64_t tstres[3] = {_ULL(0), _ULL(0), _ULL(0)}; char tstbase32[40]; if (base32touint64(&cmpres[0], base32, 3) == -1) FAIL1("base32touint64 returned -1 on %s", base32); if (thex_tiger_root(stream, &tstres[0], NULL) == -1) FAIL1("thex_tiger_root returned -1 on %s", base32); if (uint64tobase32(tstbase32, tstres, 3) == -1) FAIL1("uint64tobase32 returned -1 on %s", base32); if (memcmp(&cmpres[0], &tstres[0], 3 * sizeof(uint64_t)) != 0) { unsigned i; char hexbuf[49]; memset(hexbuf, '.', 48); hexbuf[48] = '\0'; for (i = 0; i < 3 * sizeof(uint64_t); ++i) { char cmphigh = (char)(*(((uint8_t*)&cmpres[0]) + i) >> 4); char cmplow = (char)(*(((uint8_t*)&cmpres[0]) + i) & 0xf); char tsthigh = (char)(*(((uint8_t*)&tstres[0]) + i) >> 4); char tstlow = (char)(*(((uint8_t*)&tstres[0]) + i) & 0xf); if (cmphigh != tsthigh) hexbuf[2*i] = tsthigh >= 10 ? 'a'+(tsthigh-10) : '0'+tsthigh; if (cmplow != tstlow) hexbuf[2*i+1] = tstlow >= 10 ? 'a'+(tstlow-10) : '0'+tstlow; } FAIL3("memcmp: mismatch on %s != %s: %s", base32, tstbase32, hexbuf); } return 0; } static int thex_memcmp(const char* data, unsigned length, const char* base32) { int ret; struct rofile* stream; stream = rofopen_mem(data, length); if (stream == NULL) FAIL1("rofopen_mem failed on %s", base32); ret = thex_cmp(stream, base32); rofclose(stream); return ret; } static int thex_strcmp(const char* str, const char* base32) { return thex_memcmp(str, strlen(str), base32); } static int test_standard_hashes() { char buf[1026]; int i; for (i = 0; i < 1025; ++i) buf[i] = 'A'; buf[1025] = '\0'; return thex_strcmp("", "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ") + thex_memcmp("\0", 1, "VK54ZIEEVTWNAUI5D5RDFIL37LX2IQNSTAXFKSA") + thex_memcmp(buf, 1024, "L66Q4YVNAFWVS23X2HJIRA5ZJ7WXR3F26RSASFA") + thex_memcmp(buf, 1025, "PZMRYHGY6LTBEH63ZWAHDORHSYTLO4LEFUIKHWY"); } static int test_extra_hashes() { #define buflen (20 * 1024 * 28) /* \x00A-Z\xFF */ char buf[buflen]; int i; for (i = 0; i < buflen; i += 28) memcpy(buf + i, "\x00" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "\xff", 28); return thex_strcmp("abcdefghijklmnopqrstuvwxyz", "LMHNA2VYO465P2RDOGTR2CL6XKHZNI2X4CCUY5Y") + thex_memcmp("\xff\x00\x01", 3, "BRA2Y3Q5YXZKONQOTBA5BMIWTWMFVFISP3AFLUY") + thex_memcmp(buf, buflen, /* 573440 */ "YWCGBHG5J26IDNFH3M55MR7674GYLSBXBWITCZA") + thex_memcmp(buf, buflen - 5463, /* 567977 */ "OQMPMBCCCTSJJSKNO3FGFZX4T636THZB57UT7HI"); #undef buflen } static int test_pavelch_hashes() { char buf[256]; int i; for (i = 0; i < 256; ++i) buf[i] = (char)i; return thex_memcmp(buf, 125, "B5LOOSIJN7KWAWIJUJPNHKLCZ5TGDZ34NKB7LVA") + thex_memcmp(buf, 126, "UFWW3Q7PYSXGWUACF6C5F4377A4BYNUM5JENX6Y") + thex_memcmp(buf, 127, "YJ6JWRX74NIKSRYWR2MVUEHF2K2RKUEHDK6MG7I") + thex_memcmp(buf, 128, "ZU6NIYQCFYZKUZHOJABKACHEQV7GQMT75Q7H6MQ") + thex_memcmp(buf, 129, "3YDAQRYUVS5DZNQWTJNXIQZ65PJV22VQ6HEY32I") /* +1 */ + thex_memcmp(buf + 1, 125, "CXMZBH4NNFUJ47TYUDNZFAMUUWLCHZZFHKU5IAA") + thex_memcmp(buf + 1, 126, "3Y4VRHOMBRSUQZ4UHAAZI24YRCZUOUTCPHFBLPI") + thex_memcmp(buf + 1, 127, "GT5HY5HOM7A7SLAL4HH5JMXUNIKP7OMZMBESL5Q") + thex_memcmp(buf + 1, 128, "32RM6ILFACIWWHX4JGFYI5U5CD6CUTYFDHR5POI") + thex_memcmp(buf + 1, 129, "DGD6BKKGH3AQUVA7DDOZWS2LRPYTCG5C23GNLKA") /* +2 */ + thex_memcmp(buf + 2, 125, "LGBYVEKTCQ5FYMU4XDQN2CN63J3JDFY4IABMETA") + thex_memcmp(buf + 2, 126, "T7IEE2ZZJ3XI2QUSJSKOKXGC74KFT44M5FSX6WA") + thex_memcmp(buf + 2, 127, "7KWOAII6AEAV67SK2ACZMN3HTN2ZYBNRSSUKGLA") + thex_memcmp(buf + 2, 128, "XRTRHLCALO34QVC6NSXY4JTSC6THMGFXRUIW72I") + thex_memcmp(buf + 2, 129, "O74RH63EWYNJHAFE7PXUF3JD4LQWGJOGLS4UU4Q") /* last */ + thex_memcmp(buf, 254, "V7NMKNTONQNSWUQENDMHVLPFLIXKGDDQBIWJHYA") + thex_memcmp(buf, 255, "A7NQ5IZLVIPPHVDFAFHA5TDSBYJ5MKYTQMRJNBA") + thex_memcmp(buf, 256, "YAJKVS45WRYJNA3IO4FWTYFXNTDHBEWMDGU465I") + thex_memcmp(buf + 1, 254, "SCIIV6BFYPFII5GNTWGEEAPBUEXJOYYP67LOGVA") + thex_memcmp(buf + 1, 255, "UMC6OJR6MLYN6ZWWL2XM5CQC7TROEI4P67C4PJQ") + thex_memcmp(buf + 2, 254, "7HJFO26TDOH6T3KDYSI37EAXLYN3KL6SZBQLZMY"); } TESTS(thex_test) TEST(test_standard_hashes); TEST(test_extra_hashes); TEST(test_pavelch_hashes); ENDTESTS tthsum-1.3.1/tiger.c0000664000175000017500000014240011656447501013710 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009,2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================== The greater part of this source comes from the creators of the Tiger Hash algorithm, Ross Anderson and Eli Biham. ======================================================================*/ #include "tiger.h" #include "endian.h" #include #include /* Tiger S boxes */ static uint64_t tiger_sboxes[1024] = { _ULL(0x02AAB17CF7E90C5E) /* 0 */, _ULL(0xAC424B03E243A8EC) /* 1 */, _ULL(0x72CD5BE30DD5FCD3) /* 2 */, _ULL(0x6D019B93F6F97F3A) /* 3 */, _ULL(0xCD9978FFD21F9193) /* 4 */, _ULL(0x7573A1C9708029E2) /* 5 */, _ULL(0xB164326B922A83C3) /* 6 */, _ULL(0x46883EEE04915870) /* 7 */, _ULL(0xEAACE3057103ECE6) /* 8 */, _ULL(0xC54169B808A3535C) /* 9 */, _ULL(0x4CE754918DDEC47C) /* 10 */, _ULL(0x0AA2F4DFDC0DF40C) /* 11 */, _ULL(0x10B76F18A74DBEFA) /* 12 */, _ULL(0xC6CCB6235AD1AB6A) /* 13 */, _ULL(0x13726121572FE2FF) /* 14 */, _ULL(0x1A488C6F199D921E) /* 15 */, _ULL(0x4BC9F9F4DA0007CA) /* 16 */, _ULL(0x26F5E6F6E85241C7) /* 17 */, _ULL(0x859079DBEA5947B6) /* 18 */, _ULL(0x4F1885C5C99E8C92) /* 19 */, _ULL(0xD78E761EA96F864B) /* 20 */, _ULL(0x8E36428C52B5C17D) /* 21 */, _ULL(0x69CF6827373063C1) /* 22 */, _ULL(0xB607C93D9BB4C56E) /* 23 */, _ULL(0x7D820E760E76B5EA) /* 24 */, _ULL(0x645C9CC6F07FDC42) /* 25 */, _ULL(0xBF38A078243342E0) /* 26 */, _ULL(0x5F6B343C9D2E7D04) /* 27 */, _ULL(0xF2C28AEB600B0EC6) /* 28 */, _ULL(0x6C0ED85F7254BCAC) /* 29 */, _ULL(0x71592281A4DB4FE5) /* 30 */, _ULL(0x1967FA69CE0FED9F) /* 31 */, _ULL(0xFD5293F8B96545DB) /* 32 */, _ULL(0xC879E9D7F2A7600B) /* 33 */, _ULL(0x860248920193194E) /* 34 */, _ULL(0xA4F9533B2D9CC0B3) /* 35 */, _ULL(0x9053836C15957613) /* 36 */, _ULL(0xDB6DCF8AFC357BF1) /* 37 */, _ULL(0x18BEEA7A7A370F57) /* 38 */, _ULL(0x037117CA50B99066) /* 39 */, _ULL(0x6AB30A9774424A35) /* 40 */, _ULL(0xF4E92F02E325249B) /* 41 */, _ULL(0x7739DB07061CCAE1) /* 42 */, _ULL(0xD8F3B49CECA42A05) /* 43 */, _ULL(0xBD56BE3F51382F73) /* 44 */, _ULL(0x45FAED5843B0BB28) /* 45 */, _ULL(0x1C813D5C11BF1F83) /* 46 */, _ULL(0x8AF0E4B6D75FA169) /* 47 */, _ULL(0x33EE18A487AD9999) /* 48 */, _ULL(0x3C26E8EAB1C94410) /* 49 */, _ULL(0xB510102BC0A822F9) /* 50 */, _ULL(0x141EEF310CE6123B) /* 51 */, _ULL(0xFC65B90059DDB154) /* 52 */, _ULL(0xE0158640C5E0E607) /* 53 */, _ULL(0x884E079826C3A3CF) /* 54 */, _ULL(0x930D0D9523C535FD) /* 55 */, _ULL(0x35638D754E9A2B00) /* 56 */, _ULL(0x4085FCCF40469DD5) /* 57 */, _ULL(0xC4B17AD28BE23A4C) /* 58 */, _ULL(0xCAB2F0FC6A3E6A2E) /* 59 */, _ULL(0x2860971A6B943FCD) /* 60 */, _ULL(0x3DDE6EE212E30446) /* 61 */, _ULL(0x6222F32AE01765AE) /* 62 */, _ULL(0x5D550BB5478308FE) /* 63 */, _ULL(0xA9EFA98DA0EDA22A) /* 64 */, _ULL(0xC351A71686C40DA7) /* 65 */, _ULL(0x1105586D9C867C84) /* 66 */, _ULL(0xDCFFEE85FDA22853) /* 67 */, _ULL(0xCCFBD0262C5EEF76) /* 68 */, _ULL(0xBAF294CB8990D201) /* 69 */, _ULL(0xE69464F52AFAD975) /* 70 */, _ULL(0x94B013AFDF133E14) /* 71 */, _ULL(0x06A7D1A32823C958) /* 72 */, _ULL(0x6F95FE5130F61119) /* 73 */, _ULL(0xD92AB34E462C06C0) /* 74 */, _ULL(0xED7BDE33887C71D2) /* 75 */, _ULL(0x79746D6E6518393E) /* 76 */, _ULL(0x5BA419385D713329) /* 77 */, _ULL(0x7C1BA6B948A97564) /* 78 */, _ULL(0x31987C197BFDAC67) /* 79 */, _ULL(0xDE6C23C44B053D02) /* 80 */, _ULL(0x581C49FED002D64D) /* 81 */, _ULL(0xDD474D6338261571) /* 82 */, _ULL(0xAA4546C3E473D062) /* 83 */, _ULL(0x928FCE349455F860) /* 84 */, _ULL(0x48161BBACAAB94D9) /* 85 */, _ULL(0x63912430770E6F68) /* 86 */, _ULL(0x6EC8A5E602C6641C) /* 87 */, _ULL(0x87282515337DDD2B) /* 88 */, _ULL(0x2CDA6B42034B701B) /* 89 */, _ULL(0xB03D37C181CB096D) /* 90 */, _ULL(0xE108438266C71C6F) /* 91 */, _ULL(0x2B3180C7EB51B255) /* 92 */, _ULL(0xDF92B82F96C08BBC) /* 93 */, _ULL(0x5C68C8C0A632F3BA) /* 94 */, _ULL(0x5504CC861C3D0556) /* 95 */, _ULL(0xABBFA4E55FB26B8F) /* 96 */, _ULL(0x41848B0AB3BACEB4) /* 97 */, _ULL(0xB334A273AA445D32) /* 98 */, _ULL(0xBCA696F0A85AD881) /* 99 */, _ULL(0x24F6EC65B528D56C) /* 100 */, _ULL(0x0CE1512E90F4524A) /* 101 */, _ULL(0x4E9DD79D5506D35A) /* 102 */, _ULL(0x258905FAC6CE9779) /* 103 */, _ULL(0x2019295B3E109B33) /* 104 */, _ULL(0xF8A9478B73A054CC) /* 105 */, _ULL(0x2924F2F934417EB0) /* 106 */, _ULL(0x3993357D536D1BC4) /* 107 */, _ULL(0x38A81AC21DB6FF8B) /* 108 */, _ULL(0x47C4FBF17D6016BF) /* 109 */, _ULL(0x1E0FAADD7667E3F5) /* 110 */, _ULL(0x7ABCFF62938BEB96) /* 111 */, _ULL(0xA78DAD948FC179C9) /* 112 */, _ULL(0x8F1F98B72911E50D) /* 113 */, _ULL(0x61E48EAE27121A91) /* 114 */, _ULL(0x4D62F7AD31859808) /* 115 */, _ULL(0xECEBA345EF5CEAEB) /* 116 */, _ULL(0xF5CEB25EBC9684CE) /* 117 */, _ULL(0xF633E20CB7F76221) /* 118 */, _ULL(0xA32CDF06AB8293E4) /* 119 */, _ULL(0x985A202CA5EE2CA4) /* 120 */, _ULL(0xCF0B8447CC8A8FB1) /* 121 */, _ULL(0x9F765244979859A3) /* 122 */, _ULL(0xA8D516B1A1240017) /* 123 */, _ULL(0x0BD7BA3EBB5DC726) /* 124 */, _ULL(0xE54BCA55B86ADB39) /* 125 */, _ULL(0x1D7A3AFD6C478063) /* 126 */, _ULL(0x519EC608E7669EDD) /* 127 */, _ULL(0x0E5715A2D149AA23) /* 128 */, _ULL(0x177D4571848FF194) /* 129 */, _ULL(0xEEB55F3241014C22) /* 130 */, _ULL(0x0F5E5CA13A6E2EC2) /* 131 */, _ULL(0x8029927B75F5C361) /* 132 */, _ULL(0xAD139FABC3D6E436) /* 133 */, _ULL(0x0D5DF1A94CCF402F) /* 134 */, _ULL(0x3E8BD948BEA5DFC8) /* 135 */, _ULL(0xA5A0D357BD3FF77E) /* 136 */, _ULL(0xA2D12E251F74F645) /* 137 */, _ULL(0x66FD9E525E81A082) /* 138 */, _ULL(0x2E0C90CE7F687A49) /* 139 */, _ULL(0xC2E8BCBEBA973BC5) /* 140 */, _ULL(0x000001BCE509745F) /* 141 */, _ULL(0x423777BBE6DAB3D6) /* 142 */, _ULL(0xD1661C7EAEF06EB5) /* 143 */, _ULL(0xA1781F354DAACFD8) /* 144 */, _ULL(0x2D11284A2B16AFFC) /* 145 */, _ULL(0xF1FC4F67FA891D1F) /* 146 */, _ULL(0x73ECC25DCB920ADA) /* 147 */, _ULL(0xAE610C22C2A12651) /* 148 */, _ULL(0x96E0A810D356B78A) /* 149 */, _ULL(0x5A9A381F2FE7870F) /* 150 */, _ULL(0xD5AD62EDE94E5530) /* 151 */, _ULL(0xD225E5E8368D1427) /* 152 */, _ULL(0x65977B70C7AF4631) /* 153 */, _ULL(0x99F889B2DE39D74F) /* 154 */, _ULL(0x233F30BF54E1D143) /* 155 */, _ULL(0x9A9675D3D9A63C97) /* 156 */, _ULL(0x5470554FF334F9A8) /* 157 */, _ULL(0x166ACB744A4F5688) /* 158 */, _ULL(0x70C74CAAB2E4AEAD) /* 159 */, _ULL(0xF0D091646F294D12) /* 160 */, _ULL(0x57B82A89684031D1) /* 161 */, _ULL(0xEFD95A5A61BE0B6B) /* 162 */, _ULL(0x2FBD12E969F2F29A) /* 163 */, _ULL(0x9BD37013FEFF9FE8) /* 164 */, _ULL(0x3F9B0404D6085A06) /* 165 */, _ULL(0x4940C1F3166CFE15) /* 166 */, _ULL(0x09542C4DCDF3DEFB) /* 167 */, _ULL(0xB4C5218385CD5CE3) /* 168 */, _ULL(0xC935B7DC4462A641) /* 169 */, _ULL(0x3417F8A68ED3B63F) /* 170 */, _ULL(0xB80959295B215B40) /* 171 */, _ULL(0xF99CDAEF3B8C8572) /* 172 */, _ULL(0x018C0614F8FCB95D) /* 173 */, _ULL(0x1B14ACCD1A3ACDF3) /* 174 */, _ULL(0x84D471F200BB732D) /* 175 */, _ULL(0xC1A3110E95E8DA16) /* 176 */, _ULL(0x430A7220BF1A82B8) /* 177 */, _ULL(0xB77E090D39DF210E) /* 178 */, _ULL(0x5EF4BD9F3CD05E9D) /* 179 */, _ULL(0x9D4FF6DA7E57A444) /* 180 */, _ULL(0xDA1D60E183D4A5F8) /* 181 */, _ULL(0xB287C38417998E47) /* 182 */, _ULL(0xFE3EDC121BB31886) /* 183 */, _ULL(0xC7FE3CCC980CCBEF) /* 184 */, _ULL(0xE46FB590189BFD03) /* 185 */, _ULL(0x3732FD469A4C57DC) /* 186 */, _ULL(0x7EF700A07CF1AD65) /* 187 */, _ULL(0x59C64468A31D8859) /* 188 */, _ULL(0x762FB0B4D45B61F6) /* 189 */, _ULL(0x155BAED099047718) /* 190 */, _ULL(0x68755E4C3D50BAA6) /* 191 */, _ULL(0xE9214E7F22D8B4DF) /* 192 */, _ULL(0x2ADDBF532EAC95F4) /* 193 */, _ULL(0x32AE3909B4BD0109) /* 194 */, _ULL(0x834DF537B08E3450) /* 195 */, _ULL(0xFA209DA84220728D) /* 196 */, _ULL(0x9E691D9B9EFE23F7) /* 197 */, _ULL(0x0446D288C4AE8D7F) /* 198 */, _ULL(0x7B4CC524E169785B) /* 199 */, _ULL(0x21D87F0135CA1385) /* 200 */, _ULL(0xCEBB400F137B8AA5) /* 201 */, _ULL(0x272E2B66580796BE) /* 202 */, _ULL(0x3612264125C2B0DE) /* 203 */, _ULL(0x057702BDAD1EFBB2) /* 204 */, _ULL(0xD4BABB8EACF84BE9) /* 205 */, _ULL(0x91583139641BC67B) /* 206 */, _ULL(0x8BDC2DE08036E024) /* 207 */, _ULL(0x603C8156F49F68ED) /* 208 */, _ULL(0xF7D236F7DBEF5111) /* 209 */, _ULL(0x9727C4598AD21E80) /* 210 */, _ULL(0xA08A0896670A5FD7) /* 211 */, _ULL(0xCB4A8F4309EBA9CB) /* 212 */, _ULL(0x81AF564B0F7036A1) /* 213 */, _ULL(0xC0B99AA778199ABD) /* 214 */, _ULL(0x959F1EC83FC8E952) /* 215 */, _ULL(0x8C505077794A81B9) /* 216 */, _ULL(0x3ACAAF8F056338F0) /* 217 */, _ULL(0x07B43F50627A6778) /* 218 */, _ULL(0x4A44AB49F5ECCC77) /* 219 */, _ULL(0x3BC3D6E4B679EE98) /* 220 */, _ULL(0x9CC0D4D1CF14108C) /* 221 */, _ULL(0x4406C00B206BC8A0) /* 222 */, _ULL(0x82A18854C8D72D89) /* 223 */, _ULL(0x67E366B35C3C432C) /* 224 */, _ULL(0xB923DD61102B37F2) /* 225 */, _ULL(0x56AB2779D884271D) /* 226 */, _ULL(0xBE83E1B0FF1525AF) /* 227 */, _ULL(0xFB7C65D4217E49A9) /* 228 */, _ULL(0x6BDBE0E76D48E7D4) /* 229 */, _ULL(0x08DF828745D9179E) /* 230 */, _ULL(0x22EA6A9ADD53BD34) /* 231 */, _ULL(0xE36E141C5622200A) /* 232 */, _ULL(0x7F805D1B8CB750EE) /* 233 */, _ULL(0xAFE5C7A59F58E837) /* 234 */, _ULL(0xE27F996A4FB1C23C) /* 235 */, _ULL(0xD3867DFB0775F0D0) /* 236 */, _ULL(0xD0E673DE6E88891A) /* 237 */, _ULL(0x123AEB9EAFB86C25) /* 238 */, _ULL(0x30F1D5D5C145B895) /* 239 */, _ULL(0xBB434A2DEE7269E7) /* 240 */, _ULL(0x78CB67ECF931FA38) /* 241 */, _ULL(0xF33B0372323BBF9C) /* 242 */, _ULL(0x52D66336FB279C74) /* 243 */, _ULL(0x505F33AC0AFB4EAA) /* 244 */, _ULL(0xE8A5CD99A2CCE187) /* 245 */, _ULL(0x534974801E2D30BB) /* 246 */, _ULL(0x8D2D5711D5876D90) /* 247 */, _ULL(0x1F1A412891BC038E) /* 248 */, _ULL(0xD6E2E71D82E56648) /* 249 */, _ULL(0x74036C3A497732B7) /* 250 */, _ULL(0x89B67ED96361F5AB) /* 251 */, _ULL(0xFFED95D8F1EA02A2) /* 252 */, _ULL(0xE72B3BD61464D43D) /* 253 */, _ULL(0xA6300F170BDC4820) /* 254 */, _ULL(0xEBC18760ED78A77A) /* 255 */, _ULL(0xE6A6BE5A05A12138) /* 256 */, _ULL(0xB5A122A5B4F87C98) /* 257 */, _ULL(0x563C6089140B6990) /* 258 */, _ULL(0x4C46CB2E391F5DD5) /* 259 */, _ULL(0xD932ADDBC9B79434) /* 260 */, _ULL(0x08EA70E42015AFF5) /* 261 */, _ULL(0xD765A6673E478CF1) /* 262 */, _ULL(0xC4FB757EAB278D99) /* 263 */, _ULL(0xDF11C6862D6E0692) /* 264 */, _ULL(0xDDEB84F10D7F3B16) /* 265 */, _ULL(0x6F2EF604A665EA04) /* 266 */, _ULL(0x4A8E0F0FF0E0DFB3) /* 267 */, _ULL(0xA5EDEEF83DBCBA51) /* 268 */, _ULL(0xFC4F0A2A0EA4371E) /* 269 */, _ULL(0xE83E1DA85CB38429) /* 270 */, _ULL(0xDC8FF882BA1B1CE2) /* 271 */, _ULL(0xCD45505E8353E80D) /* 272 */, _ULL(0x18D19A00D4DB0717) /* 273 */, _ULL(0x34A0CFEDA5F38101) /* 274 */, _ULL(0x0BE77E518887CAF2) /* 275 */, _ULL(0x1E341438B3C45136) /* 276 */, _ULL(0xE05797F49089CCF9) /* 277 */, _ULL(0xFFD23F9DF2591D14) /* 278 */, _ULL(0x543DDA228595C5CD) /* 279 */, _ULL(0x661F81FD99052A33) /* 280 */, _ULL(0x8736E641DB0F7B76) /* 281 */, _ULL(0x15227725418E5307) /* 282 */, _ULL(0xE25F7F46162EB2FA) /* 283 */, _ULL(0x48A8B2126C13D9FE) /* 284 */, _ULL(0xAFDC541792E76EEA) /* 285 */, _ULL(0x03D912BFC6D1898F) /* 286 */, _ULL(0x31B1AAFA1B83F51B) /* 287 */, _ULL(0xF1AC2796E42AB7D9) /* 288 */, _ULL(0x40A3A7D7FCD2EBAC) /* 289 */, _ULL(0x1056136D0AFBBCC5) /* 290 */, _ULL(0x7889E1DD9A6D0C85) /* 291 */, _ULL(0xD33525782A7974AA) /* 292 */, _ULL(0xA7E25D09078AC09B) /* 293 */, _ULL(0xBD4138B3EAC6EDD0) /* 294 */, _ULL(0x920ABFBE71EB9E70) /* 295 */, _ULL(0xA2A5D0F54FC2625C) /* 296 */, _ULL(0xC054E36B0B1290A3) /* 297 */, _ULL(0xF6DD59FF62FE932B) /* 298 */, _ULL(0x3537354511A8AC7D) /* 299 */, _ULL(0xCA845E9172FADCD4) /* 300 */, _ULL(0x84F82B60329D20DC) /* 301 */, _ULL(0x79C62CE1CD672F18) /* 302 */, _ULL(0x8B09A2ADD124642C) /* 303 */, _ULL(0xD0C1E96A19D9E726) /* 304 */, _ULL(0x5A786A9B4BA9500C) /* 305 */, _ULL(0x0E020336634C43F3) /* 306 */, _ULL(0xC17B474AEB66D822) /* 307 */, _ULL(0x6A731AE3EC9BAAC2) /* 308 */, _ULL(0x8226667AE0840258) /* 309 */, _ULL(0x67D4567691CAECA5) /* 310 */, _ULL(0x1D94155C4875ADB5) /* 311 */, _ULL(0x6D00FD985B813FDF) /* 312 */, _ULL(0x51286EFCB774CD06) /* 313 */, _ULL(0x5E8834471FA744AF) /* 314 */, _ULL(0xF72CA0AEE761AE2E) /* 315 */, _ULL(0xBE40E4CDAEE8E09A) /* 316 */, _ULL(0xE9970BBB5118F665) /* 317 */, _ULL(0x726E4BEB33DF1964) /* 318 */, _ULL(0x703B000729199762) /* 319 */, _ULL(0x4631D816F5EF30A7) /* 320 */, _ULL(0xB880B5B51504A6BE) /* 321 */, _ULL(0x641793C37ED84B6C) /* 322 */, _ULL(0x7B21ED77F6E97D96) /* 323 */, _ULL(0x776306312EF96B73) /* 324 */, _ULL(0xAE528948E86FF3F4) /* 325 */, _ULL(0x53DBD7F286A3F8F8) /* 326 */, _ULL(0x16CADCE74CFC1063) /* 327 */, _ULL(0x005C19BDFA52C6DD) /* 328 */, _ULL(0x68868F5D64D46AD3) /* 329 */, _ULL(0x3A9D512CCF1E186A) /* 330 */, _ULL(0x367E62C2385660AE) /* 331 */, _ULL(0xE359E7EA77DCB1D7) /* 332 */, _ULL(0x526C0773749ABE6E) /* 333 */, _ULL(0x735AE5F9D09F734B) /* 334 */, _ULL(0x493FC7CC8A558BA8) /* 335 */, _ULL(0xB0B9C1533041AB45) /* 336 */, _ULL(0x321958BA470A59BD) /* 337 */, _ULL(0x852DB00B5F46C393) /* 338 */, _ULL(0x91209B2BD336B0E5) /* 339 */, _ULL(0x6E604F7D659EF19F) /* 340 */, _ULL(0xB99A8AE2782CCB24) /* 341 */, _ULL(0xCCF52AB6C814C4C7) /* 342 */, _ULL(0x4727D9AFBE11727B) /* 343 */, _ULL(0x7E950D0C0121B34D) /* 344 */, _ULL(0x756F435670AD471F) /* 345 */, _ULL(0xF5ADD442615A6849) /* 346 */, _ULL(0x4E87E09980B9957A) /* 347 */, _ULL(0x2ACFA1DF50AEE355) /* 348 */, _ULL(0xD898263AFD2FD556) /* 349 */, _ULL(0xC8F4924DD80C8FD6) /* 350 */, _ULL(0xCF99CA3D754A173A) /* 351 */, _ULL(0xFE477BACAF91BF3C) /* 352 */, _ULL(0xED5371F6D690C12D) /* 353 */, _ULL(0x831A5C285E687094) /* 354 */, _ULL(0xC5D3C90A3708A0A4) /* 355 */, _ULL(0x0F7F903717D06580) /* 356 */, _ULL(0x19F9BB13B8FDF27F) /* 357 */, _ULL(0xB1BD6F1B4D502843) /* 358 */, _ULL(0x1C761BA38FFF4012) /* 359 */, _ULL(0x0D1530C4E2E21F3B) /* 360 */, _ULL(0x8943CE69A7372C8A) /* 361 */, _ULL(0xE5184E11FEB5CE66) /* 362 */, _ULL(0x618BDB80BD736621) /* 363 */, _ULL(0x7D29BAD68B574D0B) /* 364 */, _ULL(0x81BB613E25E6FE5B) /* 365 */, _ULL(0x071C9C10BC07913F) /* 366 */, _ULL(0xC7BEEB7909AC2D97) /* 367 */, _ULL(0xC3E58D353BC5D757) /* 368 */, _ULL(0xEB017892F38F61E8) /* 369 */, _ULL(0xD4EFFB9C9B1CC21A) /* 370 */, _ULL(0x99727D26F494F7AB) /* 371 */, _ULL(0xA3E063A2956B3E03) /* 372 */, _ULL(0x9D4A8B9A4AA09C30) /* 373 */, _ULL(0x3F6AB7D500090FB4) /* 374 */, _ULL(0x9CC0F2A057268AC0) /* 375 */, _ULL(0x3DEE9D2DEDBF42D1) /* 376 */, _ULL(0x330F49C87960A972) /* 377 */, _ULL(0xC6B2720287421B41) /* 378 */, _ULL(0x0AC59EC07C00369C) /* 379 */, _ULL(0xEF4EAC49CB353425) /* 380 */, _ULL(0xF450244EEF0129D8) /* 381 */, _ULL(0x8ACC46E5CAF4DEB6) /* 382 */, _ULL(0x2FFEAB63989263F7) /* 383 */, _ULL(0x8F7CB9FE5D7A4578) /* 384 */, _ULL(0x5BD8F7644E634635) /* 385 */, _ULL(0x427A7315BF2DC900) /* 386 */, _ULL(0x17D0C4AA2125261C) /* 387 */, _ULL(0x3992486C93518E50) /* 388 */, _ULL(0xB4CBFEE0A2D7D4C3) /* 389 */, _ULL(0x7C75D6202C5DDD8D) /* 390 */, _ULL(0xDBC295D8E35B6C61) /* 391 */, _ULL(0x60B369D302032B19) /* 392 */, _ULL(0xCE42685FDCE44132) /* 393 */, _ULL(0x06F3DDB9DDF65610) /* 394 */, _ULL(0x8EA4D21DB5E148F0) /* 395 */, _ULL(0x20B0FCE62FCD496F) /* 396 */, _ULL(0x2C1B912358B0EE31) /* 397 */, _ULL(0xB28317B818F5A308) /* 398 */, _ULL(0xA89C1E189CA6D2CF) /* 399 */, _ULL(0x0C6B18576AAADBC8) /* 400 */, _ULL(0xB65DEAA91299FAE3) /* 401 */, _ULL(0xFB2B794B7F1027E7) /* 402 */, _ULL(0x04E4317F443B5BEB) /* 403 */, _ULL(0x4B852D325939D0A6) /* 404 */, _ULL(0xD5AE6BEEFB207FFC) /* 405 */, _ULL(0x309682B281C7D374) /* 406 */, _ULL(0xBAE309A194C3B475) /* 407 */, _ULL(0x8CC3F97B13B49F05) /* 408 */, _ULL(0x98A9422FF8293967) /* 409 */, _ULL(0x244B16B01076FF7C) /* 410 */, _ULL(0xF8BF571C663D67EE) /* 411 */, _ULL(0x1F0D6758EEE30DA1) /* 412 */, _ULL(0xC9B611D97ADEB9B7) /* 413 */, _ULL(0xB7AFD5887B6C57A2) /* 414 */, _ULL(0x6290AE846B984FE1) /* 415 */, _ULL(0x94DF4CDEACC1A5FD) /* 416 */, _ULL(0x058A5BD1C5483AFF) /* 417 */, _ULL(0x63166CC142BA3C37) /* 418 */, _ULL(0x8DB8526EB2F76F40) /* 419 */, _ULL(0xE10880036F0D6D4E) /* 420 */, _ULL(0x9E0523C9971D311D) /* 421 */, _ULL(0x45EC2824CC7CD691) /* 422 */, _ULL(0x575B8359E62382C9) /* 423 */, _ULL(0xFA9E400DC4889995) /* 424 */, _ULL(0xD1823ECB45721568) /* 425 */, _ULL(0xDAFD983B8206082F) /* 426 */, _ULL(0xAA7D29082386A8CB) /* 427 */, _ULL(0x269FCD4403B87588) /* 428 */, _ULL(0x1B91F5F728BDD1E0) /* 429 */, _ULL(0xE4669F39040201F6) /* 430 */, _ULL(0x7A1D7C218CF04ADE) /* 431 */, _ULL(0x65623C29D79CE5CE) /* 432 */, _ULL(0x2368449096C00BB1) /* 433 */, _ULL(0xAB9BF1879DA503BA) /* 434 */, _ULL(0xBC23ECB1A458058E) /* 435 */, _ULL(0x9A58DF01BB401ECC) /* 436 */, _ULL(0xA070E868A85F143D) /* 437 */, _ULL(0x4FF188307DF2239E) /* 438 */, _ULL(0x14D565B41A641183) /* 439 */, _ULL(0xEE13337452701602) /* 440 */, _ULL(0x950E3DCF3F285E09) /* 441 */, _ULL(0x59930254B9C80953) /* 442 */, _ULL(0x3BF299408930DA6D) /* 443 */, _ULL(0xA955943F53691387) /* 444 */, _ULL(0xA15EDECAA9CB8784) /* 445 */, _ULL(0x29142127352BE9A0) /* 446 */, _ULL(0x76F0371FFF4E7AFB) /* 447 */, _ULL(0x0239F450274F2228) /* 448 */, _ULL(0xBB073AF01D5E868B) /* 449 */, _ULL(0xBFC80571C10E96C1) /* 450 */, _ULL(0xD267088568222E23) /* 451 */, _ULL(0x9671A3D48E80B5B0) /* 452 */, _ULL(0x55B5D38AE193BB81) /* 453 */, _ULL(0x693AE2D0A18B04B8) /* 454 */, _ULL(0x5C48B4ECADD5335F) /* 455 */, _ULL(0xFD743B194916A1CA) /* 456 */, _ULL(0x2577018134BE98C4) /* 457 */, _ULL(0xE77987E83C54A4AD) /* 458 */, _ULL(0x28E11014DA33E1B9) /* 459 */, _ULL(0x270CC59E226AA213) /* 460 */, _ULL(0x71495F756D1A5F60) /* 461 */, _ULL(0x9BE853FB60AFEF77) /* 462 */, _ULL(0xADC786A7F7443DBF) /* 463 */, _ULL(0x0904456173B29A82) /* 464 */, _ULL(0x58BC7A66C232BD5E) /* 465 */, _ULL(0xF306558C673AC8B2) /* 466 */, _ULL(0x41F639C6B6C9772A) /* 467 */, _ULL(0x216DEFE99FDA35DA) /* 468 */, _ULL(0x11640CC71C7BE615) /* 469 */, _ULL(0x93C43694565C5527) /* 470 */, _ULL(0xEA038E6246777839) /* 471 */, _ULL(0xF9ABF3CE5A3E2469) /* 472 */, _ULL(0x741E768D0FD312D2) /* 473 */, _ULL(0x0144B883CED652C6) /* 474 */, _ULL(0xC20B5A5BA33F8552) /* 475 */, _ULL(0x1AE69633C3435A9D) /* 476 */, _ULL(0x97A28CA4088CFDEC) /* 477 */, _ULL(0x8824A43C1E96F420) /* 478 */, _ULL(0x37612FA66EEEA746) /* 479 */, _ULL(0x6B4CB165F9CF0E5A) /* 480 */, _ULL(0x43AA1C06A0ABFB4A) /* 481 */, _ULL(0x7F4DC26FF162796B) /* 482 */, _ULL(0x6CBACC8E54ED9B0F) /* 483 */, _ULL(0xA6B7FFEFD2BB253E) /* 484 */, _ULL(0x2E25BC95B0A29D4F) /* 485 */, _ULL(0x86D6A58BDEF1388C) /* 486 */, _ULL(0xDED74AC576B6F054) /* 487 */, _ULL(0x8030BDBC2B45805D) /* 488 */, _ULL(0x3C81AF70E94D9289) /* 489 */, _ULL(0x3EFF6DDA9E3100DB) /* 490 */, _ULL(0xB38DC39FDFCC8847) /* 491 */, _ULL(0x123885528D17B87E) /* 492 */, _ULL(0xF2DA0ED240B1B642) /* 493 */, _ULL(0x44CEFADCD54BF9A9) /* 494 */, _ULL(0x1312200E433C7EE6) /* 495 */, _ULL(0x9FFCC84F3A78C748) /* 496 */, _ULL(0xF0CD1F72248576BB) /* 497 */, _ULL(0xEC6974053638CFE4) /* 498 */, _ULL(0x2BA7B67C0CEC4E4C) /* 499 */, _ULL(0xAC2F4DF3E5CE32ED) /* 500 */, _ULL(0xCB33D14326EA4C11) /* 501 */, _ULL(0xA4E9044CC77E58BC) /* 502 */, _ULL(0x5F513293D934FCEF) /* 503 */, _ULL(0x5DC9645506E55444) /* 504 */, _ULL(0x50DE418F317DE40A) /* 505 */, _ULL(0x388CB31A69DDE259) /* 506 */, _ULL(0x2DB4A83455820A86) /* 507 */, _ULL(0x9010A91E84711AE9) /* 508 */, _ULL(0x4DF7F0B7B1498371) /* 509 */, _ULL(0xD62A2EABC0977179) /* 510 */, _ULL(0x22FAC097AA8D5C0E) /* 511 */, _ULL(0xF49FCC2FF1DAF39B) /* 512 */, _ULL(0x487FD5C66FF29281) /* 513 */, _ULL(0xE8A30667FCDCA83F) /* 514 */, _ULL(0x2C9B4BE3D2FCCE63) /* 515 */, _ULL(0xDA3FF74B93FBBBC2) /* 516 */, _ULL(0x2FA165D2FE70BA66) /* 517 */, _ULL(0xA103E279970E93D4) /* 518 */, _ULL(0xBECDEC77B0E45E71) /* 519 */, _ULL(0xCFB41E723985E497) /* 520 */, _ULL(0xB70AAA025EF75017) /* 521 */, _ULL(0xD42309F03840B8E0) /* 522 */, _ULL(0x8EFC1AD035898579) /* 523 */, _ULL(0x96C6920BE2B2ABC5) /* 524 */, _ULL(0x66AF4163375A9172) /* 525 */, _ULL(0x2174ABDCCA7127FB) /* 526 */, _ULL(0xB33CCEA64A72FF41) /* 527 */, _ULL(0xF04A4933083066A5) /* 528 */, _ULL(0x8D970ACDD7289AF5) /* 529 */, _ULL(0x8F96E8E031C8C25E) /* 530 */, _ULL(0xF3FEC02276875D47) /* 531 */, _ULL(0xEC7BF310056190DD) /* 532 */, _ULL(0xF5ADB0AEBB0F1491) /* 533 */, _ULL(0x9B50F8850FD58892) /* 534 */, _ULL(0x4975488358B74DE8) /* 535 */, _ULL(0xA3354FF691531C61) /* 536 */, _ULL(0x0702BBE481D2C6EE) /* 537 */, _ULL(0x89FB24057DEDED98) /* 538 */, _ULL(0xAC3075138596E902) /* 539 */, _ULL(0x1D2D3580172772ED) /* 540 */, _ULL(0xEB738FC28E6BC30D) /* 541 */, _ULL(0x5854EF8F63044326) /* 542 */, _ULL(0x9E5C52325ADD3BBE) /* 543 */, _ULL(0x90AA53CF325C4623) /* 544 */, _ULL(0xC1D24D51349DD067) /* 545 */, _ULL(0x2051CFEEA69EA624) /* 546 */, _ULL(0x13220F0A862E7E4F) /* 547 */, _ULL(0xCE39399404E04864) /* 548 */, _ULL(0xD9C42CA47086FCB7) /* 549 */, _ULL(0x685AD2238A03E7CC) /* 550 */, _ULL(0x066484B2AB2FF1DB) /* 551 */, _ULL(0xFE9D5D70EFBF79EC) /* 552 */, _ULL(0x5B13B9DD9C481854) /* 553 */, _ULL(0x15F0D475ED1509AD) /* 554 */, _ULL(0x0BEBCD060EC79851) /* 555 */, _ULL(0xD58C6791183AB7F8) /* 556 */, _ULL(0xD1187C5052F3EEE4) /* 557 */, _ULL(0xC95D1192E54E82FF) /* 558 */, _ULL(0x86EEA14CB9AC6CA2) /* 559 */, _ULL(0x3485BEB153677D5D) /* 560 */, _ULL(0xDD191D781F8C492A) /* 561 */, _ULL(0xF60866BAA784EBF9) /* 562 */, _ULL(0x518F643BA2D08C74) /* 563 */, _ULL(0x8852E956E1087C22) /* 564 */, _ULL(0xA768CB8DC410AE8D) /* 565 */, _ULL(0x38047726BFEC8E1A) /* 566 */, _ULL(0xA67738B4CD3B45AA) /* 567 */, _ULL(0xAD16691CEC0DDE19) /* 568 */, _ULL(0xC6D4319380462E07) /* 569 */, _ULL(0xC5A5876D0BA61938) /* 570 */, _ULL(0x16B9FA1FA58FD840) /* 571 */, _ULL(0x188AB1173CA74F18) /* 572 */, _ULL(0xABDA2F98C99C021F) /* 573 */, _ULL(0x3E0580AB134AE816) /* 574 */, _ULL(0x5F3B05B773645ABB) /* 575 */, _ULL(0x2501A2BE5575F2F6) /* 576 */, _ULL(0x1B2F74004E7E8BA9) /* 577 */, _ULL(0x1CD7580371E8D953) /* 578 */, _ULL(0x7F6ED89562764E30) /* 579 */, _ULL(0xB15926FF596F003D) /* 580 */, _ULL(0x9F65293DA8C5D6B9) /* 581 */, _ULL(0x6ECEF04DD690F84C) /* 582 */, _ULL(0x4782275FFF33AF88) /* 583 */, _ULL(0xE41433083F820801) /* 584 */, _ULL(0xFD0DFE409A1AF9B5) /* 585 */, _ULL(0x4325A3342CDB396B) /* 586 */, _ULL(0x8AE77E62B301B252) /* 587 */, _ULL(0xC36F9E9F6655615A) /* 588 */, _ULL(0x85455A2D92D32C09) /* 589 */, _ULL(0xF2C7DEA949477485) /* 590 */, _ULL(0x63CFB4C133A39EBA) /* 591 */, _ULL(0x83B040CC6EBC5462) /* 592 */, _ULL(0x3B9454C8FDB326B0) /* 593 */, _ULL(0x56F56A9E87FFD78C) /* 594 */, _ULL(0x2DC2940D99F42BC6) /* 595 */, _ULL(0x98F7DF096B096E2D) /* 596 */, _ULL(0x19A6E01E3AD852BF) /* 597 */, _ULL(0x42A99CCBDBD4B40B) /* 598 */, _ULL(0xA59998AF45E9C559) /* 599 */, _ULL(0x366295E807D93186) /* 600 */, _ULL(0x6B48181BFAA1F773) /* 601 */, _ULL(0x1FEC57E2157A0A1D) /* 602 */, _ULL(0x4667446AF6201AD5) /* 603 */, _ULL(0xE615EBCACFB0F075) /* 604 */, _ULL(0xB8F31F4F68290778) /* 605 */, _ULL(0x22713ED6CE22D11E) /* 606 */, _ULL(0x3057C1A72EC3C93B) /* 607 */, _ULL(0xCB46ACC37C3F1F2F) /* 608 */, _ULL(0xDBB893FD02AAF50E) /* 609 */, _ULL(0x331FD92E600B9FCF) /* 610 */, _ULL(0xA498F96148EA3AD6) /* 611 */, _ULL(0xA8D8426E8B6A83EA) /* 612 */, _ULL(0xA089B274B7735CDC) /* 613 */, _ULL(0x87F6B3731E524A11) /* 614 */, _ULL(0x118808E5CBC96749) /* 615 */, _ULL(0x9906E4C7B19BD394) /* 616 */, _ULL(0xAFED7F7E9B24A20C) /* 617 */, _ULL(0x6509EADEEB3644A7) /* 618 */, _ULL(0x6C1EF1D3E8EF0EDE) /* 619 */, _ULL(0xB9C97D43E9798FB4) /* 620 */, _ULL(0xA2F2D784740C28A3) /* 621 */, _ULL(0x7B8496476197566F) /* 622 */, _ULL(0x7A5BE3E6B65F069D) /* 623 */, _ULL(0xF96330ED78BE6F10) /* 624 */, _ULL(0xEEE60DE77A076A15) /* 625 */, _ULL(0x2B4BEE4AA08B9BD0) /* 626 */, _ULL(0x6A56A63EC7B8894E) /* 627 */, _ULL(0x02121359BA34FEF4) /* 628 */, _ULL(0x4CBF99F8283703FC) /* 629 */, _ULL(0x398071350CAF30C8) /* 630 */, _ULL(0xD0A77A89F017687A) /* 631 */, _ULL(0xF1C1A9EB9E423569) /* 632 */, _ULL(0x8C7976282DEE8199) /* 633 */, _ULL(0x5D1737A5DD1F7ABD) /* 634 */, _ULL(0x4F53433C09A9FA80) /* 635 */, _ULL(0xFA8B0C53DF7CA1D9) /* 636 */, _ULL(0x3FD9DCBC886CCB77) /* 637 */, _ULL(0xC040917CA91B4720) /* 638 */, _ULL(0x7DD00142F9D1DCDF) /* 639 */, _ULL(0x8476FC1D4F387B58) /* 640 */, _ULL(0x23F8E7C5F3316503) /* 641 */, _ULL(0x032A2244E7E37339) /* 642 */, _ULL(0x5C87A5D750F5A74B) /* 643 */, _ULL(0x082B4CC43698992E) /* 644 */, _ULL(0xDF917BECB858F63C) /* 645 */, _ULL(0x3270B8FC5BF86DDA) /* 646 */, _ULL(0x10AE72BB29B5DD76) /* 647 */, _ULL(0x576AC94E7700362B) /* 648 */, _ULL(0x1AD112DAC61EFB8F) /* 649 */, _ULL(0x691BC30EC5FAA427) /* 650 */, _ULL(0xFF246311CC327143) /* 651 */, _ULL(0x3142368E30E53206) /* 652 */, _ULL(0x71380E31E02CA396) /* 653 */, _ULL(0x958D5C960AAD76F1) /* 654 */, _ULL(0xF8D6F430C16DA536) /* 655 */, _ULL(0xC8FFD13F1BE7E1D2) /* 656 */, _ULL(0x7578AE66004DDBE1) /* 657 */, _ULL(0x05833F01067BE646) /* 658 */, _ULL(0xBB34B5AD3BFE586D) /* 659 */, _ULL(0x095F34C9A12B97F0) /* 660 */, _ULL(0x247AB64525D60CA8) /* 661 */, _ULL(0xDCDBC6F3017477D1) /* 662 */, _ULL(0x4A2E14D4DECAD24D) /* 663 */, _ULL(0xBDB5E6D9BE0A1EEB) /* 664 */, _ULL(0x2A7E70F7794301AB) /* 665 */, _ULL(0xDEF42D8A270540FD) /* 666 */, _ULL(0x01078EC0A34C22C1) /* 667 */, _ULL(0xE5DE511AF4C16387) /* 668 */, _ULL(0x7EBB3A52BD9A330A) /* 669 */, _ULL(0x77697857AA7D6435) /* 670 */, _ULL(0x004E831603AE4C32) /* 671 */, _ULL(0xE7A21020AD78E312) /* 672 */, _ULL(0x9D41A70C6AB420F2) /* 673 */, _ULL(0x28E06C18EA1141E6) /* 674 */, _ULL(0xD2B28CBD984F6B28) /* 675 */, _ULL(0x26B75F6C446E9D83) /* 676 */, _ULL(0xBA47568C4D418D7F) /* 677 */, _ULL(0xD80BADBFE6183D8E) /* 678 */, _ULL(0x0E206D7F5F166044) /* 679 */, _ULL(0xE258A43911CBCA3E) /* 680 */, _ULL(0x723A1746B21DC0BC) /* 681 */, _ULL(0xC7CAA854F5D7CDD3) /* 682 */, _ULL(0x7CAC32883D261D9C) /* 683 */, _ULL(0x7690C26423BA942C) /* 684 */, _ULL(0x17E55524478042B8) /* 685 */, _ULL(0xE0BE477656A2389F) /* 686 */, _ULL(0x4D289B5E67AB2DA0) /* 687 */, _ULL(0x44862B9C8FBBFD31) /* 688 */, _ULL(0xB47CC8049D141365) /* 689 */, _ULL(0x822C1B362B91C793) /* 690 */, _ULL(0x4EB14655FB13DFD8) /* 691 */, _ULL(0x1ECBBA0714E2A97B) /* 692 */, _ULL(0x6143459D5CDE5F14) /* 693 */, _ULL(0x53A8FBF1D5F0AC89) /* 694 */, _ULL(0x97EA04D81C5E5B00) /* 695 */, _ULL(0x622181A8D4FDB3F3) /* 696 */, _ULL(0xE9BCD341572A1208) /* 697 */, _ULL(0x1411258643CCE58A) /* 698 */, _ULL(0x9144C5FEA4C6E0A4) /* 699 */, _ULL(0x0D33D06565CF620F) /* 700 */, _ULL(0x54A48D489F219CA1) /* 701 */, _ULL(0xC43E5EAC6D63C821) /* 702 */, _ULL(0xA9728B3A72770DAF) /* 703 */, _ULL(0xD7934E7B20DF87EF) /* 704 */, _ULL(0xE35503B61A3E86E5) /* 705 */, _ULL(0xCAE321FBC819D504) /* 706 */, _ULL(0x129A50B3AC60BFA6) /* 707 */, _ULL(0xCD5E68EA7E9FB6C3) /* 708 */, _ULL(0xB01C90199483B1C7) /* 709 */, _ULL(0x3DE93CD5C295376C) /* 710 */, _ULL(0xAED52EDF2AB9AD13) /* 711 */, _ULL(0x2E60F512C0A07884) /* 712 */, _ULL(0xBC3D86A3E36210C9) /* 713 */, _ULL(0x35269D9B163951CE) /* 714 */, _ULL(0x0C7D6E2AD0CDB5FA) /* 715 */, _ULL(0x59E86297D87F5733) /* 716 */, _ULL(0x298EF221898DB0E7) /* 717 */, _ULL(0x55000029D1A5AA7E) /* 718 */, _ULL(0x8BC08AE1B5061B45) /* 719 */, _ULL(0xC2C31C2B6C92703A) /* 720 */, _ULL(0x94CC596BAF25EF42) /* 721 */, _ULL(0x0A1D73DB22540456) /* 722 */, _ULL(0x04B6A0F9D9C4179A) /* 723 */, _ULL(0xEFFDAFA2AE3D3C60) /* 724 */, _ULL(0xF7C8075BB49496C4) /* 725 */, _ULL(0x9CC5C7141D1CD4E3) /* 726 */, _ULL(0x78BD1638218E5534) /* 727 */, _ULL(0xB2F11568F850246A) /* 728 */, _ULL(0xEDFABCFA9502BC29) /* 729 */, _ULL(0x796CE5F2DA23051B) /* 730 */, _ULL(0xAAE128B0DC93537C) /* 731 */, _ULL(0x3A493DA0EE4B29AE) /* 732 */, _ULL(0xB5DF6B2C416895D7) /* 733 */, _ULL(0xFCABBD25122D7F37) /* 734 */, _ULL(0x70810B58105DC4B1) /* 735 */, _ULL(0xE10FDD37F7882A90) /* 736 */, _ULL(0x524DCAB5518A3F5C) /* 737 */, _ULL(0x3C9E85878451255B) /* 738 */, _ULL(0x4029828119BD34E2) /* 739 */, _ULL(0x74A05B6F5D3CECCB) /* 740 */, _ULL(0xB610021542E13ECA) /* 741 */, _ULL(0x0FF979D12F59E2AC) /* 742 */, _ULL(0x6037DA27E4F9CC50) /* 743 */, _ULL(0x5E92975A0DF1847D) /* 744 */, _ULL(0xD66DE190D3E623FE) /* 745 */, _ULL(0x5032D6B87B568048) /* 746 */, _ULL(0x9A36B7CE8235216E) /* 747 */, _ULL(0x80272A7A24F64B4A) /* 748 */, _ULL(0x93EFED8B8C6916F7) /* 749 */, _ULL(0x37DDBFF44CCE1555) /* 750 */, _ULL(0x4B95DB5D4B99BD25) /* 751 */, _ULL(0x92D3FDA169812FC0) /* 752 */, _ULL(0xFB1A4A9A90660BB6) /* 753 */, _ULL(0x730C196946A4B9B2) /* 754 */, _ULL(0x81E289AA7F49DA68) /* 755 */, _ULL(0x64669A0F83B1A05F) /* 756 */, _ULL(0x27B3FF7D9644F48B) /* 757 */, _ULL(0xCC6B615C8DB675B3) /* 758 */, _ULL(0x674F20B9BCEBBE95) /* 759 */, _ULL(0x6F31238275655982) /* 760 */, _ULL(0x5AE488713E45CF05) /* 761 */, _ULL(0xBF619F9954C21157) /* 762 */, _ULL(0xEABAC46040A8EAE9) /* 763 */, _ULL(0x454C6FE9F2C0C1CD) /* 764 */, _ULL(0x419CF6496412691C) /* 765 */, _ULL(0xD3DC3BEF265B0F70) /* 766 */, _ULL(0x6D0E60F5C3578A9E) /* 767 */, _ULL(0x5B0E608526323C55) /* 768 */, _ULL(0x1A46C1A9FA1B59F5) /* 769 */, _ULL(0xA9E245A17C4C8FFA) /* 770 */, _ULL(0x65CA5159DB2955D7) /* 771 */, _ULL(0x05DB0A76CE35AFC2) /* 772 */, _ULL(0x81EAC77EA9113D45) /* 773 */, _ULL(0x528EF88AB6AC0A0D) /* 774 */, _ULL(0xA09EA253597BE3FF) /* 775 */, _ULL(0x430DDFB3AC48CD56) /* 776 */, _ULL(0xC4B3A67AF45CE46F) /* 777 */, _ULL(0x4ECECFD8FBE2D05E) /* 778 */, _ULL(0x3EF56F10B39935F0) /* 779 */, _ULL(0x0B22D6829CD619C6) /* 780 */, _ULL(0x17FD460A74DF2069) /* 781 */, _ULL(0x6CF8CC8E8510ED40) /* 782 */, _ULL(0xD6C824BF3A6ECAA7) /* 783 */, _ULL(0x61243D581A817049) /* 784 */, _ULL(0x048BACB6BBC163A2) /* 785 */, _ULL(0xD9A38AC27D44CC32) /* 786 */, _ULL(0x7FDDFF5BAAF410AB) /* 787 */, _ULL(0xAD6D495AA804824B) /* 788 */, _ULL(0xE1A6A74F2D8C9F94) /* 789 */, _ULL(0xD4F7851235DEE8E3) /* 790 */, _ULL(0xFD4B7F886540D893) /* 791 */, _ULL(0x247C20042AA4BFDA) /* 792 */, _ULL(0x096EA1C517D1327C) /* 793 */, _ULL(0xD56966B4361A6685) /* 794 */, _ULL(0x277DA5C31221057D) /* 795 */, _ULL(0x94D59893A43ACFF7) /* 796 */, _ULL(0x64F0C51CCDC02281) /* 797 */, _ULL(0x3D33BCC4FF6189DB) /* 798 */, _ULL(0xE005CB184CE66AF1) /* 799 */, _ULL(0xFF5CCD1D1DB99BEA) /* 800 */, _ULL(0xB0B854A7FE42980F) /* 801 */, _ULL(0x7BD46A6A718D4B9F) /* 802 */, _ULL(0xD10FA8CC22A5FD8C) /* 803 */, _ULL(0xD31484952BE4BD31) /* 804 */, _ULL(0xC7FA975FCB243847) /* 805 */, _ULL(0x4886ED1E5846C407) /* 806 */, _ULL(0x28CDDB791EB70B04) /* 807 */, _ULL(0xC2B00BE2F573417F) /* 808 */, _ULL(0x5C9590452180F877) /* 809 */, _ULL(0x7A6BDDFFF370EB00) /* 810 */, _ULL(0xCE509E38D6D9D6A4) /* 811 */, _ULL(0xEBEB0F00647FA702) /* 812 */, _ULL(0x1DCC06CF76606F06) /* 813 */, _ULL(0xE4D9F28BA286FF0A) /* 814 */, _ULL(0xD85A305DC918C262) /* 815 */, _ULL(0x475B1D8732225F54) /* 816 */, _ULL(0x2D4FB51668CCB5FE) /* 817 */, _ULL(0xA679B9D9D72BBA20) /* 818 */, _ULL(0x53841C0D912D43A5) /* 819 */, _ULL(0x3B7EAA48BF12A4E8) /* 820 */, _ULL(0x781E0E47F22F1DDF) /* 821 */, _ULL(0xEFF20CE60AB50973) /* 822 */, _ULL(0x20D261D19DFFB742) /* 823 */, _ULL(0x16A12B03062A2E39) /* 824 */, _ULL(0x1960EB2239650495) /* 825 */, _ULL(0x251C16FED50EB8B8) /* 826 */, _ULL(0x9AC0C330F826016E) /* 827 */, _ULL(0xED152665953E7671) /* 828 */, _ULL(0x02D63194A6369570) /* 829 */, _ULL(0x5074F08394B1C987) /* 830 */, _ULL(0x70BA598C90B25CE1) /* 831 */, _ULL(0x794A15810B9742F6) /* 832 */, _ULL(0x0D5925E9FCAF8C6C) /* 833 */, _ULL(0x3067716CD868744E) /* 834 */, _ULL(0x910AB077E8D7731B) /* 835 */, _ULL(0x6A61BBDB5AC42F61) /* 836 */, _ULL(0x93513EFBF0851567) /* 837 */, _ULL(0xF494724B9E83E9D5) /* 838 */, _ULL(0xE887E1985C09648D) /* 839 */, _ULL(0x34B1D3C675370CFD) /* 840 */, _ULL(0xDC35E433BC0D255D) /* 841 */, _ULL(0xD0AAB84234131BE0) /* 842 */, _ULL(0x08042A50B48B7EAF) /* 843 */, _ULL(0x9997C4EE44A3AB35) /* 844 */, _ULL(0x829A7B49201799D0) /* 845 */, _ULL(0x263B8307B7C54441) /* 846 */, _ULL(0x752F95F4FD6A6CA6) /* 847 */, _ULL(0x927217402C08C6E5) /* 848 */, _ULL(0x2A8AB754A795D9EE) /* 849 */, _ULL(0xA442F7552F72943D) /* 850 */, _ULL(0x2C31334E19781208) /* 851 */, _ULL(0x4FA98D7CEAEE6291) /* 852 */, _ULL(0x55C3862F665DB309) /* 853 */, _ULL(0xBD0610175D53B1F3) /* 854 */, _ULL(0x46FE6CB840413F27) /* 855 */, _ULL(0x3FE03792DF0CFA59) /* 856 */, _ULL(0xCFE700372EB85E8F) /* 857 */, _ULL(0xA7BE29E7ADBCE118) /* 858 */, _ULL(0xE544EE5CDE8431DD) /* 859 */, _ULL(0x8A781B1B41F1873E) /* 860 */, _ULL(0xA5C94C78A0D2F0E7) /* 861 */, _ULL(0x39412E2877B60728) /* 862 */, _ULL(0xA1265EF3AFC9A62C) /* 863 */, _ULL(0xBCC2770C6A2506C5) /* 864 */, _ULL(0x3AB66DD5DCE1CE12) /* 865 */, _ULL(0xE65499D04A675B37) /* 866 */, _ULL(0x7D8F523481BFD216) /* 867 */, _ULL(0x0F6F64FCEC15F389) /* 868 */, _ULL(0x74EFBE618B5B13C8) /* 869 */, _ULL(0xACDC82B714273E1D) /* 870 */, _ULL(0xDD40BFE003199D17) /* 871 */, _ULL(0x37E99257E7E061F8) /* 872 */, _ULL(0xFA52626904775AAA) /* 873 */, _ULL(0x8BBBF63A463D56F9) /* 874 */, _ULL(0xF0013F1543A26E64) /* 875 */, _ULL(0xA8307E9F879EC898) /* 876 */, _ULL(0xCC4C27A4150177CC) /* 877 */, _ULL(0x1B432F2CCA1D3348) /* 878 */, _ULL(0xDE1D1F8F9F6FA013) /* 879 */, _ULL(0x606602A047A7DDD6) /* 880 */, _ULL(0xD237AB64CC1CB2C7) /* 881 */, _ULL(0x9B938E7225FCD1D3) /* 882 */, _ULL(0xEC4E03708E0FF476) /* 883 */, _ULL(0xFEB2FBDA3D03C12D) /* 884 */, _ULL(0xAE0BCED2EE43889A) /* 885 */, _ULL(0x22CB8923EBFB4F43) /* 886 */, _ULL(0x69360D013CF7396D) /* 887 */, _ULL(0x855E3602D2D4E022) /* 888 */, _ULL(0x073805BAD01F784C) /* 889 */, _ULL(0x33E17A133852F546) /* 890 */, _ULL(0xDF4874058AC7B638) /* 891 */, _ULL(0xBA92B29C678AA14A) /* 892 */, _ULL(0x0CE89FC76CFAADCD) /* 893 */, _ULL(0x5F9D4E0908339E34) /* 894 */, _ULL(0xF1AFE9291F5923B9) /* 895 */, _ULL(0x6E3480F60F4A265F) /* 896 */, _ULL(0xEEBF3A2AB29B841C) /* 897 */, _ULL(0xE21938A88F91B4AD) /* 898 */, _ULL(0x57DFEFF845C6D3C3) /* 899 */, _ULL(0x2F006B0BF62CAAF2) /* 900 */, _ULL(0x62F479EF6F75EE78) /* 901 */, _ULL(0x11A55AD41C8916A9) /* 902 */, _ULL(0xF229D29084FED453) /* 903 */, _ULL(0x42F1C27B16B000E6) /* 904 */, _ULL(0x2B1F76749823C074) /* 905 */, _ULL(0x4B76ECA3C2745360) /* 906 */, _ULL(0x8C98F463B91691BD) /* 907 */, _ULL(0x14BCC93CF1ADE66A) /* 908 */, _ULL(0x8885213E6D458397) /* 909 */, _ULL(0x8E177DF0274D4711) /* 910 */, _ULL(0xB49B73B5503F2951) /* 911 */, _ULL(0x10168168C3F96B6B) /* 912 */, _ULL(0x0E3D963B63CAB0AE) /* 913 */, _ULL(0x8DFC4B5655A1DB14) /* 914 */, _ULL(0xF789F1356E14DE5C) /* 915 */, _ULL(0x683E68AF4E51DAC1) /* 916 */, _ULL(0xC9A84F9D8D4B0FD9) /* 917 */, _ULL(0x3691E03F52A0F9D1) /* 918 */, _ULL(0x5ED86E46E1878E80) /* 919 */, _ULL(0x3C711A0E99D07150) /* 920 */, _ULL(0x5A0865B20C4E9310) /* 921 */, _ULL(0x56FBFC1FE4F0682E) /* 922 */, _ULL(0xEA8D5DE3105EDF9B) /* 923 */, _ULL(0x71ABFDB12379187A) /* 924 */, _ULL(0x2EB99DE1BEE77B9C) /* 925 */, _ULL(0x21ECC0EA33CF4523) /* 926 */, _ULL(0x59A4D7521805C7A1) /* 927 */, _ULL(0x3896F5EB56AE7C72) /* 928 */, _ULL(0xAA638F3DB18F75DC) /* 929 */, _ULL(0x9F39358DABE9808E) /* 930 */, _ULL(0xB7DEFA91C00B72AC) /* 931 */, _ULL(0x6B5541FD62492D92) /* 932 */, _ULL(0x6DC6DEE8F92E4D5B) /* 933 */, _ULL(0x353F57ABC4BEEA7E) /* 934 */, _ULL(0x735769D6DA5690CE) /* 935 */, _ULL(0x0A234AA642391484) /* 936 */, _ULL(0xF6F9508028F80D9D) /* 937 */, _ULL(0xB8E319A27AB3F215) /* 938 */, _ULL(0x31AD9C1151341A4D) /* 939 */, _ULL(0x773C22A57BEF5805) /* 940 */, _ULL(0x45C7561A07968633) /* 941 */, _ULL(0xF913DA9E249DBE36) /* 942 */, _ULL(0xDA652D9B78A64C68) /* 943 */, _ULL(0x4C27A97F3BC334EF) /* 944 */, _ULL(0x76621220E66B17F4) /* 945 */, _ULL(0x967743899ACD7D0B) /* 946 */, _ULL(0xF3EE5BCAE0ED6782) /* 947 */, _ULL(0x409F753600C879FC) /* 948 */, _ULL(0x06D09A39B5926DB6) /* 949 */, _ULL(0x6F83AEB0317AC588) /* 950 */, _ULL(0x01E6CA4A86381F21) /* 951 */, _ULL(0x66FF3462D19F3025) /* 952 */, _ULL(0x72207C24DDFD3BFB) /* 953 */, _ULL(0x4AF6B6D3E2ECE2EB) /* 954 */, _ULL(0x9C994DBEC7EA08DE) /* 955 */, _ULL(0x49ACE597B09A8BC4) /* 956 */, _ULL(0xB38C4766CF0797BA) /* 957 */, _ULL(0x131B9373C57C2A75) /* 958 */, _ULL(0xB1822CCE61931E58) /* 959 */, _ULL(0x9D7555B909BA1C0C) /* 960 */, _ULL(0x127FAFDD937D11D2) /* 961 */, _ULL(0x29DA3BADC66D92E4) /* 962 */, _ULL(0xA2C1D57154C2ECBC) /* 963 */, _ULL(0x58C5134D82F6FE24) /* 964 */, _ULL(0x1C3AE3515B62274F) /* 965 */, _ULL(0xE907C82E01CB8126) /* 966 */, _ULL(0xF8ED091913E37FCB) /* 967 */, _ULL(0x3249D8F9C80046C9) /* 968 */, _ULL(0x80CF9BEDE388FB63) /* 969 */, _ULL(0x1881539A116CF19E) /* 970 */, _ULL(0x5103F3F76BD52457) /* 971 */, _ULL(0x15B7E6F5AE47F7A8) /* 972 */, _ULL(0xDBD7C6DED47E9CCF) /* 973 */, _ULL(0x44E55C410228BB1A) /* 974 */, _ULL(0xB647D4255EDB4E99) /* 975 */, _ULL(0x5D11882BB8AAFC30) /* 976 */, _ULL(0xF5098BBB29D3212A) /* 977 */, _ULL(0x8FB5EA14E90296B3) /* 978 */, _ULL(0x677B942157DD025A) /* 979 */, _ULL(0xFB58E7C0A390ACB5) /* 980 */, _ULL(0x89D3674C83BD4A01) /* 981 */, _ULL(0x9E2DA4DF4BF3B93B) /* 982 */, _ULL(0xFCC41E328CAB4829) /* 983 */, _ULL(0x03F38C96BA582C52) /* 984 */, _ULL(0xCAD1BDBD7FD85DB2) /* 985 */, _ULL(0xBBB442C16082AE83) /* 986 */, _ULL(0xB95FE86BA5DA9AB0) /* 987 */, _ULL(0xB22E04673771A93F) /* 988 */, _ULL(0x845358C9493152D8) /* 989 */, _ULL(0xBE2A488697B4541E) /* 990 */, _ULL(0x95A2DC2DD38E6966) /* 991 */, _ULL(0xC02C11AC923C852B) /* 992 */, _ULL(0x2388B1990DF2A87B) /* 993 */, _ULL(0x7C8008FA1B4F37BE) /* 994 */, _ULL(0x1F70D0C84D54E503) /* 995 */, _ULL(0x5490ADEC7ECE57D4) /* 996 */, _ULL(0x002B3C27D9063A3A) /* 997 */, _ULL(0x7EAEA3848030A2BF) /* 998 */, _ULL(0xC602326DED2003C0) /* 999 */, _ULL(0x83A7287D69A94086) /* 1000 */, _ULL(0xC57A5FCB30F57A8A) /* 1001 */, _ULL(0xB56844E479EBE779) /* 1002 */, _ULL(0xA373B40F05DCBCE9) /* 1003 */, _ULL(0xD71A786E88570EE2) /* 1004 */, _ULL(0x879CBACDBDE8F6A0) /* 1005 */, _ULL(0x976AD1BCC164A32F) /* 1006 */, _ULL(0xAB21E25E9666D78B) /* 1007 */, _ULL(0x901063AAE5E5C33C) /* 1008 */, _ULL(0x9818B34448698D90) /* 1009 */, _ULL(0xE36487AE3E1E8ABB) /* 1010 */, _ULL(0xAFBDF931893BDCB4) /* 1011 */, _ULL(0x6345A0DC5FBBD519) /* 1012 */, _ULL(0x8628FE269B9465CA) /* 1013 */, _ULL(0x1E5D01603F9C51EC) /* 1014 */, _ULL(0x4DE44006A15049B7) /* 1015 */, _ULL(0xBF6C70E5F776CBB1) /* 1016 */, _ULL(0x411218F2EF552BED) /* 1017 */, _ULL(0xCB0C0708705A36A3) /* 1018 */, _ULL(0xE74D14754F986044) /* 1019 */, _ULL(0xCD56D9430EA8280E) /* 1020 */, _ULL(0xC12591D7535F5065) /* 1021 */, _ULL(0xC83223F1720AEF96) /* 1022 */, _ULL(0xC3A0396F7363A51F) /* 1023 */ }; /* The following macro denotes that an optimization */ /* for Alpha is required. It is used only for */ /* optimization of time. Otherwise it does nothing. */ #ifdef __alpha # define OPTIMIZE_FOR_ALPHA #endif /* NOTE that this code is NOT FULLY OPTIMIZED for any */ /* machine. Assembly code might be much faster on some */ /* machines, especially if the code is compiled with */ /* gcc. */ /* The number of passes of the hash function. */ /* Three passes are recommended. */ /* Use four passes when you need extra security. */ /* Must be at least three. */ #define PASSES 3 #define t1 (tiger_sboxes) #define t2 (tiger_sboxes + 256) #define t3 (tiger_sboxes + 256 * 2) #define t4 (tiger_sboxes + 256 * 3) #define save_abc \ aa = a; \ bb = b; \ cc = c; #ifdef OPTIMIZE_FOR_ALPHA /* This is the official definition of round */ #define round(a,b,c,x,mul) \ c ^= x; \ a -= t1[((c)>>(0*8))&0xFF] ^ t2[((c)>>(2*8))&0xFF] ^ \ t3[((c)>>(4*8))&0xFF] ^ t4[((c)>>(6*8))&0xFF]; \ b += t4[((c)>>(1*8))&0xFF] ^ t3[((c)>>(3*8))&0xFF] ^ \ t2[((c)>>(5*8))&0xFF] ^ t1[((c)>>(7*8))&0xFF]; \ b *= mul; #else /* This code works faster when compiled on 32-bit machines */ /* (but works slower on Alpha) */ #define round(a,b,c,x,mul) \ c ^= x; \ a -= t1[(uint8_t)(c)] ^ \ t2[(uint8_t)(((uint32_t)(c))>>(2*8))] ^ \ t3[(uint8_t)((c)>>(4*8))] ^ \ t4[(uint8_t)(((uint32_t)((c)>>(4*8)))>>(2*8))]; \ b += t4[(uint8_t)(((uint32_t)(c))>>(1*8))] ^ \ t3[(uint8_t)(((uint32_t)(c))>>(3*8))] ^ \ t2[(uint8_t)(((uint32_t)((c)>>(4*8)))>>(1*8))] ^ \ t1[(uint8_t)(((uint32_t)((c)>>(4*8)))>>(3*8))]; \ b *= mul; #endif #define pass(a,b,c,mul) \ round(a,b,c,x0,mul) \ round(b,c,a,x1,mul) \ round(c,a,b,x2,mul) \ round(a,b,c,x3,mul) \ round(b,c,a,x4,mul) \ round(c,a,b,x5,mul) \ round(a,b,c,x6,mul) \ round(b,c,a,x7,mul) #define key_schedule \ x0 -= x7 ^ _ULL(0xA5A5A5A5A5A5A5A5); \ x1 ^= x0; \ x2 += x1; \ x3 -= x2 ^ ((~x1)<<19); \ x4 ^= x3; \ x5 += x4; \ x6 -= x5 ^ ((~x4)>>23); \ x7 ^= x6; \ x0 += x7; \ x1 -= x0 ^ ((~x7)<<19); \ x2 ^= x1; \ x3 += x2; \ x4 -= x3 ^ ((~x2)>>23); \ x5 ^= x4; \ x6 += x5; \ x7 -= x6 ^ _ULL(0x0123456789ABCDEF); #define feedforward \ a ^= aa; \ b -= bb; \ c += cc; #ifdef OPTIMIZE_FOR_ALPHA /* The loop is unrolled: works better on Alpha */ #define compress \ save_abc \ pass(a,b,c,5) \ key_schedule \ pass(c,a,b,7) \ key_schedule \ pass(b,c,a,9) \ for (pass_no=3; pass_no= 64; i -= 64) { #if BYTE_ORDER == BIG_ENDIAN for (j = 0; j < 64; ++j) temp8[j ^ 7] = ((const uint8_t*)str)[j]; tiger_compress(temp64, result); #else /* BYTE_ORDER != BIG_ENDIAN */ tiger_compress(str, result); #endif /* BYTE_ORDER != BIG_ENDIAN */ str += 8; } #if BYTE_ORDER == BIG_ENDIAN for (j = 0; j < i; ++j) temp8[j ^ 7] = ((const uint8_t*)str)[j]; temp8[j ^ 7] = 0x01; j++; for (; j & 7; ++j) temp8[j ^ 7] = 0; #else /* BYTE_ORDER != BIG_ENDIAN */ for (j = 0; j < i; ++j) temp8[j] = ((const uint8_t*)str)[j]; temp8[j++] = 0x01; for (; j & 7; ++j) temp8[j] = 0; #endif /* BYTE_ORDER != BIG_ENDIAN */ /* Ensure that we don't mind endianness here */ assert((j % 8) == 0); if (j > 56) { for (; j < 64; ++j) temp8[j] = 0; tiger_compress(temp64, result); j = 0; } for (; j < 56; ++j) temp8[j] = 0; temp64[7] = ((uint64_t)length) << 3; tiger_compress(temp64, result); #undef temp8 #undef temp64 } /* The tiger_bp function does the same as the tiger function, * except that it prepends the specified byte to the input. * The THEX algorithm requires this prepended byte. * This function is here to prevent useless copying of large * blocks of data, since one should be able to drop a read-only * block of a (let's say memory mapped) file here. * * In the best case -- on LITTLE_ENDIAN -- data should be aligned at * (data%8)+1, but that's impractical: most of the time you'll call * this with either 3-int64's or with data read from disk (where it * is *not* cheaper to read smaller unaligned blocks). The * REQUIRE_ALIGNMENT preprocessor directive ensures that alignment * is enforced when absolutely necessary. * * (On BIG_ENDIAN this isn't an issue, as we need to swap the octets * anyway, aligning them at the same time.) */ void tiger_bp(char prepend, const void* data, unsigned length, uint64_t* result) { register unsigned j; /* Ensure that temp is 64-bit aligned, but provide 8-bit access: */ #if 0 /* This is technically not aliasing-safe... */ uint64_t temp64[8]; uint8_t *temp8 = (uint8_t*)&temp64[0]; #else /* ...but this isn't guaranteerd to work either, although it usually * will. */ union { uint64_t temp64[8]; int8_t temp8[64]; } temp; # define temp8 temp.temp8 # define temp64 temp.temp64 #endif result[0] = _ULL(0x0123456789ABCDEF); result[1] = _ULL(0xFEDCBA9876543210); result[2] = _ULL(0xF096A5B4C3B2E187); if (length >= 63) { register unsigned i = length + 1; const uint8_t* str; #if BYTE_ORDER == BIG_ENDIAN temp8[7] = (uint8_t)prepend; for (j = 1; j < 64; ++j) temp8[j ^ 7] = ((const uint8_t*)data)[j-1]; #else /* BYTE_ORDER != BIG_ENDIAN */ temp8[0] = prepend; memcpy(temp8 + 1, (const uint8_t*)data, 63); #endif /* BYTE_ORDER != BIG_ENDIAN */ tiger_compress(temp64, result); /* Not 64-bit aligned! */ str = ((const uint8_t*)data) + 63; i -= 64; for (; i >= 64; i -= 64) { #if BYTE_ORDER == BIG_ENDIAN for (j = 0; j < 64; ++j) temp8[j ^ 7] = str[j]; tiger_compress(temp64, result); #else /* BYTE_ORDER != BIG_ENDIAN */ #ifdef REQUIRE_ALIGNMENT memcpy(temp8, str, 64); /* 3.5% penalty on x86_64 */ tiger_compress(temp64, result); #else /* Misaligned, but cheaper than the above option on x86 */ tiger_compress((const uint64_t*)str, result); #endif #endif /* BYTE_ORDER != BIG_ENDIAN */ str += 64; } #if BYTE_ORDER == BIG_ENDIAN for (j = 0; j < i; ++j) temp8[j ^ 7] = str[j]; temp8[j++ ^ 7] = 0x01; for (; j & 7; ++j) temp8[j ^ 7] = 0; #else /* BYTE_ORDER != BIG_ENDIAN */ for (j = 0; j < i; ++j) temp8[j] = str[j]; temp8[j++] = 0x01; for (; j & 7; j++) temp8[j] = 0; #endif /* BYTE_ORDER != BIG_ENDIAN */ } else /* i < 64 and we didn't prepend anything yet */ { #if BYTE_ORDER == BIG_ENDIAN temp8[7] = (uint8_t)prepend; for (j = 1; j < length + 1; ++j) temp8[j ^ 7] = ((const uint8_t*)data)[j-1]; temp8[j++ ^ 7] = 0x01; for (; j & 7; ++j) temp8[j ^ 7] = 0; #else /* BYTE_ORDER != BIG_ENDIAN */ temp8[0] = prepend; memcpy(temp8 + 1, (const uint8_t*)data, length); j = length + 1; temp8[j++] = 0x01; for (; j & 7; ++j) temp8[j] = 0; #endif /* BYTE_ORDER != BIG_ENDIAN */ } /* Ensure that we don't mind endianness here */ assert((j % 8) == 0); if (j > 56) { for (; j < 64; ++j) temp8[j] = 0; tiger_compress(temp64, result); j = 0; } for (; j < 56; ++j) temp8[j] = 0; temp64[7] = ((uint64_t)length + 1) << 3; tiger_compress(temp64, result); #undef temp8 #undef temp64 } tthsum-1.3.1/tiger.h0000664000175000017500000000370711656447501013723 0ustar walterwalter#ifndef INCLUDED_TIGER_H #define INCLUDED_TIGER_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * The tiger3/192 hash algorithm (192 bits, 3 passes) */ #include "types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * The Tiger Hash function. * Supply an 64-bit aligned octet-stream and the length of the _octet_ stream. * The last parameter, result, must be large enough to hold 3 uint64_t's. */ void tiger(const uint64_t* data, unsigned length, uint64_t* result); /** * The Tiger Hash function, modified to prepend the specified byte to the input * data. This is useful for the THEX algorithm which prepends a 0x00 to leaf * nodes and 0x01 to the hash nodes. * * Note that this function does not align the data properly on little endian * machines. On big endian machines it will re-align because it copies the * data to a temporary buffer while converting the little endian input. * * See tiger() for details of the other arguments. */ void tiger_bp(char prepend, const void* data, unsigned length, uint64_t* result); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_TIGER_H */ tthsum-1.3.1/tiger_test.c0000664000175000017500000004613511701307706014750 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009,2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "tiger.h" #include "base32.h" #include "test.h" #include #include static int help_cmp_base32_bin(const char* name, const uint64_t* input, unsigned input_len, const char* base32) { uint64_t res[3]; char base32buf[40]; tiger((uint64_t*)input, input_len, res); uint64tobase32(base32buf, res, 3); TEST_PASS3(strcmp(base32buf, base32) == 0, "Tiger hash result for \"%s\" is wrong! " "Expected \"%s\", got \"%s\".", name, base32, base32buf); if (input_len != 0) { tiger_bp(((const char*)input)[0], (const char*)input + 1, input_len - 1, res); uint64tobase32(base32buf, res, 3); TEST_PASS1(strcmp(base32buf, base32) == 0, "Tiger BP hash result for \"%s\" is wrong!", name); } return 0; } static int help_cmp_base32(const char* input, const char* base32) { unsigned input_len = strlen(input); uint64_t buf64[32]; if (input_len > 8*32) abort(); memcpy(buf64, input, input_len); /* force 64 bit alignment */ return help_cmp_base32_bin(input, buf64, input_len, base32); } static int test_tiger192_nessie_1a() { /* echo -n '3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3' | * perl -e 'use MIME::Base32 "RFC";$bin=<>;$bin=~s/([0-9A-Fa-f]{2})/chr * hex $1/eg;print MIME::Base32::encode($bin)."\n";' */ return help_cmp_base32("", "GKJ2YYYMCPYCIX4SXOYXM3QWCZ5E4WCJFXPHH4Y") + help_cmp_base32("a", "O67PX3ZOP34KWLWI7E57LB5H7RQT4JD7L4SHQCI") + help_cmp_base32("abc", "FKVRJBHIYFMPFP5YYX7UDNL2KJISSEY4SV5V7EY") + help_cmp_base32("message digest", "3GA7RS3YEANJKDOPGBEHKHSEDRIX7SQ2UVNCT5Q") + help_cmp_base32("abcdefghijklmnopqrstuvwxyz", "C4KKI4XO4V6TABAECK74YVIDFIFRCYBP6N5652I") + help_cmp_base32("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnl" "mnomnopnopq", "B557TIM3TRMPFN3BBX36QTYKYOTRYYY6PNJ7PDQ"); } static int test_tiger192_nessie_1b() { int ret = 0; char buf[2048]; char *p; int i = 0; /* A..Z a..z 0..9 */ p = buf; for (i = 'A'; i <= 'Z'; ++i) *p++ = (char)i; for (i = 'a'; i <= 'z'; ++i) *p++ = (char)i; for (i = '0'; i <= '9'; ++i) *p++ = (char)i; *p = '\0'; ret += help_cmp_base32(buf, "RXHKNAFBOWB64UBLUOFDYNUGKGEQ766M3RE2RTA"); /* 8 * (1..0) */ p = buf; for (i = 0; i < 8; ++i) { int j; for (j = '1'; j <= '9'; ++j) *p++ = (char)j; *p++ = (char)'0'; } *p = '\0'; ret += help_cmp_base32(buf, "DQKHSVJJ7WPSA6UVR6CMKLYR5CD7UDFL37MRX7I"); /* 1M * 'a' */ p = (char*)malloc(1000000); memset(p, 'a', 1000000); ret += help_cmp_base32_bin("one million times 'a'", (const uint64_t*)p, 1000000, "NWYOE4U4X2WZHVYVY2T5GYYC5GZ45YGSXQYUWQI"); free(p); return ret; } static int test_tiger192_ross_and_eli() { return help_cmp_base32("", "GKJ2YYYMCPYCIX4SXOYXM3QWCZ5E4WCJFXPHH4Y") + help_cmp_base32("abc", "FKVRJBHIYFMPFP5YYX7UDNL2KJISSEY4SV5V7EY") + help_cmp_base32("Tiger", "3UACGB4Z6UAJ73DN5PEDRO3KE7PSXHLPCEGHSNY") + help_cmp_base32("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr" "stuvwxyz0123456789+-", "64OILA4QFL5YPHW74YIPQLANI6DKHJJUKBCINNI") + help_cmp_base32("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopq" "rstuvwxyz+0123456789", "JDHOWYYIXB6UN2K5MVQRFTPRRWLZCX4XMVSYSVY") + help_cmp_base32("Tiger - A Fast New Hash Function, by Ross An" "derson and Eli Biham", "RKDGQKIEBJAQY4U22I7VVWTRCYB3HTOTK7SMCXQ") + help_cmp_base32("Tiger - A Fast New Hash Function, by Ross An" "derson and Eli Biham, proceedings of Fast Software Encrypti" "on 3, Cambridge, 1996.", "MMNL3UID5OND2JC3NX6U255SK76HIOKQDUKWRXI") + help_cmp_base32("Tiger - A Fast New Hash Function, by Ross An" "derson and Eli Biham, proceedings of Fast Software Encrypti" "on 3, Cambridge.", "ZZK2NL6VSH26XLCUP74E7CJCP6JTDWVQWYI4RCI") + help_cmp_base32("message digest", "3GA7RS3YEANJKDOPGBEHKHSEDRIX7SQ2UVNCT5Q") + help_cmp_base32("12345678901234567890123456789012345678901234" "567890123456789012345678901234567890", "DQKHSVJJ7WPSA6UVR6CMKLYR5CD7UDFL37MRX7I") + help_cmp_base32("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr" "stuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm" "nopqrstuvwxyz0123456789+-", "YVADJZNUH24AAWCIU7QK42VMO3SP6WIK44K72JI"); } static int test_tiger192_0to255() { char name[256]; uint64_t buf64[32]; char *buf = (char*)&buf64[0]; /* char[256] */ const char *results[256] = { "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ", "MWYOD2RWZIL63YXQKXTH5LLHWHBIFII2LOR2RYA", "VN73RUQ44PMNTO27DLY7F6QNHQTXSBQWBW4NEJQ", "7YXJ2Q7XJMMZ3ENZFEOXHTH4UC7KL4DI7OREJ7Y", "HX3NM4X6TWVLEFJD5MCHAXMKRNZLPCYAVVDF2HA", "4BLSINJ74KMVPQ7I325KEHIMFXKJZSRCDEOVVUY", "IBLN3P4CVZ2KWVTSBXVPA6NMULYHN3IENUCE3ZI", "QAP3TPQ2TLDTG6UBGRNTQRPE47ATV4P3VW3TOIY", "IMAVMVD2QJESZKCZHBJQI5EPMXZNJJ7CMZFOFMI", "7RBVCN6NMUWXECQR5X2HVPSGQC5EVVN5QEGJQNI", "ECUBIPPUP5LRL6QJAX7G7HI5FNNS2TRG7KMJGCY", "4SRAMMAZ7PADJXVQDYVJKKLAIIYZZPADTWTJVEI", "WXYPUVYMJTLJUPDIISF6ILEGLPPXP3LIXE4HLZY", "QAV6N2RM5BVAWNY7ENKJISYZZMZDDL37WTYA76A", "27AIQY5V4XR5NG2UASQRMMK2NGHBFDV27BRWW4A", "LRJIRSYOJZJTAVV2KKJUIDM343Z4IYJDHPY62UI", "RDJ2STZYEDSAQ7NGTWF34LHUCVDGAY3QTRCQYTI", "YB5UWFK7T52YAXM5BBYIP7G5FDIIVHICEGJEI7Q", "5ZDT4VU76PQJFT4JS2ZRZZTF5J6WCUQNILRHHFI", "4E625AEYCOOPZ2TVLUQGB4IH4PDVQHW7T5FTXBI", "WSFJYCPSNM3ZVIUPXR2QWUGO62OQ2DXDP73WL5Y", "K5FACRLDOMAU6QLZZWQUKQPC4PC2DTO2T6OQOHA", "6LRIGHS3WSXQLEKMJOTBXOGWADI66BY4LXYCE2I", "W6AIUW3CLDF6OGHNVE4JPDDJ2P74IWRCF2O36TA", "3DSOA5W546EVBVI6VSPZPUWRSFVASECGLVC2KXA", "J3PM7KXB32MLPYCW4ZGKEQADIIV343YEQEU3ETA", "BXRIHNNESU7KV3DPH7PFBV4HLSHOK75HTPOHB7A", "5TOUXIMTNW46N6B6FPL7HHJDSJ5BUF5S2UVIMSI", "XYIYSNDA4SLFT567H6Z32XR6TIYZ7BP5GSLOE3A", "V3ANUDZMYBSGGJOMAMYZUDQIB5ULI2ZT7AMSBVQ", "RASP2OMYJ5VFF777DEAW4J6FSSJBIUQIMNZ7F3Q", "RNSZFL53ALRCPKSFDNOP3SBBXBBELU2LS27U6EY", "SYG7TQ2J5RTBT7ZX4PYPJAZODHGGUTSNNCLCMUI", "6TRLPKTSXR6W4DHW3IIJJPXPVKOFKYIDE7DCSAA", "AX6RXAGKJR6BJ7S36CWL2DVD3LSJRXBZDXHSE5Y", "YXUV7FJYTDDIGVNVSFIHXNYU6DS5VOMYTUEDSAA", "WLKOFBWPP2UKW3WNMUGJ4SGKENEX5LPFKSC5WHQ", "TVIWK7QRYVH734QF3O2DKCL2FPDPSPCL5DLBQCY", "HRVOHEITK2RUHLRRCNZV6B747NPAI2WNI6YA7OY", "MZBUFTPMZAS62NAKP77C4VYQPXILL4SMESZMH4A", "J337ZIJ442CNQHPE6VTNFCL45NAH7OZ532A72ZA", "KRUJ73HNMPZJPMJ42SKLQXTIM2APJ54N47WIDVI", "V5BUXW64P34QXYB6ICQDH4LORJL3IGCA4HUKWWI", "UMW3M6HUJEC4DCLI6XMJRSTZSLV6FZGMGMMLS3A", "33U5KGNBFLH3RIETLI3I23TMOXXO5ZXSWDK5DEI", "ZPDUQY2HFUOJ2I6FE32JBC6U2QRU4AGLZSM2T2I", "NQRIUHKIOHUAFYBVZG5RNRIYONKIIH5WXY6GTNQ", "ZKTVLRK2VBU6MM6LHRWZHJLBSRFMOQMBKTRLB4A", "U2BV67AMNSUPJJCXQ65PU52HRLU23W7PXQYFFUY", "4QDHKWKX5QQ3U2TEWXJ2V4YXJHHZRX4S6GY77YA", "BQWUURFIAPN2TG32IZ2VHSJJHNDKKOCVRPLX3VA", "6BHQCGYJ2J22DBKSRTAEB23RSZE4QRY2Q6ZFTMY", "HWULK77VF7FOPQZGG3WGZADQQGE45WARHRON4HQ", "NRWIROHBRX24WIXNWYNC2PWXI5A2OCF4IZLW7NY", "FVEO4K7YLXRDI5KL5TZ4N5NQ4YUYRNN7ESXKLOY", "BULXALO4UB4O2HGFDOK56KPKCBJ45F7WSOK4MEY", "TWGCVUZH3ZB5K6BNL4QIQH2KRRBTXIM27SGBLLI", "EJ52IGNXMDM5CDN3BFMF5XKHLLBHGT6UKOPYE5I", "F5JCBKBI56KOGJ55KHKN6XCYMCPYVE5Z7YA775Q", "B3WZ7EPBUM5FBOHJCPN2BNPCJDJGHYP4OLDKISI", "OZVXA7UZT7Z4KHXACFUFCO5A3TX6VMRC3UPWT5Q", "QXTHCBUU47BWUI2A3JVDOHAFMBCQ6PKE2NNNTDA", "2QA7TMJ5HHBEI56AVZUXDRYFYY6AM7ZJKCGCTSI", "EEW7RHCXCVJHANCKZSYZAJ5QWJVRAT5A7O7A7ZA", "HPW6OZ5KJJ2QPW7P7A6RXQZ7M7V2TRSJIUDGEJY", "PH7ND647C7CJQAII5BQFYEGZ4F3KZD7E62TFAZA", "JDM3OYRKW74JNDWZEYSV66HIZZDB4TERML76RNY", "MY4MQOBXFF5T6U5Q7ASMBB6ZUC4NT7DCMVUDXDY", "C5CCDT3NGMP7KGJE7CKG5ASEKVOJAIGTRYY3NWY", "APSCV62776NZYN4UUPN6ZGP2PY7XGBPPA66ST3Y", "ZSX4NDKLH3MITXE7FDFZEJMARJAKVDQNLSRUH7Y", "5ASPSO2AEIARRBXPYVCTTVGV2UMGHLNDFH5U4IQ", "PTYNYANTEZUHKMHUEBALUDIM5EYXIRK6RKMQ2FA", "PKHGDFDZ6T24IGHMAQMANBIOM4R4UVVPXQ6TFTA", "BA6FZKIPJMUWYQQEAVM4QKLBJHKO5OVV54WLQLI", "GWA3PLBS7KFATBX5CTZHP6YQNYISXEWRRTLITPI", "EWHIELM4YHWKRNK5SJN2GYN2FWP4E6XRQHYTRNA", "VBWB5CFGIUK7UKA2IYWUM5CYEMKJJ4LOQNO7Q4Y", "O3T7A37JXCZYRWYBF6FUXYX3GQ7ZLEJ63XSHUJY", "AATYWTSWSDTST3DRDC236Y6J2HVRE2EWBCJ4U5I", "RXTQ4ZFDDOQ26T24EPHXOTGKGL7JKLLWYP65DNY", "XPVHFSCAOSN2XLYUCX7KYNBUCG4JKFNYPBEKBGQ", "Y3B4ZLA3GOG7CF5GD3HZUKAOTOTQS6CMOK3WO4I", "V2MBH32EFHVOOPVJ7W26EPJGHLY3XB4SRT27ASA", "NBSHZV577OHFGDJIZBTILKGS6ZL64TGWJ3OX4ZQ", "VKGDLMHHI2XVMQ27NRYRVUCCHFTOURMQQ5AJOEY", "VLK4BVPJQCZJXSEJQXCUI4L3QH2YZW4SHI2GRYA", "6YESTUKHQHPEJ2TAPKX4BUS7UG3O6PDKUD4LHVY", "YSAIPXDV5RB2KSSZH4SODM2ZXN24LANGLQYXBUA", "CHITOL557WP7KFDBDKZA2MN2MLYYQVWI22XDVVY", "6KUAO24QC7W233WUD5AJZHRS5M54BEHK5CPYKXI", "OAX2I7S32NPDIS23Q7AAQIIGGNZANSW5HVGVAFA", "XHQD73LVFJLAYOYDMXW7LP6E3R7KYXSLXOJXHDI", "HSCMKK7VCB32LAM7K3S2LQOAMIERQFLZHEZCBRY", "7DWMUKFFEVMU4E4LKXAGMF5AMPPXJ7RUNHMYHAI", "CCA4HOXOYCW7JGAMF2TFSOYJA3OL5XSIAV2UO5A", "WUKS4OO6BP7ITAWXQP6E6DFXCYHLFVU7N45T4WY", "NJVXMC73DFS4OKWHSP44AL5CDMHRYNF5EZALW2Y", "DZW4X6ULVDMWYKIQC5UKNI4UGPK22WSQ4CLQOMA", "OMZCFU5AGM2R7L6WRROORJGYGO5HIIGUIEB4W2Y", "4TGX3JM3EFPR32VI7O5IKDZMDJ7UYPKJL7TIASQ", "PPTYY6IHCNKFOVGUY6FJGGFMUSVALDC4ENKACMI", "W4ODQCNFAS7C6V5OTYS33TBZEHOGMXDFFCPKKWQ", "FOGKHGLXKNPLNEXPX4G6ZWUJOGUGAT37ZOXHLXI", "HTCIWUPEYXPE6DBKXYF6N3SLMPGFMSUHYAMUHTI", "CV5M355VT7BFSZXZPAZAOVKDMSECQQHHEUPNNQI", "32Q47LWPDDJWCHGNAULRGGQW3W6JPIJJALOYXKY", "FLJOTEF46ZEBFBG7IS4WCYZGQ7BOMTP24KXBNQQ", "QOHTUOZIUUFBFNLQOSIKMYEA3T5AEMHFQO3OWFA", "ZCZAGFISDTP3HKI3YDW7CGEG6KB463CIB5EYMJY", "FMH3ATYQBPU22UNX2ZGHMZI3VNFX2MOR3EMVOEI", "WZEVWYSW75DE5RAJUQEYWYRORPN3CABUCGCU7VY", "C5A2PCKHFYQODTEJQ2NCI57E6KAHYIQYF2S3EII", "A6W4QLFT6JZYTIJLNOOCWJUL3X6R3FDY3HW2BVY", "3G6WOYH3QGNIUPHOOUYD7AQI7SR6COFVC7NLSNA", "T7HSDKJDNQWBFBQ72IHR7MK2DB6NP3TYEH3SXZY", "OPIWK5U3GTNG6FIUMTTBCFOQ4CNGN6GQ7ICJOJQ", "ORMAX6UI52QDYDVOOIXYDGL6IAGZZQS7UAYR36Q", "4PDKG2MCBYTHZE4NE5VILCJIAQGHYJNIEZIB3RY", "YIFNSDNQXC7OAM25A2JFTGIQMCLJ53E7SOPEZJY", "6N2G6TGWUGOMCN6F7TEPMCSMBJ7VNWLRSC32TQQ", "MOR3PHVPHXZVDAEWARSQLHAK33QG2RIXTJLCQTY", "MBVP3AZ5BATCRVMGOJAD5ZW3GSHG62GYZUMUP6A", "OVT6VDQQZPZRF6CHRN6FDWD3AC3M6PPIFMB5ZZY", "3PG4FONYLCPWY5QWWVNQLGZ3HY4NS6U6NXY7FGQ", "CXMZBH4NNFUJ47TYUDNZFAMUUWLCHZZFHKU5IAA", "3Y4VRHOMBRSUQZ4UHAAZI24YRCZUOUTCPHFBLPI", "GT5HY5HOM7A7SLAL4HH5JMXUNIKP7OMZMBESL5Q", "32RM6ILFACIWWHX4JGFYI5U5CD6CUTYFDHR5POI", "DGD6BKKGH3AQUVA7DDOZWS2LRPYTCG5C23GNLKA", "KAQ2LYN7TEYGNVIVRGTWRL4FDSS7GPIRVRRY3KY", "RY4HR4SOJ32AV72H7CEFIIXV243JAEZCRVXFNGA", "YDS3SGLNKTO2XBRYTXRT6CQFC5RPCTWY4VIR6VA", "TOZ7PTUDBNRYA2P4PUAOWH3ARMW7ADF3R4R5XZQ", "2VN5HKX2D4YH3IQMMILR5OU3KSVZFUU6YLGSNIY", "AHDZC2W5Y6YBQNKPIJQLYXUJ3IWCTAZPBF24SGQ", "G7YYLV7LIVZSYBBAKYZ4R6BUWXO7KHZ7KVPPKRI", "QGC3IZH4PMI64TRRC24QESZKGUEXJMLFE6LCRUI", "MAO56LXX4CO7KHF3VRBXN6ROPZYA3F6OU5HEOZA", "NXJZ3LLKNFIGECW3KK4FLRFYJXR656BBRUZGGOA", "YRUYD3AKI3SIVIH5JTQV425AVNCS363J4YGK5QY", "WBZK3JBTM5J7OQ62IPALVEV3X66UY54RM427YJA", "YYF7KUUYFKY5O6QO7HXAQA5TZVVMZKJEPKKUC3Q", "AAM2ABFELIJXLKNODF4AHLNHSOMIKTKPT742OZI", "3YUIDE5QJGJVRXXX47FZFFDVPFQ4UZFPEQWBXHQ", "HK7TEYEMKYVUHFUB25XJC2ZRBKBHLHRFUHKORMA", "MGF5LPUOV2QUETHAAKGHYXQYXEKD7GG4HP2UN5Y", "EKNBK6YSSIDDZTUZKW2S6QJRX3WQRBPAZXNJDDQ", "HWWBBJ3Y2V7T73HZVQ7G2YPBTZEIPCKGZHJHGWQ", "TUSLJITDCZP7K3IEZHD6PH5ZJN7TFQOUIIXAOMQ", "E7VYSFDMRIGE5OULOWP67BCEA5IKCQLTUTVTNWA", "XYJETXKBVW57IIUABPGKJI46XREQSTZUFMDNFGQ", "PTYB2XTVSY7XRYNLNARPN6NAZOCGBVTLVOZUYXY", "WVAE3KBQLN2WWLOE4YFU447H7PRALW3IMWIEL3A", "RJC52KLP336OETVMOHIYMSM5IWD5FY2C77HTZEI", "7SEPD75TGIFSJQOYC232N4YCYRXC7NC7SLVR73Y", "DJ6AGOILGDVFL5ZJGRUU7JTCEJFWPSU6MYHH6RI", "CTNJSYU245C6H3UIQVY5RMNJ3OPBWHMB4V76OJQ", "OGORC6O2MB6IDTKYUILD6W2AY3RRDQBACL6JVPQ", "IJ4336JAXNGBHTHNBYNQ7TS6O4V6POP7UHARAZY", "U7EFYE2KTRCPB4DRU6EB4F2JGOANBN7RMHLJ4YI", "IHKFGKRUUBEWCPAAQJKUOM5ZFG3FP3GHWHGNQRA", "TODCDW4LPZS2NWK5DRIBA3J5G2GCHIO2PIIVXGA", "LRLOEZ3HQRTTPTIK3MMEUJCOIBNRDJM4KD4R2BQ", "IDPALYFIHCRENOVNATHEF6CWEDWEVDGVFSU2MWI", "2MBXSFC6RFO674PVSF7FIVW7JIZJUCNFRZ3TMPY", "HLMYUQO5K6FQGCU6TKVG7G55XQ6P6W5UGJTPZMY", "IYG2OE2T5QEKYYH7U4PWQEKAMGNU4XOO3X3E2JA", "KZLRXQ3K5KXF7HEIBMMNGZWXXF2NTNKKKCBZURA", "THSWZB6CU6TYPB6YEODWJI6GPTARSN3O2OWFTNQ", "6TOHWP2AIVPZSFU7S5KOBTX3H7TOQG7YCSWMKCI", "ZXTONTTSRYXGLT2JC75OMWFUVBDSLLYGMYKT72Y", "MRIZWQYCM7QE2A4UOJB2XLQ6T3FRDQ7SP7JEZ2I", "PZTTS46DJG2PMYTLOHDRR3DOKNGHOWINXBHWE7Q", "W2OFMNVOWMDAL5WKJJTRX2BYXM5KBHH3OUKEGQY", "JJCDGWPQ3LB34AWD2XX3UEN23P2XXJZ2YXPHWEA", "3F5FSYBRDWYQMEFEFSUAUG44A3QUQLVOHZNOODQ", "E4OHMFFQFIOYB4K7DHVGBXYC54SXF3QO3C3Y3FI", "ZA6NHVBVUIIRDY6BCXWOBWQD5TASWUV3KZNDI4Y", "YJCMEZZ2JGFJUW2Y2Y2WOO42KIAYXHHLTX6EPYI", "XD6JPM6DMKD6NTPPFEFOB57EOBUDMJP4LBD7ZFQ", "OZBHUSVBAVJZBYOVUHVMKBALFYXP345BGQ4XSSQ", "4QA33HZMJJPNT4XSXCJTKYKJ6V7DMQ73225Q2TY", "F5SLLM6AXAVPOAULYDB2TLY3J32GJZ5ZNTQNFUY", "VWXRK7F3R2ZLMCEUMK3QN6Y7BXI4O2UC7V3OKJA", "HYIRWDFF6PDAJDEWDWCJAOVER4ZAHC4MGXF7VXA", "OARGE3NPDEUZCF5LKXLCLP47IAPEKKH62HDHK3Y", "2FEP6FOWAMLPZE43I64EE6LYWVP7MUBHCBEODAA", "IYNG4VYBO32ADGEQ4GQH3AAKY2UGILZDY5TG6GY", "MELMIUEKN24DJIPKRPM4XYWCTED5KBIILWZBHUQ", "D7F6NJVK53BPIZHZFYIANJJ3VDI56ZX3ID4QDWA", "JEUJXOTM77T7SLFBA2L3Q6I7MQP5HUZL7CFKS7Y", "ORDNK5DB6T5IHQJE4NLS5DF7VZU2FTV3H565SEI", "HTJD4F42BZ64RNWGMMJVM7LTW4VRKW4JHZGFDHI", "G7QTMS6DLMKVEOOMFS4A2YWWEEXGOR67SDCTZCQ", "KDF4GLZP4WGFGTNPVIEZTOYMMBBS5HIIJUTFUDI", "FWQBOAZMVQLA4E5BMEVLK6DRWOMEXDZ7BVARFTA", "6RSPTN2DJSEJUY2VBLSRIUWH3VG2TZBZWBR7IZA", "6IARIZQCKVK7HLJSHXBWELEIAUKMGLP273ZIXOQ", "NB7CEN3VJPU7ZBCITQAXNHZKINMLIGW7ANVYFZA", "RJC44IPNNHRCFEXLBT7LZ455NRU45XWPF4DKDBI", "5MOCB7SLPFJSVM553DHRRVRJSBV7EGPHE3C36QA", "7DJXLJEVKAM7XHQPPPKSNMBWXT3COBEL7XFRITI", "6BBPKU43LJ2RLSRZBOKGMPEBX536DSPHWOIV6EA", "PI4E3BDUPERN6CXYMK5X3UQMWORLAMMP4VPUZWA", "YZWIPSJZQNMJZJO47DRZ2ZLXUSD2RSXJ6F4BJBA", "4HIQKOIHLZOWZNJF36BHTIHGFPYLDYOMIS5HPEY", "EB4HKLKAQP7ZEHWLNYLBJSDAIPD5GCH6F22W5UY", "2GR57JDXL3TCEYOUTHGXRAY2ZKO3A3G2NQ3GRHA", "AZ635YQX5IHUIJ5IKYZVV4EVYDBIOTBOYJHECGI", "DN32SZO6SEU7SEHU23ZNPKWFBEA6ADNT2BWF2QQ", "2XJ5TSJ7UKK7MJPBO4NBBW5FXPLNFISJ7EPER7I", "JB55WLFKIR3PLVAK6BGG65LVG56JQX224MJ6G2Y", "4MW7ZSNBX4LSURKHSIYAEEFFGPUJOMRVG4QJALY", "XT3ASJ6DIECY5VYWHLV7CPVERVXNFBGUW3VQ3HI", "QQNEFKUIIPKFQM6Y4XSKAHYD3OAT75ZHXW6366A", "EUXMMGHHGC6HZ7UGMFNJZCOSXYTA7PDM3UUWEFY", "5MYSTBUSOYXB6W5XUTPYD2A3XEHA2JJTEKSGPMI", "72XGOD2IY7MFXK3URTCMBEVAPIRP44ZUOERJXGI", "DOF4GVPB3UQFM2FXKX5XZPEL3MYVIJG53QQEXFY", "NZQZPSB3Y4NY5R6NZSDZZEYNFJW77OGVC63JQ6A", "4LKYFNQQUE2JBDR5MZ74KX54RHSWGBWCQVMKSKY", "XH5YMKIQHK6COXGT4JBY5IO5SQTS6IZ4PDIFZII", "TZPF64R4YI6QL3ZN2UW3Z3YJQOIG5ACDZ47WDPA", "S5PGNXT2WOIMIZDU3DHAIWVDJ25NWGUU3VEPDII", "ZTCDIG52EXSTQSNXMFZVYXIB5MX2CCMEZEAWGTY", "GTUJMZY2CSZQ3WX6A23BCGRBCBY3GLQ4VVL67RY", "BOOXD4JIXX6WRN6BQU6JDZ76PEMDHN24UF4EAEA", "75JXVY2ZT4JJNWRKSTVYOY3UDRSYOEIX2QYL3TQ", "4EVUFPLLBEXNBX7DC65LR3ELULPDXYKAQO2RRFI", "3RC2GTPP5M4RAZAOI5ZTTFJFOIE7I4THW6JP5HY", "ISM2YBQKIDZMLDARHCN75AAWVAVD5ISHIA7PJAI", "BLB4GRYDVNHZNGZJRP4I53IR2JYXA66OLSWK6SA", "YO3ZP3NESLRUOJWJ2Z2ZCMTXR53DA3RSCMJSWFY", "FC4BPAJVHCW4D6GDYVQCIA34S5YESFTXSWPVIAY", "VQWALTQ2VV66M75RRCRG4ZEFBBHER6TLHQ6VG3I", "FCGJCN4WPOTGMZBBLMDKG5SJLIRT7HPFWOYAIJY", "XABLN2BETS3DMOFSDWSMBCNBN4AECT75GTQZ6GA", "5YBTJHDV6AILPCSIPTHMNADWKE645GX3N4MHZXA", "N6F6BY5IP7IJNT2X7TRRY3SCZ4ATZ5VHGZ7EFQQ", "JAAEWOBNORJASTMJ3JUFMZFZCVLF7ECHPTORUXY", "HX6GPU5GUAT5MJKE5O63XWYAFA4ZX5KY6RKRP2Q", "G42Q47J2JYQO5L6CDRH2ODBHUIEAG6XHLMHSFIQ", "QEIE7IKMSAI5UIVDJRMYMPFDHBEU7YRZF2BYGVI", "G3VSBYIRM76QI4I36PQ36JGJXHNABSOLRZRN4QA", "BBXWENR7SUAV2OPOWT3BEZWQEQETQFMVHHAOZ5Y", "O72GHKBQVOD2SM2UH5DWLSBROAPDO77WCFPLMJY", "SSIRRW6I47HUQLBCJU47HROY52OWN6VGKYERCPA", "PUMGP24L3C3BK6OLUNN75H6TNTXGO47BJYQLYQY", "GD2TAVFT3EMTPGL32ZQAFBZ7T65QAKJ4QFFYNAA", "7XPTUXVFHWNKGNK6SU4DJBBXR23NOWIEO4LZGNY", "V66BL34FLEWONDE4Z6WCE6OOE4SXJ2A767VGJBI", "DZ4DTF7KCDSBBUXQV3ENXBV3QBNVCJNURAL6VFY", "Z63ZRRF5CFJ2JODAZ7DUFFGGIIIO26XHC2BYCEA", "SCIIV6BFYPFII5GNTWGEEAPBUEXJOYYP67LOGVA", "UMC6OJR6MLYN6ZWWL2XM5CQC7TROEI4P67C4PJQ" }; int i; name[255] = '\0'; for (i = 0; i < 256; ++i) { /* Avoid snprintf because it's not C90 */ sprintf(name, "", i, i + 1); buf[i] = (char)i; if (help_cmp_base32_bin(name, buf64, i + 1, results[i])) return 1; } return 0; } static int test_tiger192_alignment() { uint64_t res[3]; char buf[127]; memset(buf, (int)'A', 127); tiger_bp(0x00, buf, 127, res); TEST_PASS3(res[0] == _ULL(0x007bbdabb402654c) && res[1] == _ULL(0xaa7aefd7cb812b2d) && res[2] == _ULL(0x1df2166aea456fca), "Tiger BP hash result for \"<127*A>\" is wrong! " "Expected 007bbdabb402654c aa7aefd7cb812b2d 1df2166aea456fca, " "got %016" PRIx64 " %016" PRIx64 " %016" PRIx64 ".\n", res[0], res[1], res[2]); /* The ARM fails on this second one when unaligned access is attempted on the * last int64. It rotates some values and ends up with 8*A instead of 7*A+LF. */ buf[126] = '\n'; tiger_bp(0x00, buf, 127, res); TEST_PASS3(res[0] == _ULL(0x8dfae2bea717c033) && res[1] == _ULL(0x91fc74dffb9eba48) && res[2] == _ULL(0xe62d12fd8ef213af), "Tiger BP hash result for \"<126*A+LF>\" is wrong! " "Expected 8dfae2bea717c033 91fc74dffb9eba48 e62d12fd8ef213af, " "got %016" PRIx64 " %016" PRIx64 " %016" PRIx64 ".\n", res[0], res[1], res[2]); return 0; } static int test_tiger192_abelarm_o3() { uint64_t res[3]; uint64_t const out[] = { _ULL(0x60d56f0949e7560f), _ULL(0xcf62a9d35ea20959), _ULL(0xd4f5836a7ce76166), /* 0..124 (len=125) */ _ULL(0x6baec4efc36d6da1), _ULL(0xf87ff3d2852f0250), _ULL(0xfbdb48ea8c361c38), /* 0..125 (len=126) */ _ULL(0xa950e3ff469b7cc2), _ULL(0xd2e5105a998e1647), _ULL(0x7dc3bc1a875015b5), /* 0..126 (len=127) */ _ULL(0xaa322e0262d43ccd), _ULL(0x85e408a00248ee64), _ULL(0x327f3eec7f32687e) /* 0..127 (len=128) */ }; char buf[128]; int i, j; int failures = 0; /* A different ARM (abel@debian) fails on this one with -O3 optimization * when an uint64_t pointer is pointing to unaligned memory. */ for (i = 0; i < 128; ++i) buf[i] = (char)i; for (i = 0, j = 125; j <= 128 /* i < 4 * 3 */; i += 3, ++j) { tiger_bp(0x00, buf, j, res); if (res[0] != out[i] || res[1] != out[i+1] || res[2] != out[i+2]) { fprintf(stderr, ">>> %s:%i: Tiger BP hash result for \"<\\x00.." "\\x%hhx is wrong! Expected %016" PRIx64 " %016" PRIx64 " %016" PRIx64 ", got %016" PRIx64 " %016" PRIx64 " %016" PRIx64 ".\n", __FILE__, __LINE__, j - 1, out[i], out[i+1], out[i+2], res[0], res[1], res[2]); ++failures; } } if (failures) return 1; return 0; } TESTS(tiger_test) TEST(test_tiger192_nessie_1a); TEST(test_tiger192_nessie_1b); TEST(test_tiger192_ross_and_eli); TEST(test_tiger192_0to255); TEST(test_tiger192_alignment); TEST(test_tiger192_abelarm_o3); ENDTESTS tthsum-1.3.1/tthsum.10000664000175000017500000001222611701311406014023 0ustar walterwalter.\" Written in VIM, obviously. .TH TTHSUM "1" "Dec 2009" "tthsum version 1.3.1" "User Commands" .SH NAME tthsum \- generates or checks TTH message digests .SH SYNOPSIS .B tthsum [-bhmpvVw] [-c [file]] | [file...] .SH DESCRIPTION .B tthsum generates or checks TTH checksums (roots of the Tiger/THEX hash tree). The Merkle Hash Tree, invented by Ralph Merkle, is a hash construct that exhibits desirable properties for verifying the integrity of files and file subranges in an incremental or out-of-order fashion. .B tthsum uses the Tiger hash algorithm, by Ross Anderson and Eli Biham, for both the internal and the leaf nodes. The specification of the THEX algorithm is at: . .I http://www.open-content.net/specs/draft-jchapweske-thex-02.html The specification of the Tiger hash algorithm is at: . .I http://www.cs.technion.ac.il/~biham/Reports/Tiger/ Normally .B tthsum generates checksums of all files given to it as parameters and prints the checksums followed by the filenames. If, however, .B -c is specified, only one filename parameter is allowed. This file should contain checksums and filenames to which these checksums refer, and the files listed in that file are checked against the checksums listed there. See option .B -c for more information. If no file is specified data will be read from standard input. .SS OPTIONS .TP .B -b An md5sum compatibility option. It does absolutely nothing. (md5sum uses -b to treat binary files differently from texts files.) .TP .B -c Check tthsum of all files listed in .I file against the checksum listed in the same file. The actual format of that file is the same as output of .BR tthsum . That is, each line in the file describes a file. A line looks like: .B \ So, for example, if a file were created and its message digest calculated like so: .B echo foo > tth-test-file; tthsum tth-test-file .B tthsum would report: .B A2MPPCGS5CPJV6AOAP37ICDCFV3WYU7PBREC6FY\ tth-test-file See .B NOTES for more information on the digest file format. .TP .B -m Use .BR mmap (2) instead of .BR read (2) to read the contents of the files to hash. Normally, using read is cheaper. This all depends on system load, I/O speed, CPU speed, L1 and/or L2 cache size and whatnot. .TP .B -p Show the progress. Print the percentage of completeness while hashing on standard error. Prints file position instead of percentage when the file size is unknown. .TP .B -v Be verbose. Print filenames when checking (with -c). .TP .B -w Warn on improperly formatted lines when checking (with -c). .TP .B -h, -V Print a small help text or the version, respectively, on standard out. If an unknown combination of options is encountered, the small help is printed on standard error and .B tthsum will return non-zero. .SH "RETURN VALUE" .B tthsum returns 0 if no error occurred or, when checking a digest, if at least one line is formatted properly and the TTHs of all properly formatted lines match. .B tthsum returns 2 if an unknown combination of options is encountered. In all other cases will .B tthsum return 1. .SH NOTES .B tthsum intentionally uses an interface identical to md5sum. .B tthsum uses BASE32 encoding consisting of the following characters: .BR ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 . It will accept lower case letters in the digest input as well. .B tthsum does not accept long options such as .BR --help . A digest file format line looks like: .BR . .B BASE32 is a 39 character long BASE32 encoded string. .B SPACES is a set of two spaces (0x20). .B FILENAME is the name of the file, encoded in UTF8 and with all control characters (those below 0x20) encoded as \\xNN or \\C C-style escapes. (The backslash is escaped as \\\\ as well. On Windows, backslashes in paths will be translated to slashes for compatibility with real operating systems.) .B EOL may be CRLF (\\r\\n), just plain LF (\\n) or even nothing at end-of-file. If you see warnings about an improper locale setup, check your LANG and/or LC_CTYPE environment variables. If these are not set properly, .B tthsum cannot represent non-ASCII characters (those above 0x7F) in UTF8. See .BR locale (1) for more information or try to set LC_CTYPE to e.g. "en_US". .SH "REPORTING BUGS" Report bugs to . .SH COPYRIGHT Copyright \(co 2009 Walter Doekes. License GPLv3+: GNU GPL version 3 or later .br This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. .SH AUTHOR .B tthsum and this manpage were written by Walter Doekes (walter+tthsum@wjd.nu). The hashing code was copied directly from DC++, an open source peer-to-peer file sharing program by Jacek Sieka (jacek@creatio.se) who had based the hashing code on the one used in BCDC++ (a modified DC++) by Dustin Brody (blackclaw@parsoma.net). After version 1.1.0, the hashing code from the Tiger hash authors is used instead, to support big endian architectures and to remove the need for C++ compilers and libraries. The md5sum manpage, written by Juho Vuori (javuori@cc.helsinki.fi), was used as a template. This manpage was proofread by Dustin Brody. .SH "SEE ALSO" .BR cksfv (1), .BR md5sum (1), .BR sha1sum (1) tthsum-1.3.1/tthsum.c0000664000175000017500000002221111656447501014117 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "tthsum.h" #include "base32.h" #include "escape.h" #include "read.h" #include "thex.h" #include "types.h" #include "utf8.h" #include #include #include #ifdef USE_TEXTS # include "texts.h" #else /* !USE_TEXTS */ # define get_error() "Fail" #endif /* !USE_TEXTS */ #define MY_PATH_MAX 32768 static void tthsum_progress(uint64_t current_pos, uint64_t end_pos); static struct rofile* tthsum_rofopen(const char* filename, const struct tthsum_options* options); static int tthsum_generate_root(const char* filename, const struct tthsum_options* opt) { struct rofile* stream; uint64_t hash[3]; char hash_base32[40]; /* unicode will be at most equal sized to the multibyte charset */ wchar_t filename_uni[MY_PATH_MAX + 1]; /* utf8/C-escaping will be at most 4 times the mbcs equivalent */ char filename_buf[MY_PATH_MAX * 4 + 1]; if (filename != NULL && strlen(filename) > MY_PATH_MAX) { #ifdef USE_TEXTS set_error("tthsum_generate_root", TTHSUM_FILENAME_TOO_LARGE); #endif /* USE_TEXTS */ return -1; } if ((stream = tthsum_rofopen(filename, opt)) == NULL || thex_tiger_root(stream, hash, opt->progress_every_mib ? tthsum_progress : NULL) == -1) { if (stream != NULL) rofclose(stream); return -1; } rofclose(stream); if (uint64tobase32(hash_base32, hash, 3) == -1) return -1; if (filename != NULL) { /* the order of calling to_utf8 or to_ctrlesc doesn't matter, as they operate on chars 0-127 and 128-255 respectively. */ #ifdef _WIN32 /* change all \\ to / on Windows */ char filename_tmp[MY_PATH_MAX + 1]; char* p; for (p = filename_tmp; *filename != '\0'; ++filename) if (*filename == '\\') *p++ = '/'; else *p++ = *filename; *p = '\0'; strtoctrlesc(filename_buf, filename_tmp); #else /* !_WIN32 */ strtoctrlesc(filename_buf, filename); #endif /* !_WIN32 */ if (mbstowcs(filename_uni, filename_buf, MY_PATH_MAX + 1) == (size_t)-1) { if (!opt->has_locale) fprintf(stderr, "tthsum: warning: Locale settings are C/POSIX. " "See the tthsum manpage for help.\n"); #ifdef USE_TEXTS set_error("mbstowcs", -1); #endif /* USE_TEXTS */ return -1; } if (wcstoutf8(filename_buf, filename_uni, MY_PATH_MAX * 4 + 1) == (size_t)-1) return -1; } else { strcpy(filename_buf, "-"); } /* print our root hash with utf8/escaped filename */ printf("%s %s\n", hash_base32, filename_buf); return 0; } int tthsum_generate_roots(const char* filenames[], int files, const struct tthsum_options* opt) { int i; for (i = 0; i < files; ++i) { if (tthsum_generate_root(filenames[i], opt) == -1) #ifdef USE_TEXTS fprintf(stderr, "tthsum: `%s': %s\n", filenames[i] ? filenames[i] : "-", get_error()); #else /* !USE_TEXTS */ fprintf(stderr, "tthsum: `%s': Fail\n", filenames[i] ? filenames[i] : "-"); #endif /* !USE_TEXTS */ } return 0; } static int tthsum_check_digest_line(char* line, unsigned line_len, const struct tthsum_options* opt) { /* 39char base32, 2 spaces, MY_PATH_MAX utf8/C-esc file, 1 terminating \0 */ wchar_t filename_uni[MY_PATH_MAX * 4 + 1]; char filename_mbs[MY_PATH_MAX * 4 + 1]; char filename[MY_PATH_MAX * 4 + 1]; struct rofile* stream; uint64_t hash_line[3] = {_ULL(0), _ULL(0), _ULL(0)}; uint64_t hash_file[3]; char* linep = line; char tmp; /* must be at least 39 base32 + 2 spaces + 1 filename long */ if (line_len < 42 || line_len > (MY_PATH_MAX * 4 + 39 + 2)) { #ifdef USE_TEXTS set_error("tthsum_check_digest_line", TTHSUM_LINE_CORRUPT); #endif /* USE_TEXTS */ return -1; } /* read base32 hash */ if (base32touint64(hash_line, linep, 3) == -1) return -1; /* check the two spaces */ linep += 39; if (*linep != ' ' || *++linep != ' ') { #ifdef USE_TEXTS set_error("tthsum_check_digest_line", TTHSUM_LINE_CORRUPT); #endif /* USE_TEXTS */ return -1; } ++linep; /* fetch filename and convert to local codepage. * unfortunately our windows utf8 routine doesn't return success unless * it has found a terminating null, sigh */ tmp = *(line + line_len); *(line + line_len) = '\0'; if (utf8towcs(filename_uni, linep, MY_PATH_MAX * 4 + 1) == (size_t)-1) { *(line + line_len) = tmp; return -1; } *(line + line_len) = tmp; /* yes, uncorrupting the crap */ filename_uni[MY_PATH_MAX * 4] = '\0'; /* make sure we're terminated */ /* proceed */ if (wcstombs(filename_mbs, filename_uni, MY_PATH_MAX * 4 + 1) == (size_t)-1) { #ifdef USE_TEXTS set_error("wcstombs", -1); #endif /* USE_TEXTS */ return -1; } filename_mbs[MY_PATH_MAX * 4] = '\0'; /* make sure we're terminated */ if (ctrlesctostr(filename, filename_mbs) == -1) return -1; /* w00t, got filename. go check TTH on it */ if ((stream = tthsum_rofopen(filename, opt)) == NULL || thex_tiger_root(stream, hash_file, opt->progress_every_mib ? tthsum_progress : NULL) == -1) { if (opt->verbose) fprintf(stderr, "%-14s FAILED (%s)\n", filename, get_error()); else fprintf(stderr, "tthsum: `%s': %s\n", filename, get_error()); if (stream != NULL) rofclose(stream); return 0; } rofclose(stream); /* compare tth's */ if (memcmp(hash_line, hash_file, 3 * 8) == 0) { if (opt->verbose) printf("%-14s OK\n", filename); return 1; } /* not equal, print an error */ if (!opt->verbose) { #ifdef USE_TEXTS fprintf(stderr, "tthsum: %s `%s'\n", get_text(TTHSUM_MISMATCHED_TTH), filename); #else /* !USE_TEXTS */ fprintf(stderr, "tthsum: TTH check failed for `%s'\n", filename); #endif /* !USE_TEXTS */ } else { printf("%-14s FAILED\n", filename); } return 0; } int tthsum_check_digest(const char* filename, const struct tthsum_options* opt) { unsigned filesize; char* file_buf = rof_readall( filename == NULL ? rofopen_sysfd_stdin() : rofopen_sysfile(filename), &filesize ); char* file_buf_end; char* s; char* e; unsigned line_no = 1; unsigned lines_correct = 0; unsigned lines_incorrect = 0; unsigned files_correct = 0; if (filename == NULL) filename = "-"; if (file_buf == NULL) { #ifdef USE_TEXTS fprintf(stderr, "tthsum: `%s': %s\n", filename, get_error()); #else /* !USE_TEXTS */ fprintf(stderr, "tthsum: `%s': Fail\n", filename); #endif /* !USE_TEXTS */ return 1; } /* Operate on a line by line basis.. we would like to get the most out * of corrupt or un-decodable files (esp. if the decoding fails for some * files only) */ file_buf_end = file_buf + filesize; s = e = file_buf; while (1) { int ret; /* find \r or \n, or really, any ctrl-character will do, as they're all escaped */ while (e != file_buf_end && (unsigned char)*e >= 0x20) ++e; /* test the line */ ret = tthsum_check_digest_line(s, e - s, opt); if (ret == 1) { ++lines_correct; ++files_correct; } else if (ret == 0) { ++lines_correct; } else { if (opt->warn) #ifdef USE_TEXTS fprintf(stderr, "tthsum: `%s': %u: %s\n", filename, line_no, get_error()); #else /* !USE_TEXTS */ fprintf(stderr, "tthsum: `%s': %u: Fail\n", filename, line_no); #endif /* !USE_TEXTS */ ++lines_incorrect; } /* find the only true line separator, the \n */ s = e; while (s != file_buf_end && *s != '\n') ++s; if (s == file_buf_end || s + 1 == file_buf_end) /* expect \n at eof */ break; /* start on the next line */ e = ++s; ++line_no; } /* free our readfile data */ free(file_buf); if (files_correct == 0 && lines_correct == 0) { fprintf(stderr, "tthsum: `%s': No files checked\n", filename); return -1; } else if (lines_correct != files_correct) { if (opt->verbose) fprintf(stderr, "tthsum: %u of %u file(s) failed TTH check\n", lines_correct - files_correct, files_correct); return -1; } return 0; } static void tthsum_progress(uint64_t current_pos, uint64_t end_pos) { if (end_pos != (uint64_t)-1) fprintf(stderr, "(%0.1f%%)\r", 100.0 * (float)current_pos / (float)end_pos); else fprintf(stderr, "(%" PRIu64 ")\r", current_pos); } static struct rofile* tthsum_rofopen(const char* filename, const struct tthsum_options* options) { if (filename == NULL) return rofopen_sysfd_stdin(); else if (!options->use_mmap) return rofopen_sysfile(filename); return rofopen_mmap(filename); } tthsum-1.3.1/tthsum.h0000664000175000017500000000274711656447501014140 0ustar walterwalter#ifndef INCLUDED_TTHSUM_H #define INCLUDED_TTHSUM_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * The tthsum application. */ #ifdef __cplusplus extern "C" { #endif /** * Option flags. */ struct tthsum_options { int has_locale; unsigned progress_every_mib; int use_mmap; int verbose; int warn; }; /** * Generate a tthsum digest. */ int tthsum_generate_roots(const char** filenames, int files, const struct tthsum_options* opt); /** * Check a tthsum digest. */ int tthsum_check_digest(const char* filenames, const struct tthsum_options* opt); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_TTHSUM_H */ tthsum-1.3.1/tthsum.html0000664000175000017500000001636411656447501014655 0ustar walterwalter Man page of TTHSUM

TTHSUM

Section: User Commands (1)
Updated: Dec 2009
Index Return to Main Contents
 

NAME

tthsum - generates or checks TTH message digests

 

SYNOPSIS

tthsum [-bhmpvVw] [-c [file]] | [file...]

 

DESCRIPTION

tthsum generates or checks TTH checksums (roots of the Tiger/THEX hash tree). The Merkle Hash Tree, invented by Ralph Merkle, is a hash construct that exhibits desirable properties for verifying the integrity of files and file subranges in an incremental or out-of-order fashion. tthsum uses the Tiger hash algorithm, by Ross Anderson and Eli Biham, for both the internal and the leaf nodes.

The specification of the THEX algorithm is at:
 .  http://www.open-content.net/specs/draft-jchapweske-thex-02.html

The specification of the Tiger hash algorithm is at:
 .  http://www.cs.technion.ac.il/~biham/Reports/Tiger/

Normally tthsum generates checksums of all files given to it as parameters and prints the checksums followed by the filenames. If, however, -c is specified, only one filename parameter is allowed. This file should contain checksums and filenames to which these checksums refer, and the files listed in that file are checked against the checksums listed there. See option -c for more information.

If no file is specified data will be read from standard input.

 

OPTIONS

-b
An md5sum compatibility option. It does absolutely nothing. (md5sum uses -b to treat binary files differently from texts files.)

-c
Check tthsum of all files listed in file against the checksum listed in the same file. The actual format of that file is the same as output of tthsum. That is, each line in the file describes a file. A line looks like:

<TTH CHECKSUM>  <FILENAME>

So, for example, if a file were created and its message digest calculated like so:

echo foo > tth-test-file; tthsum tth-test-file

tthsum would report:

A2MPPCGS5CPJV6AOAP37ICDCFV3WYU7PBREC6FY  tth-test-file

See NOTES for more information on the digest file format.

-m
Use mmap(2) instead of read(2) to read the contents of the files to hash. Normally, using read is cheaper. This all depends on system load, I/O speed, CPU speed, L1 and/or L2 cache size and whatnot.

-p
Show the progress. Print the percentage of completeness while hashing on standard error. Prints file position instead of percentage when the file size is unknown.

-v
Be verbose. Print filenames when checking (with -c).

-w
Warn on improperly formatted lines when checking (with -c).

-h, -V
Print a small help text or the version, respectively, on standard out. If an unknown combination of options is encountered, the small help is printed on standard error and tthsum will return non-zero.

 

RETURN VALUE

tthsum returns 0 if no error occurred or, when checking a digest, if at least one line is formatted properly and the TTHs of all properly formatted lines match. tthsum returns 2 if an unknown combination of options is encountered. In all other cases will tthsum return 1.

 

NOTES

tthsum intentionally uses an interface identical to md5sum.

tthsum uses BASE32 encoding consisting of the following characters: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567. It will accept lower case letters in the digest input as well.

tthsum does not accept long options such as --help.

A digest file format line looks like: <BASE32><SPACES><FILENAME><EOL>. BASE32 is a 39 character long BASE32 encoded string. SPACES is a set of two spaces (0x20). FILENAME is the name of the file, encoded in UTF8 and with all control characters (those below 0x20) encoded as \xNN or \C C-style escapes. (The backslash is escaped as \\ as well. On Windows, backslashes in paths will be translated to slashes for compatibility with real operating systems.) EOL may be CRLF (\r\n), just plain LF (\n) or even nothing at end-of-file.

If you see warnings about an improper locale setup, check your LANG and/or LC_CTYPE environment variables. If these are not set properly, tthsum cannot represent non-ASCII characters (those above 0x7F) in UTF8. See locale(1) for more information or try to set LC_CTYPE to e.g. "en_US".

 

REPORTING BUGS

Report bugs to <walter+tthsum@wjd.nu>.

 

COPYRIGHT

Copyright © 2009 Walter Doekes. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

 

AUTHOR

tthsum and this manpage were written by Walter Doekes (walter+tthsum@wjd.nu). The hashing code was copied directly from DC++, an open source peer-to-peer file sharing program by Jacek Sieka (jacek@creatio.se) who had based the hashing code on the one used in BCDC++ (a modified DC++) by Dustin Brody (blackclaw@parsoma.net). After version 1.1.0, the hashing code from the Tiger hash authors is used instead, to support big endian architectures and to remove the need for C++ compilers and libraries. The md5sum manpage, written by Juho Vuori (javuori@cc.helsinki.fi), was used as a template. This manpage was proofread by Dustin Brody.

 

SEE ALSO

cksfv(1), md5sum(1), sha1sum(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
RETURN VALUE
NOTES
REPORTING BUGS
COPYRIGHT
AUTHOR
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:24:26 GMT, May 28, 2009 tthsum-1.3.1/types.h0000664000175000017500000000433211656447501013750 0ustar walterwalter#ifndef INCLUDED_TYPES_H #define INCLUDED_TYPES_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009,2011 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * A portable way to get fixed width integer types, most notably the * 64-bit unsigned integer and its printf formatting macro. (And a * macro for portable function inlining.) */ #ifdef __cplusplus /* Request PRI* macros */ # define __STDC_FORMAT_MACROS #endif #include /* define (u)int*_t types */ #ifdef _MSC_VER typedef signed __int8 int8_t; typedef signed __int16 int16_t; typedef signed __int32 int32_t; typedef signed __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; typedef signed long ssize_t; #else /* !_MSC_VER */ # include #endif /* !_MSC_VER */ /* define initialization and formatting types */ #ifdef _MSC_VER # define _LL(x) x##LL # define _ULL(x) x##ULL # define PRIu64 "I64u" # define PRIx64 "I64x" #elif ULONG_MAX == 4294967295U # define _LL(x) x##LL # define _ULL(x) x##ULL #else /* !_MSC_VER && ULONG_MAX != 4294967295u */ # define _LL(x) x##L # define _ULL(x) x##UL #endif /* !_MSC_VER && ULONG_MAX != 4294967295u */ /* use inline if compiler supports it */ #if _MSC_VER # define _INLINE __inline #elif __STRICT_ANSI__ # define _INLINE #else # define _INLINE inline #endif #endif /* INCLUDED_TYPES_H */ tthsum-1.3.1/types_test.c0000664000175000017500000000653211656447501015006 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "types.h" #include "test.h" static int test_type8() { int8_t i = 127; uint8_t u = 127; i += 1; TEST_PASS(i == -128, "(s) 127 + 1 != -128"); u += 1; TEST_PASS(u == 128, "127 + 1 != 128"); i += 128; TEST_PASS(i == 0, "(s) -128 + 128 != 0"); u += 128; TEST_PASS(u == 0, "128 + 128 != 0"); i -= 1; TEST_PASS(i == -1, "(s) 0 - 1 != -1"); u -= 1; TEST_PASS(u == 255, "0 - 1 != 255"); return 0; } static int test_type16() { int16_t i = 32767; uint16_t u = 32767; i += 1; TEST_PASS(i == -32768, "(s) 32767 + 1 != -32768"); u += 1; TEST_PASS(u == 32768, "32767 + 1 != 32768"); i += 32768; TEST_PASS(i == 0, "(s) -32768 + 32768 != 0"); u += 32768; TEST_PASS(u == 0, "32768 + 32768 != 0"); i -= 1; TEST_PASS(i == -1, "(s) 0 - 1 != -1"); u -= 1; TEST_PASS(u == 65535, "0 - 1 != 65535"); return 0; } static int test_type32() { int32_t i = 2147483647; uint32_t u = 2147483647; /* gcc on 32 bits emits a warning about -2147483648 being "unsigned only * in ISO C90", but I don't want it to be unsigned anyway... */ i += 1; TEST_PASS(i == (-2147483647 - 1), "(s) 2147483647 + 1 != -2147483648"); u += 1; TEST_PASS(u == 2147483648U, "2147483647 + 1 != 2147483648"); i += 2147483648U; TEST_PASS(i == 0, "(s) -2147483648 + 2147483648 != 0"); u += 2147483648U; TEST_PASS(u == 0, "2147483648 + 2147483648 != 0"); i -= 1; TEST_PASS(i == -1, "(s) 0 - 1 != -1"); u -= 1; TEST_PASS(u == 4294967295U, "0 - 1 != 4294967295"); return 0; } static int test_type64() { int64_t i = _LL(9223372036854775807); uint64_t u = _ULL(9223372036854775807); /* gcc emits a warning about _LL(-9223372036854775808) being too large, * which is wrong. That value is perfectly fine. */ i += 1; TEST_PASS(i == _LL(-9223372036854775807) - _LL(1), "(s) 9223372036854775807 + 1 != -9223372036854775808"); u += 1; TEST_PASS(u == _ULL(9223372036854775808), "9223372036854775807 + 1 != 9223372036854775808"); i += _ULL(9223372036854775808); TEST_PASS(i == 0, "(s) -9223372036854775808 + 9223372036854775808 != 0"); u += _ULL(9223372036854775808); TEST_PASS(u == 0, "9223372036854775808 + 9223372036854775808 != 0"); i -= 1; TEST_PASS(i == -1, "(s) 0 - 1 != -1"); u -= 1; TEST_PASS(u == _ULL(18446744073709551615), "0 - 1 != 18446744073709551615"); return 0; } TESTS(types_test) TEST(test_type8); TEST(test_type16); TEST(test_type32); TEST(test_type64); ENDTESTS tthsum-1.3.1/utf8.c0000664000175000017500000002041311656447501013463 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "utf8.h" #include "types.h" #include #include #include /* If you define USE_WINDOWS_UTF8, you'll get unspecified/different behaviour * on WIN32 in certain cases (on invalid characters, short destination * strings...). It is only included for testing. "My" functions should perform * reasonably equal and behave like defined in exceptional cases. */ #if defined(_WIN32) && defined(USE_WINDOWS_UTF8) # define WINDOWS_LEAN_AND_MEAN # include #endif /* _WIN32 && USE_WINDOWS_UTF8 */ #ifdef USE_TEXTS # include "texts.h" #endif /* USE_TEXTS */ /* UTF-8 conversion table: * * 0x00000000 - 0x0000007F * 0xxxxxxx * 0x00000080 - 0x000007FF * 110xxxxx 10xxxxxx * 0x00000800 - 0x0000FFFF * 1110xxxx 10xxxxxx 10xxxxxx * 0x00010000 - 0x001FFFFF * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx * 0x00200000 - 0x03FFFFFF * 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx * 0x04000000 - 0x7FFFFFFF * 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx * * Note that UNICODE defines only characters 0x0 - 0x10ffff, so a utf8-encoded * character is at most 4 characters long. */ size_t wcstoautf8(char** dest, const wchar_t* src) { /* At most 4 characters in UTF-8, add the terminating 0 (null). */ int len = wcslen(src) * 4 + 1; size_t ret; *dest = (char*)malloc(len * sizeof(char)); if (!*dest) { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ return -1; } ret = wcstoutf8(*dest, src, len); if (ret == (size_t)-1) free(*dest); return ret; } size_t wcstoutf8(char* dest, const wchar_t* src, size_t n) { #if defined(_WIN32) && defined(USE_WINDOWS_UTF8) int ret; int len = wcslen(src); if (len == 0) { if (dest && n != 0) *dest = '\0'; return 0; } ++len; ret = WideCharToMultiByte( CP_UTF8, /* code page */ 0, /* performance and mapping flags */ src, /* wide-character string */ len, /* number of chars in string */ dest, /* buffer for new string */ n, /* size of buffer */ NULL, /* default for unmappable chars */ NULL /* set when default char used */ ); if (ret == 0) { #ifdef USE_TEXTS set_error("WideCharToMultiByte", -1); #endif /* USE_TEXTS */ return (size_t)-1; } return (size_t)ret; #else /* !_WIN32 || !USE_WINDOWS_UTF8 */ size_t count = 0; #ifdef _WIN32 # define _W(x) ((uint32_t)x) uint32_t ch; #else /* !_WIN32 */ # define _W(x) ((wchar_t)x) wchar_t ch; #endif /* !_WIN32 */ while ((ch = _W(*src)) != _W(L'\0') && (!dest || count < n)) { int mask, len, i; if (ch < 0x80) { len = 1; mask = 0x0; /* 0xxxxxxx */ } else if (ch < 0x800) { len = 2; mask = 0xc0; /* 110xxxxx */ } else if (ch < 0x10000) { /* Surrogate code points */ if (ch >= 0xd800 && ch < 0xe000) { #ifdef _WIN32 /* UTF-16 pairs for 16bits wchar */ wchar_t ch2 = *++src; if (ch2 < 0xdc00 || ch2 >= 0xe000 || ch >= 0xdc00) { if (dest) *dest = '\0'; #ifdef USE_TEXTS set_error("wcstoutf8", UTF8_INVALID_UNICODE); #endif /* USE_TEXTS */ return (size_t)-1; } ch = 0x10000 | ((ch & 0x3ff) << 10) | (ch2 & 0x3ff); len = 4; mask = 0xf0; #else /* !_WIN32 */ /* Invalid for 32bits wchar */ if (dest) *dest = '\0'; #ifdef USE_TEXTS set_error("wcstoutf8", UTF8_INVALID_UNICODE); #endif /* USE_TEXTS */ return (size_t)-1; #endif /* !_WIN32 */ } else { len = 3; mask = 0xe0; /* 1110xxxx */ } #ifndef _WIN32 } else if (ch < 0x200000) { len = 4; mask = 0xf0; /* 11110xxx */ #endif /* _WIN32 */ } else { if (dest) *dest = '\0'; #ifdef USE_TEXTS set_error("wcstoutf8", UTF8_INVALID_UNICODE); #endif /* USE_TEXTS */ return (size_t)-1; } if (dest) { if (count + len > n) { *dest = '\0'; return count; } for (i = len - 1; i > 0; --i) { dest[i] = (char)((ch & 0x3f) | 0x80); /* 00111111, 10000000 */ ch >>= 6; } dest[0] = (char)(ch | mask); dest += len; } ++src; count += len; } if (dest && count < n) *dest = '\0'; return count; #endif /* !_WIN32 || !USE_WINDOWS_UTF8 */ } size_t utf8toawcs(wchar_t** dest, const char* src) { /* At most 1 wide character per UTF-8 byte + terminating zero. */ int len = strlen(src) + 1; size_t ret; *dest = (wchar_t*)malloc(len * sizeof(wchar_t)); if (!*dest) { #ifdef USE_TEXTS set_error("malloc", -1); #endif /* USE_TEXTS */ return -1; } ret = utf8towcs(*dest, src, len); if (ret == (size_t)-1) free(*dest); return ret; } size_t utf8towcs(wchar_t* dest, const char* src, size_t n) { #if defined(_WIN32) && defined(USE_WINDOWS_UTF8) int ret; int len = strlen(src); if (len == 0) { if (dest && n != 0) *dest = L'\0'; return 0; } ++len; ret = MultiByteToWideChar( CP_UTF8, /* code page */ MB_ERR_INVALID_CHARS, /* character-type options */ src, /* string to map */ len, /* number of bytes in string */ dest, /* wide-character buffer */ n /* size of buffer */ ); #ifdef USE_TEXTS if (ret == 0) set_error("MultiByteToWideChar", -1); #endif /* USE_TEXTS */ return (size_t)(ret == 0 ? -1 : ret - 1); #else /* !_WIN32 || !USE_WINDOWS_UTF8 */ size_t count = 0; while (*src != '\0' && (!dest || count < n)) { int mask, len, i; /* 0xxxxxxx */ if ((unsigned char)*src < 0x80) { len = 1; mask = 0x7f; /* 01111111 */ /* 11100000, 110xxxxx */ } else if (((unsigned char)*src & 0xe0) == 0xc0) { len = 2; mask = 0x1f; /* 00011111 */ /* 11110000, 1110xxxx */ } else if (((unsigned char)*src & 0xf0) == 0xe0) { len = 3; mask = 0x0f; /* 00001111 */ /* 11111000, 11110xxx */ } else if (((unsigned char)*src & 0xf8) == 0xf0) { len = 4; mask = 0x07; /* 00000111 */ } else { if (dest) *dest = L'\0'; #ifdef USE_TEXTS set_error("utf8towcs", UTF8_INVALID_UTF8); #endif /* USE_TEXTS */ return (size_t)-1; } if (dest) { *dest = (unsigned char)*src & mask; #ifdef _WIN32 for (i = 1; i < len && i < 3; ++i) { #else /* !_WIN32 */ for (i = 1; i < len; ++i) { #endif /* !_WIN32 */ if ((src[i] & 0xc0) != 0x80) { /* 11000000, 10000000 */ *dest = L'\0'; #ifdef USE_TEXTS set_error("utf8towcs", UTF8_INVALID_UTF8); #endif /* USE_TEXTS */ return (size_t)-1; } *dest <<= 6; *dest |= (unsigned char)src[i] & 0x3f; /* 00111111 */ } #ifdef _WIN32 if (len == 4) { wchar_t dest2; if (count + 1 >= n || (src[3] & 0xc0) != 0x80) { *dest = L'\0'; #ifdef USE_TEXTS set_error("utf8towcs", UTF8_INVALID_UTF8); #endif /* USE_TEXTS */ return (size_t)-1; } if (!(*dest & 0x400)) { *dest = L'\0'; #ifdef USE_TEXTS set_error("utf8towcs", UTF8_OVERLONG_UTF8); #endif /* USE_TEXTS */ return (size_t)-1; } dest2 = (*dest & 0xf) << 6 | ((unsigned char)src[3] & 0x3f); *dest = 0xd800 | (*dest & 0x7800) >> 5 | (*dest & 0x3f0) >> 4; *++dest = 0xdc00 | dest2; ++count; } #endif /* _WIN32 */ /* Check against overlong encoding */ if ((len == 2 && *dest <= 0x7f) || (len == 3 && *dest <= 0x7ff) #ifndef _WIN32 || (len == 4 && *dest <= 0xffff) #endif /* !_WIN32 */ ) { *dest = L'\0'; #ifdef USE_TEXTS set_error("utf8towcs", UTF8_OVERLONG_UTF8); #endif /* USE_TEXTS */ return (size_t)-1; } ++dest; } src += len; ++count; } if (dest && count < n) *dest = L'\0'; return count; #endif /* !_WIN32 || !USE_WINDOWS_UTF8 */ } tthsum-1.3.1/utf8.h0000664000175000017500000000705211656447501013474 0ustar walterwalter#ifndef INCLUDED_UTF8_H #define INCLUDED_UTF8_H /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ /** * Conversion routines to and from UTF8 and UCS (UNICODE). * * The ANSI-C mbstowcs and wcstombs functions aren't sufficient to do * UTF8 and USC conversion on machines that do not have the proper * locales set up. * The two functions contained herein (this and utf8.c) provide * functions similar in behaviour to mbstowcs and wcstombs, but * function without a proper locale set up. * * See also: mbstowcs(3), wcstombs(3), unicode(7), utf8(7). * * Last modified: 2009-05-02 */ #include #ifdef __cplusplus extern "C" { #endif /** * Convert an UTF8 multi-byte string to an UCS wide-character string. * The conversion stops at the first 0 (null) character encountered. * * - If dest is NULL, utf8towcs returns the size required for the full * string (without the terminating 0 (null) character), n is ignored. * - If dest is not NULL, utf8towcs tries to write at most n characters * to dest. the characters written (without the terminating 0 (null)) * is returned. * - If src is NULL, behaviour is undefined. * - If src contains an invalid UTF8 sequence, utf8towcs returns * (size_t)-1. If there is room, a terminating 0 (null) character * will be placed after the last successfully converted character in * dest. */ size_t utf8towcs(wchar_t* dest, const char* src, size_t n); /** * Allocate a wide character string and perform utf8towcs on it. * Free the allocated memory with free(). */ size_t utf8toawcs(wchar_t** dest, const char* src); /** * Convert an UCS wide-character string to an UTF8 multi-byte string. * The conversion stops at the first 0 (null) character encountered. * * - If dest is NULL, wcstoutf8 returns the size required for the full * string (without the terminating 0 (null) character), n is ignored. * - If dest is not NULL, wcstoutf8 tries to write at most n characters * to dest. the characters written (without the terminating 0 (null)) * is returned. * - If src is NULL, behaviour is undefined. * - If src contains an invalid UCS sequence, utf8towcs returns * (size_t)-1. If there is room, a terminating 0 (null) character * will be placed after the last successfully converted character in * dest. * The Unicode standard specifies no characters above 0x10ffff, so an * UTF8 encoding will at most contain 4 instead of 6 characters per * wide character. */ size_t wcstoutf8(char* dest, const wchar_t* src, size_t n); /** * Allocate a wide character string and perform wcstoutf8 on it. * Free the allocated memory with free(). */ size_t wcstoautf8(char** dest, const wchar_t* src); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* INCLUDED_UTF8_H */ tthsum-1.3.1/utf8_test.c0000664000175000017500000002002511656447501014521 0ustar walterwalter/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum 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 General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "utf8.h" #include "test.h" #include #include #include static int symcmpbin(const char* name, const char* utf8, const wchar_t* unicode) { char utf8buf[2048]; char* utf8alloc; wchar_t unicodebuf[2048]; wchar_t* unicodealloc; unsigned utf8len = strlen(utf8); unsigned unicodelen = wcslen(unicode); unsigned ret; unsigned allocsuccess; memset(utf8buf, 85, 2048); memset(unicodebuf, 85, 2048); if (utf8len >= 2048 || unicodelen >= 512) FAIL3("Test values too large: \"%s\" is %u and %u bytes", name, utf8len, unicodelen); if ((ret = (unsigned)utf8towcs(unicodebuf, utf8, 2048)) != unicodelen) FAIL3("utf8towcs returned wrong length for \"%s\": %u instead of %u", name, ret, unicodelen); if ((ret = (unsigned)wcstoutf8(utf8buf, unicode, 2048)) != utf8len) FAIL3("wcstoutf8 returned wrong length for \"%s\": %u instead of %u", name, ret, utf8len); if ((ret = (unsigned)utf8toawcs(&unicodealloc, utf8)) != unicodelen) FAIL3("utf8toawcs returned wrong length for \"%s\": %u instead of %u", name, ret, unicodelen); if ((ret = (unsigned)wcstoautf8(&utf8alloc, unicode)) != utf8len) { free(unicodealloc); FAIL3("wcstoautf8 returned wrong length for \"%s\": %u instead of %u", name, ret, utf8len); } allocsuccess = memcmp(utf8, utf8alloc, utf8len + 1) == 0 && memcmp(unicode, unicodealloc, (unicodelen + 1) * sizeof(wchar_t)) == 0; free(utf8alloc); free(unicodealloc); TEST_PASS3(memcmp(utf8, utf8buf, utf8len + 1) == 0, "utf8 strings mismatch on \"%s\", first chars 0x%02hx 0x%02hx", name, (short)utf8buf[0], (short)utf8buf[1]); /* %hhx is not C90 */ TEST_PASS2(memcmp(unicode, unicodebuf, (unicodelen + 1) * sizeof(wchar_t)) == 0, "unicode strings mismatch on \"%s\", first char 0x%x", name, (unsigned)unicodebuf[0]); TEST_PASS(allocsuccess, "utf8 and/or unicode strings allocated by the " "*toa* variants failed"); return 0; } static int symcmp(const char* utf8, const wchar_t* unicode) { return symcmpbin(utf8, utf8, unicode); } static int shortutf8towcs(const char* utf8) { size_t ret; wchar_t buf[5]; wchar_t* abuf; ret = utf8towcs(buf, utf8, 5); if (ret == (size_t)-1) FAIL1("utf8towcs returned -1 on \"%s\" with a 6 char buffer", utf8); if (ret != 5) FAIL2("utf8towcs returned %u on \"%s\" with a 6 char buffer", (unsigned)ret, utf8); if (utf8toawcs(&abuf, utf8) == (size_t)-1) FAIL1("failed to get an auto-alloc'd comparison sample for \"%s\"", utf8); if (memcmp(abuf, buf, 5) != 0) { free(abuf); FAIL1("short utf8towcs didn't compare with full sample for \"%s\"", utf8); } free(abuf); return 0; } static int test_wchar_size() { #ifdef _WIN32 TEST_PASS1(sizeof(wchar_t) == 2, "expected wchar_t to be 2 bytes on windows, got %u instead", (unsigned)sizeof(wchar_t)); #else /* !_WIN32 */ TEST_PASS1(sizeof(wchar_t) == 4, "expected wchar_t to be 4 bytes on this OS, got %u instead", (unsigned)sizeof(wchar_t)); #endif /* !_WIN32 */ return 0; } static int test_bidirectional_ascii() { return symcmp("", L"") + symcmp("0123ABCDabcd", L"0123ABCDabcd") + symcmpbin("(low ascii)", "\x01\x02\x03\x7d\x7e\x7f", L"\x01\x02\x03\x7d\x7e\x7f"); } static int test_bidirectional_asian() { wchar_t hiragana[] = {0x306a,0x308b,0x3068,0x0}; return symcmpbin("Hiragana na-ru-to", "\xe3\x81\xaa\xe3\x82\x8b\xe3\x81\xa8", hiragana); } static int test_bidirectional_european() { wchar_t dutch[] = {0xe4,0xeb,0xef,0xf6,0xfc,0xff,0xc4,0xcb,0xcf,0xd6,0xdc, 0x178,0x0}; wchar_t french[] = {0xe1,0xe2,0xe0,0xc1,0xc2,0xc0,0x0}; wchar_t swedish[] = {0xe5,0xe4,0xf6,0xc5,0xc4,0xd6,0x0}; return symcmpbin("Dutch aeiouy with trema", "\xc3\xa4\xc3\xab\xc3\xaf\xc3\xb6\xc3\xbc\xc3\xbf" "\xc3\x84\xc3\x8b\xc3\x8f\xc3\x96\xc3\x9c\xc5\xb8", dutch) + symcmpbin("French several a's", "\xc3\xa1\xc3\xa2\xc3\xa0\xc3\x81\xc3\x82\xc3\x80", french) + symcmpbin("Swedish ao/ae/oe", "\xc3\xa5\xc3\xa4\xc3\xb6\xc3\x85\xc3\x84\xc3\x96", swedish); } static int test_invalid_character_handling() { wchar_t unicode[2048]; char utf8[2048]; wchar_t illegal_surrogates1[] = {0x1,0xdc00,0xd800,0x1,0x0}; wchar_t illegal_surrogates2[] = {0x1,0xd800,0xd800,0x1,0x0}; wchar_t illegal_surrogates3[] = {0x1,0xd800,0x1,0xdc00,0x0}; #ifndef _WIN32 wchar_t high_unicode[] = {0x1,0xffff,0x200000,0xffff,0x1,0x0}; #endif /* _WIN32 */ TEST_PASS(utf8towcs(unicode, "abc" "\xe4" "def", 2048) == (size_t)-1, "utf8towcs should fail on latin1 swedish ae (0xE4)"); TEST_PASS(utf8towcs(unicode, "\xc1\xff", 2048) == (size_t)-1, "utf8towcs should fail on \"\\xc1\\xff\""); TEST_PASS(utf8towcs(unicode, "\xc2" "abc", 2048) == (size_t)-1, "utf8towcs should fail on \"\\xc2abc\""); TEST_PASS(utf8towcs(unicode, "abc" "\x80" "def", 2048) == (size_t)-1, "utf8towcs should fail on bare \\x80"); TEST_PASS(utf8towcs(unicode, "abc" "\xbf" "def", 2048) == (size_t)-1, "utf8towcs should fail on bare \\x80"); TEST_PASS(wcstoutf8(utf8, illegal_surrogates1, 2048) == (size_t)-1, "wcstoutf8 should fail on surrogate characters"); TEST_PASS(wcstoutf8(utf8, illegal_surrogates2, 2048) == (size_t)-1, "wcstoutf8 should fail on surrogate characters"); TEST_PASS(wcstoutf8(utf8, illegal_surrogates3, 2048) == (size_t)-1, "wcstoutf8 should fail on surrogate characters"); #ifndef _WIN32 /* Windows has 16bits wchars, so nothing above 0xffff can be found */ TEST_PASS(wcstoutf8(utf8, high_unicode, 2048) == (size_t)-1, "wcstoutf8 should fail on characters above 0x200000"); /*5+ bytes*/ #endif /* _WIN32 */ return 0; } static int test_overlong_encoding() { wchar_t buf[2]; return utf8towcs(buf, "\xc0\x80", 2) != (size_t)-1 /* 0x0 */ || utf8towcs(buf, "\xc0\xaf", 2) != (size_t)-1 /* 0x2f */ || utf8towcs(buf, "\xc1\xbf", 2) != (size_t)-1 /* 0x7f */ || utf8towcs(buf, "\xe0\x80\x80", 2) != (size_t)-1 /* 0x0 */ || utf8towcs(buf, "\xe0\x80\xaf", 2) != (size_t)-1 /* 0x2f */ || utf8towcs(buf, "\xe0\x81\xbf", 2) != (size_t)-1 /* 0x7f */ || utf8towcs(buf, "\xf0\x80\x80\x80", 2) != (size_t)-1 /* 0x0 */ || utf8towcs(buf, "\xf0\x80\x80\xaf", 2) != (size_t)-1 /* 0x2f */ || utf8towcs(buf, "\xf0\x80\x81\xbf", 2) != (size_t)-1; /* 0x7f */ } static int test_short_destination() { return shortutf8towcs("abcdef") + shortutf8towcs("\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4\xc3\xa5\xc3\xa6") + shortutf8towcs("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); } static int test_wide_wchars() { /* larger than 16 bits */ #ifdef _WIN32 wchar_t osmanya[] = {0xd801,0xdc80,0xd801,0xdc81,0xd801,0xdc82,0xd801, 0xdc83,0x0}; #else /* !_WIN32 */ wchar_t osmanya[] = {0x10480,0x10481,0x10482,0x10483,0x0}; #endif /* !_WIN32 */ return symcmpbin("Osmanya alef ba ta ja", "\xf0\x90\x92\x80\xf0\x90\x92\x81\xf0\x90\x92\x82\xf0\x90\x92\x83", osmanya); } TESTS(utf8_test) TEST(test_wchar_size); TEST(test_bidirectional_ascii); TEST(test_bidirectional_asian); TEST(test_bidirectional_european); TEST(test_invalid_character_handling); TEST(test_overlong_encoding); TEST(test_short_destination); TEST(test_wide_wchars); ENDTESTS