diff --git a/app/utils_drive.py b/app/utils_drive.py index 510a030..edee52a 100644 --- a/app/utils_drive.py +++ b/app/utils_drive.py @@ -1,9 +1,8 @@ import threading import os -import pygost.gost3412 as gost -# from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -# from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.backends import default_backend erasing_methods = { "2 прохода": { @@ -32,17 +31,12 @@ erasing_methods = { def get_random_bytes(size): seed=os.urandom(32) - # backend = default_backend() - # cipher = Cipher(algorithms.AES(seed), modes.CTR(b'\0'*16), backend=backend) - # encryptor = cipher.encryptor() - + backend = default_backend() + cipher = Cipher(algorithms.AES(seed), modes.CTR(b'\0'*16), backend=backend) + encryptor = cipher.encryptor() nulls=b'\0'*(size) - enc = gost.GOST3412Kuznechik(seed) - rounds = int(size / 32) - data = b'' - for i in range(512): - data += enc.encrypt(nulls) - return data + + return encryptor.update(nulls) class Drive(): diff --git a/pygost-5.13/AUTHORS b/pygost-5.13/AUTHORS deleted file mode 100644 index f047789..0000000 --- a/pygost-5.13/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -* Sergey Matveev diff --git a/pygost-5.13/COPYING b/pygost-5.13/COPYING deleted file mode 100644 index 9a2708d..0000000 --- a/pygost-5.13/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - 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 -. diff --git a/pygost-5.13/FAQ b/pygost-5.13/FAQ deleted file mode 100644 index 63e62d0..0000000 --- a/pygost-5.13/FAQ +++ /dev/null @@ -1,24 +0,0 @@ -Frequently asked questions -************************** - -My signature is not validated by other implementations. What is wrong? - - Try to reverse it ('sign[::-1]'). Try to swap its halves - ('sign[len(sign)/2:] + sign[:len(sign)/2]'). Try to reverse its - swapped halves too. - - It is GOST: do you expect serialization unification?! - -My signature is *still* not validated by other implementations! - - Try to reverse digest you are signing/verifying ('dgst[::-1]'). - - It is GOST: do you expect serialization unification?! - -Everything above did not help me. Does PyGOST sucks? - - No way! You still have not tried to reverse your binary private - key, public key and swap its halves. - - It is GOST: do you expect serialization unification?! - diff --git a/pygost-5.13/INSTALL b/pygost-5.13/INSTALL deleted file mode 100644 index e94b639..0000000 --- a/pygost-5.13/INSTALL +++ /dev/null @@ -1,43 +0,0 @@ -Download -******** - -No additional dependencies except Python 2.7/3.x interpreter are -required. - - Preferable way is to download tarball with the signature: - - $ [fetch|wget] http://www.pygost.cypherpunks.ru/pygost-5.13.tar.zst - $ [fetch|wget] http://www.pygost.cypherpunks.ru/pygost-5.13.tar.zst.{asc,sig} - [verify signature] - $ zstd -d < pygost-5.13.tar.zst | tar xf - - $ cd pygost-5.13 - $ python setup.py install - - You can obtain releases source code prepared tarballs on -. You *have to* verify downloaded -tarballs authenticity to be sure that you retrieved trusted and -untampered software. There are two options: - -OpenPGP (https://www.openpgp.org/) '.asc' signature - Use GNU Privacy Guard (https://www.gnupg.org/) free software - implementation. For the very first time it is necessary to get - signing public key and import it. It is provided here - (PUBKEY-PGP.asc), but you should check alternate resources. - - pub rsa2048/0xE6FD1269CD0C009E 2016-09-13 - F55A 7619 3A0C 323A A031 0E6B E6FD 1269 CD0C 009E - uid PyGOST releases - - $ gpg --auto-key-locate dane --locate-keys pygost at cypherpunks dot ru - $ gpg --auto-key-locate wkd --locate-keys pygost at cypherpunks dot ru - -OpenSSH (https://www.openssh.com/) '.sig' signature - Public key (PUBKEY-SSH.pub) and its OpenPGP signature - (PUBKEY-SSH.pub.asc) made with the key above. Its fingerprint: - 'SHA256:/Z3T/T2sXaaunefAL6tz3ZykHTDYIMh5TLd9Hh9mxlU'. - - $ ssh-keygen -Y verify -f PUBKEY-SSH.pub -I pygost@cypherpunks.ru -n file \ - -s pygost-5.13.tar.zst.sig < pygost-5.13.tar.zst - - You can obtain development source code with 'git clone -git://git.cypherpunks.ru/pygost.git'. diff --git a/pygost-5.13/MANIFEST.in b/pygost-5.13/MANIFEST.in deleted file mode 100644 index f7ccb5c..0000000 --- a/pygost-5.13/MANIFEST.in +++ /dev/null @@ -1,8 +0,0 @@ -include AUTHORS -include COPYING -include FAQ -include INSTALL -include NEWS -include README -include THANKS -include VERSION diff --git a/pygost-5.13/NEWS b/pygost-5.13/NEWS deleted file mode 100644 index 781db0d..0000000 --- a/pygost-5.13/NEWS +++ /dev/null @@ -1,271 +0,0 @@ -News -**** - -*5.13* - Ability to use masked 34.10 private keys. - -*5.12* - Fixed incorrect digest calculation when using - 'GOST34112012*.update()' method. - -*5.11* - 'gost34112012''s 'update()'/'digest()' methods are streaming now - - they do not store the whole data in memory. - -*5.10* - Added ISO 10126 'pygost.gost3413.(un)pad_iso10126' padding support. - -*5.9* - Fixed 'wrap.wrap_cryptopro', that ignored Sbox for key - diversification. - -*5.8* - Added human-readable name of the curve in 'GOST3410Curve.name'. - -*5.7* - Fixed MGM ignoring of the set tag size. - -*5.6* - Fixed lint errors for previous release. - -*5.5* - More 34.10 curve parameters aliases: - id-tc26-gost-3410-2012-256-paramSetA -> id-tc26-gost-3410-12-256-paramSetA - id-tc26-gost-3410-2012-256-paramSetB -> id-tc26-gost-3410-12-256-paramSetB - id-tc26-gost-3410-2012-256-paramSetC -> id-tc26-gost-3410-12-256-paramSetC - id-tc26-gost-3410-2012-256-paramSetD -> id-tc26-gost-3410-12-256-paramSetD - id-tc26-gost-3410-2012-512-paramSetTest -> id-tc26-gost-3410-12-512-paramSetTest - id-tc26-gost-3410-2012-512-paramSetA -> id-tc26-gost-3410-12-512-paramSetA - id-tc26-gost-3410-2012-512-paramSetB -> id-tc26-gost-3410-12-512-paramSetB - id-tc26-gost-3410-2012-512-paramSetC -> id-tc26-gost-3410-12-512-paramSetC - -*5.4* - 'gost3410.prv_marshal' helper can make private keys that are in - curve's Q field, for better compatibility with some - implementations. - -*5.3* - * More than 4 times speed increase of 'gost34112012'. - * 'asn1schemas/cert-selfsigned-example.py' optionally can issue - CA signed child certificate. - -*5.2* - * 'GOST3410Curve' has '.contains(point)' method for checking if - point is on the curve. - * 'gost3410_vko' functions check if remote peer's public key is - on the curve. - * Small typing stubs fixes. - -*5.1* - Small typing stubs fixes. - -*5.0* - * Backward incompatible removing of misleading and excess 'mode' - keyword argument from all 'gost3410*' related functions. - Point/key sizes are determined by looking at curve's - parameters size. - * 'asn1schemas/cert-selfsigned-example.py' optionally can create - CA certificate. - -*4.9* - * *Fixed* nasty bug with Edwards curves using in 34.10-VKO - functions: curve's cofactor has not been used - * CTR-ACPKM mode of operation - * OMAC-ACPKM-Master moder of operation - * KExp15/KImp15 key export/import functions - * KDF_GOSTR3411_2012_256, KDF_TREE_GOSTR3411_2012_256 - * KEG export key generation function - -*4.8* - MGM AEAD mode for 64 and 128 bit ciphers. - -*4.7* - Removed 'gost28147.addmod' for simplicity. - -*4.6* - Fix invalid 'gost28147.addmod''s behaviour with much bigger values - than the modulo. - -*4.5* - Fixed digest endianness and more RFC4491bis conformance in - 'asn1schemas/cert-selfsigned-example.py' certificate's. - -*4.4* - * 'id-tc26-gost-3410-2012-512-paramSetTest' curve - * Simple FAQ - * More test vectors for 34.10-2012 - * More X.509, PKCS #10 and corresponding ASN.1 helper structures - -*4.3* - Dummy release with fixed 'pygost.__version__'. - -*4.2* - * 'pygost.gost3410.sign' accepts predefined random data used for - k/r generation - * More test vectors for 34.10-2012 - -*4.1* - * PEP-396 compatible module's '__version__' - * Curve parameters aliases: - id-GostR3410-2001-CryptoPro-XchA-ParamSet -> id-GostR3410-2001-CryptoPro-A-ParamSet - id-GostR3410-2001-CryptoPro-XchB-ParamSet -> id-GostR3410-2001-CryptoPro-C-ParamSet - id-tc26-gost-3410-2012-256-paramSetB -> id-GostR3410-2001-CryptoPro-A-ParamSet - id-tc26-gost-3410-2012-256-paramSetC -> id-GostR3410-2001-CryptoPro-B-ParamSet - id-tc26-gost-3410-2012-256-paramSetD -> id-GostR3410-2001-CryptoPro-C-ParamSet - * Forbid any later GNU GPL version autousage (project's licence - now is GNU GPLv3 only) - -*4.0* - * 34.10-2012 TC26 twisted Edwards curve related parameters - * Coordinates conversion from twisted Edwards to Weierstrass - form and vice versa - * More test vectors - * Backward incompatible Sbox and curves parameters renaming, to - comply with OIDs identifying them: - Gost2814789_TestParamSet -> id-Gost28147-89-TestParamSet - Gost28147_CryptoProParamSetA -> id-Gost28147-89-CryptoPro-A-ParamSet - Gost28147_CryptoProParamSetB -> id-Gost28147-89-CryptoPro-B-ParamSet - Gost28147_CryptoProParamSetC -> id-Gost28147-89-CryptoPro-C-ParamSet - Gost28147_CryptoProParamSetD -> id-Gost28147-89-CryptoPro-D-ParamSet - Gost28147_tc26_ParamZ -> id-tc26-gost-28147-param-Z - GostR3411_94_TestParamSet -> id-GostR3411-94-TestParamSet - GostR3411_94_CryptoProParamSet -> id-GostR3411-94-CryptoProParamSet - - GostR3410_2001_TestParamSet -> id-GostR3410-2001-TestParamSet - GostR3410_2001_CryptoPro_A_ParamSet -> id-GostR3410-2001-CryptoPro-A-ParamSet - GostR3410_2001_CryptoPro_B_ParamSet -> id-GostR3410-2001-CryptoPro-B-ParamSet - GostR3410_2001_CryptoPro_C_ParamSet -> id-GostR3410-2001-CryptoPro-C-ParamSet - GostR3410_2001_CryptoPro_XchA_ParamSet -> id-GostR3410-2001-CryptoPro-XchA-ParamSet - GostR3410_2001_CryptoPro_XchB_ParamSet -> id-GostR3410-2001-CryptoPro-XchB-ParamSet - GostR3410_2012_TC26_256_ParamSetA -> id-tc26-gost-3410-2012-256-paramSetA - GostR3410_2012_TC26_ParamSetA -> id-tc26-gost-3410-12-512-paramSetA - GostR3410_2012_TC26_ParamSetB -> id-tc26-gost-3410-12-512-paramSetB - GostR3410_2012_TC26_ParamSetC -> id-tc26-gost-3410-2012-512-paramSetC - * Backward incompatible 'GOST3410Curve' initialization: all - parameters are passed not as big-endian encoded binaries, but - as integers - * Backward incompatible change: 'gost3410.CURVE_PARAMS' is - disappeared. 'gost3410.CURVES' dictionary holds already - initialized 'GOST3410Curve'. Just use - 'CURVES["id-tc26-gost-3410-12-512-paramSetA"]' instead of - 'GOST3410Curve(*CURVE_PARAMS["id-tc26-gost-3410-12-512-paramSetA"])' - -*3.15* - * Licence changed back to GNU GPLv3+. GNU LGPLv3+ licenced - versions are not available anymore - * More ASN.1-based test vectors (PyDERASN - (http://www.pyderasn.cypherpunks.ru/) dependency required) - -*3.14* - Add missing typing stubs related to previous release. - -*3.13* - * Ability to explicitly specify used 28147-89 Sbox in - 'pygost.wrap.*' functions - * Ability to use key meshing in 28147-89 CBC mode - -*3.12* - * Added mode argument to 'pygost.gost3410_vko.kek_34102012256', - because 256-bit private keys can be used with that algorithm - too. - * Fix incorrect degree sanitizing in - 'pygost.gost3410.GOST3410Curve.exp' preventing using of - 'UKM=1' in 'pygost.gost3410_vko.kek_*' functions. - -*3.11* - Fixed PEP247 typing stub with invalid hexdigest method. - -*3.10* - Additional missing 34.11-* typing stubs. - -*3.9* - Add missing 34.11-2012 PBKDF2 typing stub. - -*3.8* - * 34.11-2012 based PBKDF2 function added - * 34.13-2015 does not require double blocksized IVs - -*3.7* - Fixed 34.13-2015 OFB bug with IVs longer than 2 blocks. - -*3.6* - Fixed source files installation during 'setup.py install' - invocation. - -*3.5* - Dummy release: added long description in package metadata. - -*3.4* - * Small mypy stubs related fixes - * Licence changed from GNU GPLv3+ to GNU LGPLv3+ - -*3.3* - * 'GOST3412Kuz' renamed to 'GOST3412Kuznechik' - * 'GOST3412Magma' implements GOST R 34.12-2015 Magma 64-bit - block cipher - -*3.2* - 34.13-2015 block cipher modes of operation implementations. - -*3.1* - Fixed mypy stubs related to PEP247-successors. - -*3.0* - * 'gost3411_94' renamed to 'gost341194' - * 'gost3411_2012' renamed and split to 'gost34112012256', - 'gost34112012512' - * 'GOST34112012' split to 'GOST34112012256', 'GOST34112012512' - * 'gost3410.kek' moved to separate 'gost3410_vko.kek_34102001' - * VKO GOST R 34.10-2012 appeared in 'gost3410_vko', with test - vectors - * 34.11-94 digest is reversed, to be compatible with HMAC and - PBKDF2 test vectors describe in TC26 documents - * 34.11-94 PBKDF2 test vectors added - * 'gost3410.prv_unmarshal', 'gost3410.pub_marshal', - 'gost3410.pub_unmarshal' helpers added, removing the need of - 'x509' module at all - * 'gost3410.verify' requires '(pubX, pubY)' tuple, instead of - two separate 'pubX', 'pubY' arguments - * 34.11-94 based PBKDF2 function added - -*2.4* - Fixed 34.13 mypy stub. - -*2.3* - Typo and pylint fixes. - -*2.2* - GOST R 34.13-2015 padding methods. - -*2.1* - Documentation and supplementary files refactoring. - -*2.0* - PEP-0247 compatible hashers and MAC. - -*1.0* - * Ability to specify curve in pygost.x509 module - * Ability to use 34.10-2012 in pygost.x509 functions - * Renamed classes and modules: - pygost.gost3410.SIZE_34100 -> pygost.gost3410.SIZE_3410_2001 - pygost.gost3410.SIZE_34112 -> pygost.gost3410.SIZE_3410_2012 - pygost.gost3411_12.GOST341112 -> pygost.gost3411_2012.GOST34112012 - -*0.16* - 34.10-2012 TC26 curve parameters. - -*0.15* - PEP-0484 static typing hints. - -*0.14* - 34.10-2012 workability fix. - -*0.13* - Python3 compatibility. - -*0.11* - GOST R 34.12-2015 Кузнечик (Kuznechik) implementation. - -*0.10* - CryptoPro and GOST key wrapping, CryptoPro key meshing. - diff --git a/pygost-5.13/PKG-INFO b/pygost-5.13/PKG-INFO deleted file mode 100644 index 601c6f7..0000000 --- a/pygost-5.13/PKG-INFO +++ /dev/null @@ -1,96 +0,0 @@ -Metadata-Version: 2.1 -Name: pygost -Version: 5.13 -Summary: Pure Python GOST cryptographic functions library -Home-page: http://www.pygost.cypherpunks.ru/ -Author: Sergey Matveev -Author-email: stargrave@stargrave.org -License: GPLv3 -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3) -Classifier: Natural Language :: English -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 3 -Classifier: Topic :: Security :: Cryptography -Classifier: Topic :: Software Development :: Libraries :: Python Modules -License-File: COPYING -License-File: AUTHORS - -Pure Python 2.7/3.x GOST cryptographic functions library. - -GOST is GOvernment STandard of Russian Federation (and Soviet Union). - -* GOST 28147-89 (RFC 5830) block cipher with ECB, CNT (CTR), CFB, MAC, - CBC (RFC 4357) modes of operation -* various 28147-89-related S-boxes included -* GOST R 34.11-94 hash function (RFC 5831) -* GOST R 34.11-94 based PBKDF2 function -* GOST R 34.11-2012 Стрибог (Streebog) hash function (RFC 6986) -* GOST R 34.11-2012 based PBKDF2 function (Р 50.1.111-2016) -* GOST R 34.10-2001 (RFC 5832) public key signature function -* GOST R 34.10-2012 (RFC 7091) public key signature function -* various 34.10 curve parameters included -* Coordinates conversion from twisted Edwards to Weierstrass form and - vice versa -* VKO GOST R 34.10-2001 key agreement function (RFC 4357) -* VKO GOST R 34.10-2012 key agreement function (RFC 7836) -* 28147-89 and CryptoPro key wrapping (RFC 4357) -* 28147-89 CryptoPro key meshing for CFB and CBC modes (RFC 4357) -* RFC 4491 (using GOST algorithms with X.509) compatibility helpers -* GOST R 34.12-2015 128-bit block cipher Кузнечик (Kuznechik) (RFC 7801) -* GOST R 34.12-2015 64-bit block cipher Магма (Magma) -* GOST R 34.13-2015 padding methods and block cipher modes of operation - (ECB, CTR, OFB, CBC, CFB, MAC), ISO 10126 padding -* MGM AEAD mode for 64 and 128 bit ciphers (RFC 9058) -* CTR-ACPKM, OMAC-ACPKM-Master modes of operation (Р 1323565.1.017-2018) -* KExp15/KImp15 key export/import functions (Р 1323565.1.017-2018) -* KDF_GOSTR3411_2012_256, KDF_TREE_GOSTR3411_2012_256 (Р 50.1.113-2016) -* KEG export key generation function (Р 1323565.1.020-2018) -* PEP247-compatible hash/MAC functions - -Known problems: low performance and non time-constant calculations. - -Example 34.10-2012 keypair generation, signing and verifying: - - >>> from pygost.gost3410 import CURVES - >>> curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - >>> from os import urandom - >>> prv_raw = urandom(64) - >>> from pygost.gost3410 import prv_unmarshal - >>> from pygost.gost3410 import prv_marshal - >>> prv = prv_unmarshal(prv_raw) - >>> prv_raw = prv_marshal(curve, prv) - >>> from pygost.gost3410 import public_key - >>> pub = public_key(curve, prv) - >>> from pygost.gost3410 import pub_marshal - >>> from pygost.utils import hexenc - >>> print "Public key is:", hexenc(pub_marshal(pub)) - >>> from pygost import gost34112012512 - >>> data_for_signing = b"some data" - >>> dgst = gost34112012512.new(data_for_signing).digest() - >>> from pygost.gost3410 import sign - >>> signature = sign(curve, prv, dgst) - >>> from pygost.gost3410 import verify - >>> verify(curve, pub, dgst, signature) - True - -Other examples can be found in docstrings and unittests. -Example self-signed X.509 certificate creation can be found in -pygost/asn1schemas/cert-selfsigned-example.py. - -PyGOST is free software: see the file COPYING for copying conditions. - -PyGOST'es home page is: http://www.pygost.cypherpunks.ru/ -You can read about GOST algorithms more: http://www.gost.cypherpunks.ru/ - -Please send questions, bug reports and patches to -http://lists.cypherpunks.ru/gost.html mailing list. -Announcements also go to this mailing list. - -Development Git source code repository currently is located here: -http://www.git.cypherpunks.ru/?p=pygost.git;a=summary - - diff --git a/pygost-5.13/README b/pygost-5.13/README deleted file mode 100644 index 2034715..0000000 --- a/pygost-5.13/README +++ /dev/null @@ -1,73 +0,0 @@ -Pure Python 2.7/3.x GOST cryptographic functions library. - -GOST is GOvernment STandard of Russian Federation (and Soviet Union). - -* GOST 28147-89 (RFC 5830) block cipher with ECB, CNT (CTR), CFB, MAC, - CBC (RFC 4357) modes of operation -* various 28147-89-related S-boxes included -* GOST R 34.11-94 hash function (RFC 5831) -* GOST R 34.11-94 based PBKDF2 function -* GOST R 34.11-2012 Стрибог (Streebog) hash function (RFC 6986) -* GOST R 34.11-2012 based PBKDF2 function (Р 50.1.111-2016) -* GOST R 34.10-2001 (RFC 5832) public key signature function -* GOST R 34.10-2012 (RFC 7091) public key signature function -* various 34.10 curve parameters included -* Coordinates conversion from twisted Edwards to Weierstrass form and - vice versa -* VKO GOST R 34.10-2001 key agreement function (RFC 4357) -* VKO GOST R 34.10-2012 key agreement function (RFC 7836) -* 28147-89 and CryptoPro key wrapping (RFC 4357) -* 28147-89 CryptoPro key meshing for CFB and CBC modes (RFC 4357) -* RFC 4491 (using GOST algorithms with X.509) compatibility helpers -* GOST R 34.12-2015 128-bit block cipher Кузнечик (Kuznechik) (RFC 7801) -* GOST R 34.12-2015 64-bit block cipher Магма (Magma) -* GOST R 34.13-2015 padding methods and block cipher modes of operation - (ECB, CTR, OFB, CBC, CFB, MAC), ISO 10126 padding -* MGM AEAD mode for 64 and 128 bit ciphers (RFC 9058) -* CTR-ACPKM, OMAC-ACPKM-Master modes of operation (Р 1323565.1.017-2018) -* KExp15/KImp15 key export/import functions (Р 1323565.1.017-2018) -* KDF_GOSTR3411_2012_256, KDF_TREE_GOSTR3411_2012_256 (Р 50.1.113-2016) -* KEG export key generation function (Р 1323565.1.020-2018) -* PEP247-compatible hash/MAC functions - -Known problems: low performance and non time-constant calculations. - -Example 34.10-2012 keypair generation, signing and verifying: - - >>> from pygost.gost3410 import CURVES - >>> curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - >>> from os import urandom - >>> prv_raw = urandom(64) - >>> from pygost.gost3410 import prv_unmarshal - >>> from pygost.gost3410 import prv_marshal - >>> prv = prv_unmarshal(prv_raw) - >>> prv_raw = prv_marshal(curve, prv) - >>> from pygost.gost3410 import public_key - >>> pub = public_key(curve, prv) - >>> from pygost.gost3410 import pub_marshal - >>> from pygost.utils import hexenc - >>> print "Public key is:", hexenc(pub_marshal(pub)) - >>> from pygost import gost34112012512 - >>> data_for_signing = b"some data" - >>> dgst = gost34112012512.new(data_for_signing).digest() - >>> from pygost.gost3410 import sign - >>> signature = sign(curve, prv, dgst) - >>> from pygost.gost3410 import verify - >>> verify(curve, pub, dgst, signature) - True - -Other examples can be found in docstrings and unittests. -Example self-signed X.509 certificate creation can be found in -pygost/asn1schemas/cert-selfsigned-example.py. - -PyGOST is free software: see the file COPYING for copying conditions. - -PyGOST'es home page is: http://www.pygost.cypherpunks.ru/ -You can read about GOST algorithms more: http://www.gost.cypherpunks.ru/ - -Please send questions, bug reports and patches to -http://lists.cypherpunks.ru/gost.html mailing list. -Announcements also go to this mailing list. - -Development Git source code repository currently is located here: -http://www.git.cypherpunks.ru/?p=pygost.git;a=summary diff --git a/pygost-5.13/THANKS b/pygost-5.13/THANKS deleted file mode 100644 index cb2ec9d..0000000 --- a/pygost-5.13/THANKS +++ /dev/null @@ -1,8 +0,0 @@ -There are people deserving to be thanked for helping this project: - -* Dmitry Eremin-Solenikov for his - suggestions of TK26 standards usage as a base point for serialized - structures representation -* Alexander Lodin for finding bug in 34.13-2015 - OFB mode with IVs longer than 2 blocks -* Efimov Vasiliy for adding and testing of CBC-mode key meshing diff --git a/pygost-5.13/VERSION b/pygost-5.13/VERSION deleted file mode 100644 index 3fe7217..0000000 --- a/pygost-5.13/VERSION +++ /dev/null @@ -1 +0,0 @@ -5.13 diff --git a/pygost-5.13/build/lib/pygost/__init__.py b/pygost-5.13/build/lib/pygost/__init__.py deleted file mode 100644 index fba7932..0000000 --- a/pygost-5.13/build/lib/pygost/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Pure Python GOST cryptographic functions library. - -PyGOST is free software: see the file COPYING for copying conditions. -""" - -__version__ = "5.13" diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/__init__.py b/pygost-5.13/build/lib/pygost/asn1schemas/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/cert-dane-hash.py b/pygost-5.13/build/lib/pygost/asn1schemas/cert-dane-hash.py deleted file mode 100644 index 0292b9e..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/cert-dane-hash.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python3 -"""DANE's SPKI hash calculator -""" - -from base64 import standard_b64decode -from hashlib import sha256 -import sys - -from pygost.asn1schemas.x509 import Certificate - - -lines = sys.stdin.read().split("-----") -idx = lines.index("BEGIN CERTIFICATE") -if idx == -1: - raise ValueError("PEM has no CERTIFICATE") -cert_raw = standard_b64decode(lines[idx + 1]) -cert = Certificate().decod(cert_raw) -print(sha256(cert["tbsCertificate"]["subjectPublicKeyInfo"].encode()).hexdigest()) diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/cert-selfsigned-example.py b/pygost-5.13/build/lib/pygost/asn1schemas/cert-selfsigned-example.py deleted file mode 100644 index bd562b1..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/cert-selfsigned-example.py +++ /dev/null @@ -1,348 +0,0 @@ -#!/usr/bin/env python3 -"""Create example self-signed X.509 certificate -""" - -from argparse import ArgumentParser -from base64 import standard_b64decode -from base64 import standard_b64encode -from datetime import datetime -from datetime import timedelta -from os import urandom -from sys import exit as sys_exit -from sys import stdout -from textwrap import fill - -from pyderasn import Any -from pyderasn import BitString -from pyderasn import Boolean -from pyderasn import IA5String -from pyderasn import Integer -from pyderasn import OctetString -from pyderasn import PrintableString -from pyderasn import UTCTime - -from pygost.asn1schemas.oids import id_at_commonName -from pygost.asn1schemas.oids import id_at_countryName -from pygost.asn1schemas.oids import id_ce_authorityKeyIdentifier -from pygost.asn1schemas.oids import id_ce_basicConstraints -from pygost.asn1schemas.oids import id_ce_keyUsage -from pygost.asn1schemas.oids import id_ce_subjectAltName -from pygost.asn1schemas.oids import id_ce_subjectKeyIdentifier -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetA -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetB -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetC -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetD -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetA -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetB -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetC -from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_512 -from pygost.asn1schemas.prvkey import PrivateKey -from pygost.asn1schemas.prvkey import PrivateKeyAlgorithmIdentifier -from pygost.asn1schemas.prvkey import PrivateKeyInfo -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import AttributeType -from pygost.asn1schemas.x509 import AttributeTypeAndValue -from pygost.asn1schemas.x509 import AttributeValue -from pygost.asn1schemas.x509 import AuthorityKeyIdentifier -from pygost.asn1schemas.x509 import BasicConstraints -from pygost.asn1schemas.x509 import Certificate -from pygost.asn1schemas.x509 import CertificateSerialNumber -from pygost.asn1schemas.x509 import Extension -from pygost.asn1schemas.x509 import Extensions -from pygost.asn1schemas.x509 import GeneralName -from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters -from pygost.asn1schemas.x509 import KeyIdentifier -from pygost.asn1schemas.x509 import KeyUsage -from pygost.asn1schemas.x509 import Name -from pygost.asn1schemas.x509 import RDNSequence -from pygost.asn1schemas.x509 import RelativeDistinguishedName -from pygost.asn1schemas.x509 import SubjectAltName -from pygost.asn1schemas.x509 import SubjectKeyIdentifier -from pygost.asn1schemas.x509 import SubjectPublicKeyInfo -from pygost.asn1schemas.x509 import TBSCertificate -from pygost.asn1schemas.x509 import Time -from pygost.asn1schemas.x509 import Validity -from pygost.asn1schemas.x509 import Version -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_marshal -from pygost.gost3410 import public_key -from pygost.gost3410 import sign -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.utils import bytes2long - -parser = ArgumentParser(description="Self-signed X.509 certificate creator") -parser.add_argument( - "--ca", - action="store_true", - help="Enable BasicConstraints.cA", -) -parser.add_argument( - "--cn", - required=True, - help="Subject's CommonName", -) -parser.add_argument( - "--country", - help="Subject's Country", -) -parser.add_argument( - "--serial", - help="Serial number", -) -parser.add_argument( - "--ai", - required=True, - help="Signing algorithm: {256[ABCD],512[ABC]}", -) -parser.add_argument( - "--issue-with", - help="Path to PEM with CA to issue the child", -) -parser.add_argument( - "--reuse-key", - help="Path to PEM with the key to reuse", -) -parser.add_argument( - "--out-key", - help="Path to PEM with the resulting key", -) -parser.add_argument( - "--only-key", - action="store_true", - help="Only generate the key", -) -parser.add_argument( - "--out-cert", - help="Path to PEM with the resulting certificate", -) -args = parser.parse_args() -AIs = { - "256A": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetA, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetA"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "256B": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetB, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetB"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "256C": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetC, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetC"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "256D": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetD, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetD"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "512A": { - "publicKeyParamSet": id_tc26_gost3410_2012_512_paramSetA, - "key_algorithm": id_tc26_gost3410_2012_512, - "prv_len": 64, - "curve": CURVES["id-tc26-gost-3410-12-512-paramSetA"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_512, - "hasher": GOST34112012512, - }, - "512B": { - "publicKeyParamSet": id_tc26_gost3410_2012_512_paramSetB, - "key_algorithm": id_tc26_gost3410_2012_512, - "prv_len": 64, - "curve": CURVES["id-tc26-gost-3410-12-512-paramSetB"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_512, - "hasher": GOST34112012512, - }, - "512C": { - "publicKeyParamSet": id_tc26_gost3410_2012_512_paramSetC, - "key_algorithm": id_tc26_gost3410_2012_512, - "prv_len": 64, - "curve": CURVES["id-tc26-gost-3410-2012-512-paramSetC"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_512, - "hasher": GOST34112012512, - }, -} -ai = AIs[args.ai] - -ca_prv = None -ca_cert = None -ca_subj = None -ca_ai = None -if args.issue_with is not None: - with open(args.issue_with, "rb") as fd: - lines = fd.read().decode("ascii").split("-----") - idx = lines.index("BEGIN PRIVATE KEY") - if idx == -1: - raise ValueError("PEM has no PRIVATE KEY") - prv_raw = standard_b64decode(lines[idx + 1]) - idx = lines.index("BEGIN CERTIFICATE") - if idx == -1: - raise ValueError("PEM has no CERTIFICATE") - cert_raw = standard_b64decode(lines[idx + 1]) - pki = PrivateKeyInfo().decod(prv_raw) - ca_prv = prv_unmarshal(bytes(OctetString().decod(bytes(pki["privateKey"])))) - ca_cert = Certificate().decod(cert_raw) - tbs = ca_cert["tbsCertificate"] - ca_subj = tbs["subject"] - curve_oid = GostR34102012PublicKeyParameters().decod(bytes( - tbs["subjectPublicKeyInfo"]["algorithm"]["parameters"] - ))["publicKeyParamSet"] - ca_ai = next(iter([ - params for params in AIs.values() - if params["publicKeyParamSet"] == curve_oid - ])) - -key_params = GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", ai["publicKeyParamSet"]), -)) - - -def pem(obj): - return fill(standard_b64encode(obj.encode()).decode("ascii"), 64) - - -if args.reuse_key is not None: - with open(args.reuse_key, "rb") as fd: - lines = fd.read().decode("ascii").split("-----") - idx = lines.index("BEGIN PRIVATE KEY") - if idx == -1: - raise ValueError("PEM has no PRIVATE KEY") - prv_raw = standard_b64decode(lines[idx + 1]) - pki = PrivateKeyInfo().decod(prv_raw) - prv = prv_unmarshal(bytes(OctetString().decod(bytes(pki["privateKey"])))) -else: - prv_raw = urandom(ai["prv_len"]) - out = stdout if args.out_key is None else open(args.out_key, "w") - print("-----BEGIN PRIVATE KEY-----", file=out) - print(pem(PrivateKeyInfo(( - ("version", Integer(0)), - ("privateKeyAlgorithm", PrivateKeyAlgorithmIdentifier(( - ("algorithm", ai["key_algorithm"]), - ("parameters", Any(key_params)), - ))), - ("privateKey", PrivateKey(OctetString(prv_raw).encode())), - ))), file=out) - print("-----END PRIVATE KEY-----", file=out) - if args.only_key: - sys_exit() - prv = prv_unmarshal(prv_raw) - -curve = ai["curve"] -pub_raw = pub_marshal(public_key(curve, prv)) -rdn = [RelativeDistinguishedName(( - AttributeTypeAndValue(( - ("type", AttributeType(id_at_commonName)), - ("value", AttributeValue(PrintableString(args.cn))), - )), -))] -if args.country: - rdn.append(RelativeDistinguishedName(( - AttributeTypeAndValue(( - ("type", AttributeType(id_at_countryName)), - ("value", AttributeValue(PrintableString(args.country))), - )), - ))) -subj = Name(("rdnSequence", RDNSequence(rdn))) -not_before = datetime.utcnow() -not_after = not_before + timedelta(days=365 * (10 if args.ca else 1)) -ai_sign = AlgorithmIdentifier(( - ("algorithm", (ai if ca_ai is None else ca_ai)["sign_algorithm"]), -)) -exts = [ - Extension(( - ("extnID", id_ce_subjectKeyIdentifier), - ("extnValue", OctetString( - SubjectKeyIdentifier(GOST34112012256(pub_raw).digest()[:20]).encode() - )), - )), - Extension(( - ("extnID", id_ce_keyUsage), - ("critical", Boolean(True)), - ("extnValue", OctetString(KeyUsage( - ("keyCertSign" if args.ca else "digitalSignature",), - ).encode())), - )), -] -if args.ca: - exts.append(Extension(( - ("extnID", id_ce_basicConstraints), - ("critical", Boolean(True)), - ("extnValue", OctetString(BasicConstraints(( - ("cA", Boolean(True)), - )).encode())), - ))) -else: - exts.append(Extension(( - ("extnID", id_ce_subjectAltName), - ("extnValue", OctetString( - SubjectAltName(( - GeneralName(("dNSName", IA5String(args.cn))), - )).encode() - )), - ))) -if ca_ai is not None: - caKeyId = [ - bytes(SubjectKeyIdentifier().decod(bytes(ext["extnValue"]))) - for ext in ca_cert["tbsCertificate"]["extensions"] - if ext["extnID"] == id_ce_subjectKeyIdentifier - ][0] - exts.append(Extension(( - ("extnID", id_ce_authorityKeyIdentifier), - ("extnValue", OctetString(AuthorityKeyIdentifier(( - ("keyIdentifier", KeyIdentifier(caKeyId)), - )).encode())), - ))) - -serial = ( - bytes2long(GOST34112012256(urandom(16)).digest()[:20]) - if args.serial is None else int(args.serial) -) -tbs = TBSCertificate(( - ("version", Version("v3")), - ("serialNumber", CertificateSerialNumber(serial)), - ("signature", ai_sign), - ("issuer", subj if ca_ai is None else ca_subj), - ("validity", Validity(( - ("notBefore", Time(("utcTime", UTCTime(not_before)))), - ("notAfter", Time(("utcTime", UTCTime(not_after)))), - ))), - ("subject", subj), - ("subjectPublicKeyInfo", SubjectPublicKeyInfo(( - ("algorithm", AlgorithmIdentifier(( - ("algorithm", ai["key_algorithm"]), - ("parameters", Any(key_params)), - ))), - ("subjectPublicKey", BitString(OctetString(pub_raw).encode())), - ))), - ("extensions", Extensions(exts)), -)) -cert = Certificate(( - ("tbsCertificate", tbs), - ("signatureAlgorithm", ai_sign), - ("signatureValue", BitString( - sign(curve, prv, ai["hasher"](tbs.encode()).digest()[::-1]) - if ca_ai is None else - sign(ca_ai["curve"], ca_prv, ca_ai["hasher"](tbs.encode()).digest()[::-1]) - )), -)) -out = stdout if args.out_cert is None else open(args.out_cert, "w") -print("-----BEGIN CERTIFICATE-----", file=out) -print(pem(cert), file=out) -print("-----END CERTIFICATE-----", file=out) diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/cms.py b/pygost-5.13/build/lib/pygost/asn1schemas/cms.py deleted file mode 100644 index 8028d2b..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/cms.py +++ /dev/null @@ -1,431 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""CMS related structures (**NOT COMPLETE**) -""" - -from pyderasn import Any -from pyderasn import BitString -from pyderasn import Choice -from pyderasn import Integer -from pyderasn import ObjectIdentifier -from pyderasn import OctetString -from pyderasn import Sequence -from pyderasn import SequenceOf -from pyderasn import SetOf -from pyderasn import tag_ctxc -from pyderasn import tag_ctxp - -from pygost.asn1schemas.oids import id_cms_mac_attr -from pygost.asn1schemas.oids import id_contentType -from pygost.asn1schemas.oids import id_digestedData -from pygost.asn1schemas.oids import id_encryptedData -from pygost.asn1schemas.oids import id_envelopedData -from pygost.asn1schemas.oids import id_Gost28147_89 -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm_omac -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_wrap_kexp15 -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm_omac -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_wrap_kexp15 -from pygost.asn1schemas.oids import id_messageDigest -from pygost.asn1schemas.oids import id_signedData -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import Certificate -from pygost.asn1schemas.x509 import CertificateSerialNumber -from pygost.asn1schemas.x509 import Name -from pygost.asn1schemas.x509 import SubjectPublicKeyInfo - - -class CMSVersion(Integer): - pass - - -class ContentType(ObjectIdentifier): - pass - - -class IssuerAndSerialNumber(Sequence): - schema = ( - ("issuer", Name()), - ("serialNumber", CertificateSerialNumber()), - ) - - -class KeyIdentifier(OctetString): - pass - - -class SubjectKeyIdentifier(KeyIdentifier): - pass - - -class RecipientIdentifier(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - ("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))), - ) - - -class Gost2814789Key(OctetString): - bounds = (32, 32) - - -class Gost2814789MAC(OctetString): - bounds = (4, 4) - - -class Gost2814789EncryptedKey(Sequence): - schema = ( - ("encryptedKey", Gost2814789Key()), - ("maskKey", Gost2814789Key(impl=tag_ctxp(0), optional=True)), - ("macKey", Gost2814789MAC()), - ) - - -class GostR34102001TransportParameters(Sequence): - schema = ( - ("encryptionParamSet", ObjectIdentifier()), - ("ephemeralPublicKey", SubjectPublicKeyInfo( - impl=tag_ctxc(0), - optional=True, - )), - ("ukm", OctetString()), - ) - - -class GostR3410KeyTransport(Sequence): - schema = ( - ("sessionEncryptedKey", Gost2814789EncryptedKey()), - ("transportParameters", GostR34102001TransportParameters( - impl=tag_ctxc(0), - optional=True, - )), - ) - - -class GostR3410KeyTransport2019(Sequence): - schema = ( - ("encryptedKey", OctetString()), - ("ephemeralPublicKey", SubjectPublicKeyInfo()), - ("ukm", OctetString()), - ) - - -class GostR341012KEGParameters(Sequence): - schema = ( - ("algorithm", ObjectIdentifier()), - ) - - -class KeyEncryptionAlgorithmIdentifier(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_gostr3412_2015_magma_wrap_kexp15: GostR341012KEGParameters(), - id_gostr3412_2015_kuznyechik_wrap_kexp15: GostR341012KEGParameters(), - }), - (("..", "encryptedKey"), { - id_tc26_gost3410_2012_256: GostR3410KeyTransport(), - id_tc26_gost3410_2012_512: GostR3410KeyTransport(), - id_gostr3412_2015_magma_wrap_kexp15: GostR3410KeyTransport2019(), - id_gostr3412_2015_kuznyechik_wrap_kexp15: GostR3410KeyTransport2019(), - }), - (("..", "recipientEncryptedKeys", any, "encryptedKey"), { - id_tc26_gost3410_2012_256: Gost2814789EncryptedKey(), - id_tc26_gost3410_2012_512: Gost2814789EncryptedKey(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class EncryptedKey(OctetString): - pass - - -class KeyTransRecipientInfo(Sequence): - schema = ( - ("version", CMSVersion()), - ("rid", RecipientIdentifier()), - ("keyEncryptionAlgorithm", KeyEncryptionAlgorithmIdentifier()), - ("encryptedKey", EncryptedKey()), - ) - - -class OriginatorPublicKey(Sequence): - schema = ( - ("algorithm", AlgorithmIdentifier()), - ("publicKey", BitString()), - ) - - -class OriginatorIdentifierOrKey(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - ("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))), - ("originatorKey", OriginatorPublicKey(impl=tag_ctxc(1))), - ) - - -class UserKeyingMaterial(OctetString): - pass - - -class KeyAgreeRecipientIdentifier(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - # ("rKeyId", RecipientKeyIdentifier(impl=tag_ctxc(0))), - ) - - -class RecipientEncryptedKey(Sequence): - schema = ( - ("rid", KeyAgreeRecipientIdentifier()), - ("encryptedKey", EncryptedKey()), - ) - - -class RecipientEncryptedKeys(SequenceOf): - schema = RecipientEncryptedKey() - - -class KeyAgreeRecipientInfo(Sequence): - schema = ( - ("version", CMSVersion(3)), - ("originator", OriginatorIdentifierOrKey(expl=tag_ctxc(0))), - ("ukm", UserKeyingMaterial(expl=tag_ctxc(1), optional=True)), - ("keyEncryptionAlgorithm", KeyEncryptionAlgorithmIdentifier()), - ("recipientEncryptedKeys", RecipientEncryptedKeys()), - ) - - -class RecipientInfo(Choice): - schema = ( - ("ktri", KeyTransRecipientInfo()), - ("kari", KeyAgreeRecipientInfo(impl=tag_ctxc(1))), - # ("kekri", KEKRecipientInfo(impl=tag_ctxc(2))), - # ("pwri", PasswordRecipientInfo(impl=tag_ctxc(3))), - # ("ori", OtherRecipientInfo(impl=tag_ctxc(4))), - ) - - -class RecipientInfos(SetOf): - schema = RecipientInfo() - bounds = (1, float("+inf")) - - -class Gost2814789IV(OctetString): - bounds = (8, 8) - - -class Gost2814789Parameters(Sequence): - schema = ( - ("iv", Gost2814789IV()), - ("encryptionParamSet", ObjectIdentifier()), - ) - - -class Gost341215EncryptionParameters(Sequence): - schema = ( - ("ukm", OctetString()), - ) - - -class ContentEncryptionAlgorithmIdentifier(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_Gost28147_89: Gost2814789Parameters(), - id_gostr3412_2015_magma_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_magma_ctracpkm_omac: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm_omac: Gost341215EncryptionParameters(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class EncryptedContent(OctetString): - pass - - -class EncryptedContentInfo(Sequence): - schema = ( - ("contentType", ContentType()), - ("contentEncryptionAlgorithm", ContentEncryptionAlgorithmIdentifier()), - ("encryptedContent", EncryptedContent(impl=tag_ctxp(0), optional=True)), - ) - - -class Digest(OctetString): - pass - - -class AttributeValue(Any): - pass - - -class AttributeValues(SetOf): - schema = AttributeValue() - - -class EncryptedMac(OctetString): - pass - - -class Attribute(Sequence): - schema = ( - ("attrType", ObjectIdentifier(defines=( - (("attrValues",), { - id_contentType: ObjectIdentifier(), - id_messageDigest: Digest(), - id_cms_mac_attr: EncryptedMac(), - },), - ))), - ("attrValues", AttributeValues()), - ) - - -class UnprotectedAttributes(SetOf): - schema = Attribute() - bounds = (1, float("+inf")) - - -class CertificateChoices(Choice): - schema = ( - ("certificate", Certificate()), - # ("extendedCertificate", OctetString(impl=tag_ctxp(0))), - # ("v1AttrCert", AttributeCertificateV1(impl=tag_ctxc(1))), # V1 is osbolete - # ("v2AttrCert", AttributeCertificateV2(impl=tag_ctxc(2))), - # ("other", OtherCertificateFormat(impl=tag_ctxc(3))), - ) - - -class CertificateSet(SetOf): - schema = CertificateChoices() - - -class OriginatorInfo(Sequence): - schema = ( - ("certs", CertificateSet(impl=tag_ctxc(0), optional=True)), - # ("crls", RevocationInfoChoices(impl=tag_ctxc(1), optional=True)), - ) - - -class EnvelopedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("originatorInfo", OriginatorInfo(impl=tag_ctxc(0), optional=True)), - ("recipientInfos", RecipientInfos()), - ("encryptedContentInfo", EncryptedContentInfo()), - ("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class EncapsulatedContentInfo(Sequence): - schema = ( - ("eContentType", ContentType()), - ("eContent", OctetString(expl=tag_ctxc(0), optional=True)), - ) - - -class SignerIdentifier(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - ("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))), - ) - - -class DigestAlgorithmIdentifiers(SetOf): - schema = AlgorithmIdentifier() - - -class DigestAlgorithmIdentifier(AlgorithmIdentifier): - pass - - -class SignatureAlgorithmIdentifier(AlgorithmIdentifier): - pass - - -class SignatureValue(OctetString): - pass - - -class SignedAttributes(SetOf): - schema = Attribute() - bounds = (1, float("+inf")) - - -class SignerInfo(Sequence): - schema = ( - ("version", CMSVersion()), - ("sid", SignerIdentifier()), - ("digestAlgorithm", DigestAlgorithmIdentifier()), - ("signedAttrs", SignedAttributes(impl=tag_ctxc(0), optional=True)), - ("signatureAlgorithm", SignatureAlgorithmIdentifier()), - ("signature", SignatureValue()), - # ("unsignedAttrs", UnsignedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class SignerInfos(SetOf): - schema = SignerInfo() - - -class SignedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("digestAlgorithms", DigestAlgorithmIdentifiers()), - ("encapContentInfo", EncapsulatedContentInfo()), - ("certificates", CertificateSet(impl=tag_ctxc(0), optional=True)), - # ("crls", RevocationInfoChoices(impl=tag_ctxc(1), optional=True)), - ("signerInfos", SignerInfos()), - ) - - -class DigestedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("digestAlgorithm", DigestAlgorithmIdentifier()), - ("encapContentInfo", EncapsulatedContentInfo()), - ("digest", Digest()), - ) - - -class EncryptedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("encryptedContentInfo", EncryptedContentInfo()), - ("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class ContentInfo(Sequence): - schema = ( - ("contentType", ContentType(defines=( - (("content",), { - id_digestedData: DigestedData(), - id_encryptedData: EncryptedData(), - id_envelopedData: EnvelopedData(), - id_signedData: SignedData(), - }), - ))), - ("content", Any(expl=tag_ctxc(0))), - ) diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/oids.py b/pygost-5.13/build/lib/pygost/asn1schemas/oids.py deleted file mode 100644 index 4638900..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/oids.py +++ /dev/null @@ -1,60 +0,0 @@ -from pyderasn import ObjectIdentifier - - -id_at_commonName = ObjectIdentifier("2.5.4.3") -id_at_countryName = ObjectIdentifier("2.5.4.6") -id_at_localityName = ObjectIdentifier("2.5.4.7") -id_at_stateOrProvinceName = ObjectIdentifier("2.5.4.8") -id_at_organizationName = ObjectIdentifier("2.5.4.10") - -id_pkcs7 = ObjectIdentifier("1.2.840.113549.1.7") -id_data = id_pkcs7 + (1,) -id_signedData = id_pkcs7 + (2,) -id_envelopedData = id_pkcs7 + (3,) -id_digestedData = id_pkcs7 + (5,) -id_encryptedData = id_pkcs7 + (6,) - -id_pkcs9 = ObjectIdentifier("1.2.840.113549.1.9") -id_contentType = id_pkcs9 + (3,) -id_messageDigest = id_pkcs9 + (4,) -id_pkcs9_certTypes_x509Certificate = ObjectIdentifier("1.2.840.113549.1.9.22.1") -id_pkcs12_bagtypes_keyBag = ObjectIdentifier("1.2.840.113549.1.12.10.1.1") -id_pkcs12_bagtypes_pkcs8ShroudedKeyBag = ObjectIdentifier("1.2.840.113549.1.12.10.1.2") -id_pkcs12_bagtypes_certBag = ObjectIdentifier("1.2.840.113549.1.12.10.1.3") - -id_Gost28147_89 = ObjectIdentifier("1.2.643.2.2.21") -id_GostR3410_2001_TestParamSet = ObjectIdentifier("1.2.643.2.2.35.0") -id_cms_mac_attr = ObjectIdentifier("1.2.643.7.1.0.6.1.1") -id_tc26_gost3410_2012_256 = ObjectIdentifier("1.2.643.7.1.1.1.1") -id_tc26_gost3410_2012_512 = ObjectIdentifier("1.2.643.7.1.1.1.2") -id_tc26_gost3411_2012_256 = ObjectIdentifier("1.2.643.7.1.1.2.2") -id_tc26_gost3411_2012_512 = ObjectIdentifier("1.2.643.7.1.1.2.3") -id_tc26_signwithdigest_gost3410_2012_256 = ObjectIdentifier("1.2.643.7.1.1.3.2") -id_tc26_signwithdigest_gost3410_2012_512 = ObjectIdentifier("1.2.643.7.1.1.3.3") -id_gostr3412_2015_magma_ctracpkm = ObjectIdentifier("1.2.643.7.1.1.5.1.1") -id_gostr3412_2015_magma_ctracpkm_omac = ObjectIdentifier("1.2.643.7.1.1.5.1.2") -id_gostr3412_2015_kuznyechik_ctracpkm = ObjectIdentifier("1.2.643.7.1.1.5.2.1") -id_gostr3412_2015_kuznyechik_ctracpkm_omac = ObjectIdentifier("1.2.643.7.1.1.5.2.2") -id_tc26_agreement_gost3410_2012_256 = ObjectIdentifier("1.2.643.7.1.1.6.1") -id_tc26_agreement_gost3410_2012_512 = ObjectIdentifier("1.2.643.7.1.1.6.2") -id_gostr3412_2015_magma_wrap_kexp15 = ObjectIdentifier("1.2.643.7.1.1.7.1.1") -id_gostr3412_2015_kuznyechik_wrap_kexp15 = ObjectIdentifier("1.2.643.7.1.1.7.2.1") -id_tc26_gost3410_2012_256_paramSetA = ObjectIdentifier("1.2.643.7.1.2.1.1.1") -id_tc26_gost3410_2012_256_paramSetB = ObjectIdentifier("1.2.643.7.1.2.1.1.2") -id_tc26_gost3410_2012_256_paramSetC = ObjectIdentifier("1.2.643.7.1.2.1.1.3") -id_tc26_gost3410_2012_256_paramSetD = ObjectIdentifier("1.2.643.7.1.2.1.1.4") -id_tc26_gost3410_2012_512_paramSetTest = ObjectIdentifier("1.2.643.7.1.2.1.2.0") -id_tc26_gost3410_2012_512_paramSetA = ObjectIdentifier("1.2.643.7.1.2.1.2.1") -id_tc26_gost3410_2012_512_paramSetB = ObjectIdentifier("1.2.643.7.1.2.1.2.2") -id_tc26_gost3410_2012_512_paramSetC = ObjectIdentifier("1.2.643.7.1.2.1.2.3") -id_tc26_gost_28147_param_Z = ObjectIdentifier("1.2.643.7.1.2.5.1.1") - -id_pbes2 = ObjectIdentifier("1.2.840.113549.1.5.13") -id_pbkdf2 = ObjectIdentifier("1.2.840.113549.1.5.12") - -id_at_commonName = ObjectIdentifier("2.5.4.3") -id_ce_basicConstraints = ObjectIdentifier("2.5.29.19") -id_ce_subjectKeyIdentifier = ObjectIdentifier("2.5.29.14") -id_ce_keyUsage = ObjectIdentifier("2.5.29.15") -id_ce_subjectAltName = ObjectIdentifier("2.5.29.17") -id_ce_authorityKeyIdentifier = ObjectIdentifier("2.5.29.35") diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/pfx.py b/pygost-5.13/build/lib/pygost/asn1schemas/pfx.py deleted file mode 100644 index 27a87d0..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/pfx.py +++ /dev/null @@ -1,250 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""PKCS #12 related structures (**NOT COMPLETE**) -""" - -from pyderasn import Any -from pyderasn import Choice -from pyderasn import Integer -from pyderasn import ObjectIdentifier -from pyderasn import OctetString -from pyderasn import Sequence -from pyderasn import SequenceOf -from pyderasn import SetOf -from pyderasn import tag_ctxc -from pyderasn import tag_ctxp - -from pygost.asn1schemas.cms import CMSVersion -from pygost.asn1schemas.cms import ContentType -from pygost.asn1schemas.cms import Gost2814789Parameters -from pygost.asn1schemas.cms import Gost341215EncryptionParameters -from pygost.asn1schemas.oids import id_data -from pygost.asn1schemas.oids import id_encryptedData -from pygost.asn1schemas.oids import id_Gost28147_89 -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm_omac -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm_omac -from pygost.asn1schemas.oids import id_pbes2 -from pygost.asn1schemas.oids import id_pbkdf2 -from pygost.asn1schemas.oids import id_pkcs9_certTypes_x509Certificate -from pygost.asn1schemas.prvkey import PrivateKeyInfo -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import Certificate - - -class PBKDF2Salt(Choice): - schema = ( - ("specified", OctetString()), - # ("otherSource", PBKDF2SaltSources()), - ) - - -id_hmacWithSHA1 = ObjectIdentifier("1.2.840.113549.2.7") - - -class PBKDF2PRFs(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(default=id_hmacWithSHA1)), - ("parameters", Any(optional=True)), - ) - - -class IterationCount(Integer): - bounds = (1, float("+inf")) - - -class KeyLength(Integer): - bounds = (1, float("+inf")) - - -class PBKDF2Params(Sequence): - schema = ( - ("salt", PBKDF2Salt()), - ("iterationCount", IterationCount(optional=True)), - ("keyLength", KeyLength(optional=True)), - ("prf", PBKDF2PRFs()), - ) - - -class PBES2KDFs(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), {id_pbkdf2: PBKDF2Params()}), - ))), - ("parameters", Any(optional=True)), - ) - - -class PBES2Encs(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_Gost28147_89: Gost2814789Parameters(), - id_gostr3412_2015_magma_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_magma_ctracpkm_omac: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm_omac: Gost341215EncryptionParameters(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class PBES2Params(Sequence): - schema = ( - ("keyDerivationFunc", PBES2KDFs()), - ("encryptionScheme", PBES2Encs()), - ) - - -class EncryptionAlgorithmIdentifier(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), {id_pbes2: PBES2Params()}), - ))), - ("parameters", Any(optional=True)), - ) - - -class ContentEncryptionAlgorithmIdentifier(EncryptionAlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), {id_pbes2: PBES2Params()}), - ))), - ("parameters", Any(optional=True)), - ) - - -class EncryptedContent(OctetString): - pass - - -class EncryptedContentInfo(Sequence): - schema = ( - ("contentType", ContentType()), - ("contentEncryptionAlgorithm", ContentEncryptionAlgorithmIdentifier()), - ("encryptedContent", EncryptedContent(impl=tag_ctxp(0), optional=True)), - ) - - -class EncryptedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("encryptedContentInfo", EncryptedContentInfo()), - # ("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class PKCS12BagSet(Any): - pass - - -class AttrValue(SetOf): - schema = Any() - - -class PKCS12Attribute(Sequence): - schema = ( - ("attrId", ObjectIdentifier()), - ("attrValue", AttrValue()), - ) - - -class PKCS12Attributes(SetOf): - schema = PKCS12Attribute() - - -class SafeBag(Sequence): - schema = ( - ("bagId", ObjectIdentifier(defines=( - (("bagValue",), {id_encryptedData: EncryptedData()}), - ))), - ("bagValue", PKCS12BagSet(expl=tag_ctxc(0))), - ("bagAttributes", PKCS12Attributes(optional=True)), - ) - - -class SafeContents(SequenceOf): - schema = SafeBag() - - -OctetStringSafeContents = SafeContents(expl=OctetString.tag_default) - - -class AuthSafe(Sequence): - schema = ( - ("contentType", ContentType(defines=( - (("content",), {id_data: OctetStringSafeContents()}), - ))), - ("content", Any(expl=tag_ctxc(0))), - ) - - -class DigestInfo(Sequence): - schema = ( - ("digestAlgorithm", AlgorithmIdentifier()), - ("digest", OctetString()), - ) - - -class MacData(Sequence): - schema = ( - ("mac", DigestInfo()), - ("macSalt", OctetString()), - ("iterations", Integer(default=1)), - ) - - -class PFX(Sequence): - schema = ( - ("version", Integer(default=1)), - ("authSafe", AuthSafe()), - ("macData", MacData(optional=True)), - ) - - -class EncryptedPrivateKeyInfo(Sequence): - schema = ( - ("encryptionAlgorithm", EncryptionAlgorithmIdentifier()), - ("encryptedData", OctetString()), - ) - - -class PKCS8ShroudedKeyBag(EncryptedPrivateKeyInfo): - pass - - -OctetStringX509Certificate = Certificate(expl=OctetString.tag_default) - - -class CertTypes(Any): - pass - - -class CertBag(Sequence): - schema = ( - ("certId", ObjectIdentifier(defines=( - (("certValue",), { - id_pkcs9_certTypes_x509Certificate: OctetStringX509Certificate(), - }), - ))), - ("certValue", CertTypes(expl=tag_ctxc(0))), - ) - - -class KeyBag(PrivateKeyInfo): - pass diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/pkcs10.py b/pygost-5.13/build/lib/pygost/asn1schemas/pkcs10.py deleted file mode 100644 index dce45dd..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/pkcs10.py +++ /dev/null @@ -1,49 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""PKCS #10 related structures (**NOT COMPLETE**) -""" - -from pyderasn import BitString -from pyderasn import Integer -from pyderasn import Sequence -from pyderasn import SetOf -from pyderasn import tag_ctxc - -from pygost.asn1schemas.cms import Attribute -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import Name -from pygost.asn1schemas.x509 import SubjectPublicKeyInfo - - -class Attributes(SetOf): - schema = Attribute() - - -class CertificationRequestInfo(Sequence): - schema = ( - ("version", Integer(0)), - ("subject", Name()), - ("subjectPKInfo", SubjectPublicKeyInfo()), - ("attributes", Attributes(impl=tag_ctxc(0))), - ) - - -class CertificationRequest(Sequence): - schema = ( - ("certificationRequestInfo", CertificationRequestInfo()), - ("signatureAlgorithm", AlgorithmIdentifier()), - ("signature", BitString()), - ) diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/prvkey.py b/pygost-5.13/build/lib/pygost/asn1schemas/prvkey.py deleted file mode 100644 index 7da2533..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/prvkey.py +++ /dev/null @@ -1,100 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from pyderasn import Any -from pyderasn import BitString -from pyderasn import Choice -from pyderasn import Integer -from pyderasn import Null -from pyderasn import ObjectIdentifier -from pyderasn import OctetString -from pyderasn import Sequence -from pyderasn import SetOf -from pyderasn import tag_ctxc -from pyderasn import tag_ctxp - -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 -from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters - - -class ECParameters(Choice): - schema = ( - ("namedCurve", ObjectIdentifier()), - ("implicitCurve", Null()), - # ("specifiedCurve", SpecifiedECDomain()), - ) - - -ecPrivkeyVer1 = Integer(1) - - -class ECPrivateKey(Sequence): - schema = ( - ("version", Integer(ecPrivkeyVer1)), - ("privateKey", OctetString()), - ("parameters", ECParameters(expl=tag_ctxc(0), optional=True)), - ("publicKey", BitString(expl=tag_ctxc(1), optional=True)), - ) - - -class PrivateKeyAlgorithmIdentifier(Sequence): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_tc26_gost3410_2012_256: GostR34102012PublicKeyParameters(), - id_tc26_gost3410_2012_512: GostR34102012PublicKeyParameters(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class PrivateKey(OctetString): - pass - - -class AttributeValue(Any): - pass - - -class AttributeValues(SetOf): - schema = AttributeValue() - - -class Attribute(Sequence): - schema = ( - ("attrType", ObjectIdentifier()), - ("attrValues", AttributeValues()), - ) - - -class Attributes(SetOf): - schema = Attribute() - - -class PublicKey(BitString): - pass - - -class PrivateKeyInfo(Sequence): - schema = ( - ("version", Integer(0)), - ("privateKeyAlgorithm", PrivateKeyAlgorithmIdentifier()), - ("privateKey", PrivateKey()), - ("attributes", Attributes(impl=tag_ctxc(0), optional=True)), - ("publicKey", PublicKey(impl=tag_ctxp(1), optional=True)), - ) diff --git a/pygost-5.13/build/lib/pygost/asn1schemas/x509.py b/pygost-5.13/build/lib/pygost/asn1schemas/x509.py deleted file mode 100644 index 86ad7da..0000000 --- a/pygost-5.13/build/lib/pygost/asn1schemas/x509.py +++ /dev/null @@ -1,262 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -""":rfc:`5280` related structures (**NOT COMPLETE**) - -They are taken from `PyDERASN -# -# 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, version 3 of the License. -# -# 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 . -"""GOST 28147-89 block cipher - -This is implementation of :rfc:`5830` ECB, CNT, CFB and :rfc:`4357` -CBC modes of operation. N1, N2, K names are taken according to -specification's terminology. CNT and CFB modes can work with arbitrary -data lengths. -""" - -from functools import partial - -from pygost.gost3413 import pad2 -from pygost.gost3413 import pad_size -from pygost.gost3413 import unpad2 -from pygost.utils import hexdec -from pygost.utils import strxor -from pygost.utils import xrange - - -KEYSIZE = 32 -BLOCKSIZE = 8 -C1 = 0x01010104 -C2 = 0x01010101 - -# Sequence of K_i S-box applying for encryption and decryption -SEQ_ENCRYPT = ( - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 7, 6, 5, 4, 3, 2, 1, 0, -) -SEQ_DECRYPT = ( - 0, 1, 2, 3, 4, 5, 6, 7, - 7, 6, 5, 4, 3, 2, 1, 0, - 7, 6, 5, 4, 3, 2, 1, 0, - 7, 6, 5, 4, 3, 2, 1, 0, -) - -# S-box parameters -DEFAULT_SBOX = "id-Gost28147-89-CryptoPro-A-ParamSet" -SBOXES = { - "id-Gost28147-89-TestParamSet": ( - (4, 2, 15, 5, 9, 1, 0, 8, 14, 3, 11, 12, 13, 7, 10, 6), - (12, 9, 15, 14, 8, 1, 3, 10, 2, 7, 4, 13, 6, 0, 11, 5), - (13, 8, 14, 12, 7, 3, 9, 10, 1, 5, 2, 4, 6, 15, 0, 11), - (14, 9, 11, 2, 5, 15, 7, 1, 0, 13, 12, 6, 10, 4, 3, 8), - (3, 14, 5, 9, 6, 8, 0, 13, 10, 11, 7, 12, 2, 1, 15, 4), - (8, 15, 6, 11, 1, 9, 12, 5, 13, 3, 7, 10, 0, 14, 2, 4), - (9, 11, 12, 0, 3, 6, 7, 5, 4, 8, 14, 15, 1, 10, 2, 13), - (12, 6, 5, 2, 11, 0, 9, 13, 3, 14, 7, 10, 15, 4, 1, 8), - ), - "id-Gost28147-89-CryptoPro-A-ParamSet": ( - (9, 6, 3, 2, 8, 11, 1, 7, 10, 4, 14, 15, 12, 0, 13, 5), - (3, 7, 14, 9, 8, 10, 15, 0, 5, 2, 6, 12, 11, 4, 13, 1), - (14, 4, 6, 2, 11, 3, 13, 8, 12, 15, 5, 10, 0, 7, 1, 9), - (14, 7, 10, 12, 13, 1, 3, 9, 0, 2, 11, 4, 15, 8, 5, 6), - (11, 5, 1, 9, 8, 13, 15, 0, 14, 4, 2, 3, 12, 7, 10, 6), - (3, 10, 13, 12, 1, 2, 0, 11, 7, 5, 9, 4, 8, 15, 14, 6), - (1, 13, 2, 9, 7, 10, 6, 0, 8, 12, 4, 5, 15, 3, 11, 14), - (11, 10, 15, 5, 0, 12, 14, 8, 6, 2, 3, 9, 1, 7, 13, 4), - ), - "id-Gost28147-89-CryptoPro-B-ParamSet": ( - (8, 4, 11, 1, 3, 5, 0, 9, 2, 14, 10, 12, 13, 6, 7, 15), - (0, 1, 2, 10, 4, 13, 5, 12, 9, 7, 3, 15, 11, 8, 6, 14), - (14, 12, 0, 10, 9, 2, 13, 11, 7, 5, 8, 15, 3, 6, 1, 4), - (7, 5, 0, 13, 11, 6, 1, 2, 3, 10, 12, 15, 4, 14, 9, 8), - (2, 7, 12, 15, 9, 5, 10, 11, 1, 4, 0, 13, 6, 8, 14, 3), - (8, 3, 2, 6, 4, 13, 14, 11, 12, 1, 7, 15, 10, 0, 9, 5), - (5, 2, 10, 11, 9, 1, 12, 3, 7, 4, 13, 0, 6, 15, 8, 14), - (0, 4, 11, 14, 8, 3, 7, 1, 10, 2, 9, 6, 15, 13, 5, 12), - ), - "id-Gost28147-89-CryptoPro-C-ParamSet": ( - (1, 11, 12, 2, 9, 13, 0, 15, 4, 5, 8, 14, 10, 7, 6, 3), - (0, 1, 7, 13, 11, 4, 5, 2, 8, 14, 15, 12, 9, 10, 6, 3), - (8, 2, 5, 0, 4, 9, 15, 10, 3, 7, 12, 13, 6, 14, 1, 11), - (3, 6, 0, 1, 5, 13, 10, 8, 11, 2, 9, 7, 14, 15, 12, 4), - (8, 13, 11, 0, 4, 5, 1, 2, 9, 3, 12, 14, 6, 15, 10, 7), - (12, 9, 11, 1, 8, 14, 2, 4, 7, 3, 6, 5, 10, 0, 15, 13), - (10, 9, 6, 8, 13, 14, 2, 0, 15, 3, 5, 11, 4, 1, 12, 7), - (7, 4, 0, 5, 10, 2, 15, 14, 12, 6, 1, 11, 13, 9, 3, 8), - ), - "id-Gost28147-89-CryptoPro-D-ParamSet": ( - (15, 12, 2, 10, 6, 4, 5, 0, 7, 9, 14, 13, 1, 11, 8, 3), - (11, 6, 3, 4, 12, 15, 14, 2, 7, 13, 8, 0, 5, 10, 9, 1), - (1, 12, 11, 0, 15, 14, 6, 5, 10, 13, 4, 8, 9, 3, 7, 2), - (1, 5, 14, 12, 10, 7, 0, 13, 6, 2, 11, 4, 9, 3, 15, 8), - (0, 12, 8, 9, 13, 2, 10, 11, 7, 3, 6, 5, 4, 14, 15, 1), - (8, 0, 15, 3, 2, 5, 14, 11, 1, 10, 4, 7, 12, 9, 13, 6), - (3, 0, 6, 15, 1, 14, 9, 2, 13, 8, 12, 4, 11, 10, 5, 7), - (1, 10, 6, 8, 15, 11, 0, 4, 12, 3, 5, 9, 7, 13, 2, 14), - ), - "id-tc26-gost-28147-param-Z": ( - (12, 4, 6, 2, 10, 5, 11, 9, 14, 8, 13, 7, 0, 3, 15, 1), - (6, 8, 2, 3, 9, 10, 5, 12, 1, 14, 4, 7, 11, 13, 0, 15), - (11, 3, 5, 8, 2, 15, 10, 13, 14, 1, 7, 4, 12, 9, 6, 0), - (12, 8, 2, 1, 13, 4, 15, 6, 7, 0, 10, 5, 3, 14, 9, 11), - (7, 15, 5, 10, 8, 1, 6, 13, 0, 9, 3, 14, 11, 4, 2, 12), - (5, 13, 15, 6, 9, 2, 12, 10, 11, 7, 8, 1, 4, 3, 14, 0), - (8, 14, 2, 5, 6, 9, 1, 12, 15, 4, 11, 0, 13, 10, 3, 7), - (1, 7, 14, 13, 0, 5, 8, 3, 4, 15, 10, 6, 9, 12, 11, 2), - ), - "id-GostR3411-94-TestParamSet": ( - (4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3), - (14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9), - (5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11), - (7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3), - (6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2), - (4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14), - (13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12), - (1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12), - ), - "id-GostR3411-94-CryptoProParamSet": ( - (10, 4, 5, 6, 8, 1, 3, 7, 13, 12, 14, 0, 9, 2, 11, 15), - (5, 15, 4, 0, 2, 13, 11, 9, 1, 7, 6, 3, 12, 14, 10, 8), - (7, 15, 12, 14, 9, 4, 1, 0, 3, 11, 5, 2, 6, 10, 8, 13), - (4, 10, 7, 12, 0, 15, 2, 8, 14, 1, 6, 5, 13, 11, 9, 3), - (7, 6, 4, 11, 9, 12, 2, 10, 1, 8, 0, 14, 15, 13, 3, 5), - (7, 6, 2, 4, 13, 9, 15, 0, 10, 1, 5, 11, 8, 14, 12, 3), - (13, 14, 4, 1, 7, 0, 5, 10, 3, 12, 8, 15, 6, 2, 9, 11), - (1, 3, 10, 9, 5, 11, 4, 15, 8, 6, 7, 14, 13, 0, 2, 12), - ), - "EACParamSet": ( - (11, 4, 8, 10, 9, 7, 0, 3, 1, 6, 2, 15, 14, 5, 12, 13), - (1, 7, 14, 9, 11, 3, 15, 12, 0, 5, 4, 6, 13, 10, 8, 2), - (7, 3, 1, 9, 2, 4, 13, 15, 8, 10, 12, 6, 5, 0, 11, 14), - (10, 5, 15, 7, 14, 11, 3, 9, 2, 8, 1, 12, 0, 4, 6, 13), - (0, 14, 6, 11, 9, 3, 8, 4, 12, 15, 10, 5, 13, 7, 1, 2), - (9, 2, 11, 12, 0, 4, 5, 6, 3, 15, 13, 8, 1, 7, 14, 10), - (4, 0, 14, 1, 5, 11, 8, 3, 12, 2, 9, 7, 6, 10, 13, 15), - (7, 14, 12, 13, 9, 4, 8, 15, 10, 2, 6, 0, 3, 11, 5, 1), - ), -} -SBOXES["AppliedCryptography"] = SBOXES["id-GostR3411-94-TestParamSet"] - - -def _K(s, _in): - """S-box substitution - - :param s: S-box - :param _in: 32-bit word - :returns: substituted 32-bit word - """ - return ( - (s[0][(_in >> 0) & 0x0F] << 0) + - (s[1][(_in >> 4) & 0x0F] << 4) + - (s[2][(_in >> 8) & 0x0F] << 8) + - (s[3][(_in >> 12) & 0x0F] << 12) + - (s[4][(_in >> 16) & 0x0F] << 16) + - (s[5][(_in >> 20) & 0x0F] << 20) + - (s[6][(_in >> 24) & 0x0F] << 24) + - (s[7][(_in >> 28) & 0x0F] << 28) - ) - - -def block2ns(data): - """Convert block to N1 and N2 integers - """ - data = bytearray(data) - return ( - data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24, - data[4] | data[5] << 8 | data[6] << 16 | data[7] << 24, - ) - - -def ns2block(ns): - """Convert N1 and N2 integers to 8-byte block - """ - n1, n2 = ns - return bytes(bytearray(( - (n2 >> 0) & 0xFF, (n2 >> 8) & 0xFF, (n2 >> 16) & 0xFF, (n2 >> 24) & 0xFF, - (n1 >> 0) & 0xFF, (n1 >> 8) & 0xFF, (n1 >> 16) & 0xFF, (n1 >> 24) & 0xFF, - ))) - - -def _shift11(x): - """11-bit cyclic shift - """ - return ((x << 11) & (2 ** 32 - 1)) | ((x >> (32 - 11)) & (2 ** 32 - 1)) - - -def validate_key(key): - if len(key) != KEYSIZE: - raise ValueError("Invalid key size") - - -def validate_iv(iv): - if len(iv) != BLOCKSIZE: - raise ValueError("Invalid IV size") - - -def validate_sbox(sbox): - if sbox not in SBOXES: - raise ValueError("Unknown sbox supplied") - - -def xcrypt(seq, sbox, key, ns): - """Perform full-round single-block operation - - :param seq: sequence of K_i S-box applying (either encrypt or decrypt) - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bytes key: 256-bit encryption key - :param ns: N1 and N2 integers - :type ns: (int, int) - :returns: resulting N1 and N2 - :rtype: (int, int) - """ - s = SBOXES[sbox] - w = bytearray(key) - x = [ - w[0 + i * 4] | - w[1 + i * 4] << 8 | - w[2 + i * 4] << 16 | - w[3 + i * 4] << 24 for i in range(8) - ] - n1, n2 = ns - for i in seq: - n1, n2 = _shift11(_K(s, (n1 + x[i]) % (2 ** 32))) ^ n2, n1 - return n1, n2 - - -def encrypt(sbox, key, ns): - """Encrypt single block - """ - return xcrypt(SEQ_ENCRYPT, sbox, key, ns) - - -def decrypt(sbox, key, ns): - """Decrypt single block - """ - return xcrypt(SEQ_DECRYPT, sbox, key, ns) - - -def ecb(key, data, action, sbox=DEFAULT_SBOX): - """ECB mode of operation - - :param bytes key: encryption key - :param data: plaintext - :type data: bytes, multiple of BLOCKSIZE - :param func action: "encrypt"/"decrypt" - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :returns: ciphertext - :rtype: bytes - """ - validate_key(key) - validate_sbox(sbox) - if not data or len(data) % BLOCKSIZE != 0: - raise ValueError("Data is not blocksize aligned") - result = [] - for i in xrange(0, len(data), BLOCKSIZE): - result.append(ns2block(action( - sbox, key, block2ns(data[i:i + BLOCKSIZE]) - ))) - return b"".join(result) - - -ecb_encrypt = partial(ecb, action=encrypt) -ecb_decrypt = partial(ecb, action=decrypt) - - -def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX, mesh=False): - """CBC encryption mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :type bool pad: perform ISO/IEC 7816-4 padding - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: ciphertext - :rtype: bytes - - 34.13-2015 padding method 2 is used. - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - if pad: - data = pad2(data, BLOCKSIZE) - if len(data) % BLOCKSIZE != 0: - raise ValueError("Data is not blocksize aligned") - ciphertext = [iv] - for i in xrange(0, len(data), BLOCKSIZE): - if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0: - key, _ = meshing(key, iv, sbox=sbox) - ciphertext.append(ns2block(encrypt(sbox, key, block2ns( - strxor(ciphertext[-1], data[i:i + BLOCKSIZE]) - )))) - return b"".join(ciphertext) - - -def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX, mesh=False): - """CBC decryption mode of operation - - :param bytes key: encryption key - :param bytes data: ciphertext - :type bool pad: perform ISO/IEC 7816-4 unpadding after decryption - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: plaintext - :rtype: bytes - """ - validate_key(key) - validate_sbox(sbox) - if not data or len(data) % BLOCKSIZE != 0: - raise ValueError("Data is not blocksize aligned") - if len(data) < 2 * BLOCKSIZE: - raise ValueError("There is no either data, or IV in ciphertext") - iv = data[:BLOCKSIZE] - plaintext = [] - for i in xrange(BLOCKSIZE, len(data), BLOCKSIZE): - if ( - mesh and - (i - BLOCKSIZE) >= MESH_MAX_DATA and - (i - BLOCKSIZE) % MESH_MAX_DATA == 0 - ): - key, _ = meshing(key, iv, sbox=sbox) - plaintext.append(strxor( - ns2block(decrypt(sbox, key, block2ns(data[i:i + BLOCKSIZE]))), - data[i - BLOCKSIZE:i], - )) - if pad: - plaintext[-1] = unpad2(plaintext[-1], BLOCKSIZE) - return b"".join(plaintext) - - -def cnt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX): - """Counter mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :returns: ciphertext - :rtype: bytes - - For decryption you use the same function again. - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - n2, n1 = encrypt(sbox, key, block2ns(iv)) - gamma = [] - for _ in xrange(0, len(data) + pad_size(len(data), BLOCKSIZE), BLOCKSIZE): - n1 = (n1 + C2) % (2 ** 32) - n2 = (n2 + C1) % (2 ** 32 - 1) - gamma.append(ns2block(encrypt(sbox, key, (n1, n2)))) - return strxor(b"".join(gamma), data) - - -MESH_CONST = hexdec("6900722264C904238D3ADB9646E92AC418FEAC9400ED0712C086DCC2EF4CA92B") -MESH_MAX_DATA = 1024 - - -def meshing(key, iv, sbox=DEFAULT_SBOX): - """:rfc:`4357` key meshing - """ - key = ecb_decrypt(key, MESH_CONST, sbox=sbox) - iv = ecb_encrypt(key, iv, sbox=sbox) - return key, iv - - -def cfb_encrypt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX, mesh=False): - """CFB encryption mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: ciphertext - :rtype: bytes - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - ciphertext = [iv] - for i in xrange(0, len(data) + pad_size(len(data), BLOCKSIZE), BLOCKSIZE): - if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0: - key, iv = meshing(key, ciphertext[-1], sbox=sbox) - ciphertext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(iv))), - )) - continue - ciphertext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(ciphertext[-1]))), - )) - return b"".join(ciphertext[1:]) - - -def cfb_decrypt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX, mesh=False): - """CFB decryption mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: ciphertext - :rtype: bytes - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - plaintext = [] - data = iv + data - for i in xrange(BLOCKSIZE, len(data) + pad_size(len(data), BLOCKSIZE), BLOCKSIZE): - if ( - mesh and - (i - BLOCKSIZE) >= MESH_MAX_DATA and - (i - BLOCKSIZE) % MESH_MAX_DATA == 0 - ): - key, iv = meshing(key, data[i - BLOCKSIZE:i], sbox=sbox) - plaintext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(iv))), - )) - continue - plaintext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(data[i - BLOCKSIZE:i]))), - )) - return b"".join(plaintext) diff --git a/pygost-5.13/build/lib/pygost/gost28147_mac.py b/pygost-5.13/build/lib/pygost/gost28147_mac.py deleted file mode 100644 index aab2805..0000000 --- a/pygost-5.13/build/lib/pygost/gost28147_mac.py +++ /dev/null @@ -1,99 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST 28147-89 MAC -""" - -from copy import copy - -from pygost.gost28147 import block2ns -from pygost.gost28147 import BLOCKSIZE -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost28147 import ns2block -from pygost.gost28147 import validate_iv -from pygost.gost28147 import validate_key -from pygost.gost28147 import validate_sbox -from pygost.gost28147 import xcrypt -from pygost.gost3413 import pad1 -from pygost.iface import PEP247 -from pygost.utils import strxor -from pygost.utils import xrange - -digest_size = 8 -SEQ_MAC = ( - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, -) - - -class MAC(PEP247): - """GOST 28147-89 MAC mode of operation - - >>> m = MAC(key=key) - >>> m.update("some data") - >>> m.update("another data") - >>> m.hexdigest()[:8] - 'a687a08b' - """ - digest_size = digest_size - - def __init__(self, key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX): - """ - :param key: authentication key - :type key: bytes, 32 bytes - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - self.key = key - self.data = data - self.iv = iv - self.sbox = sbox - - def copy(self): - return MAC(self.key, copy(self.data), self.iv, self.sbox) - - def update(self, data): - """Append data that has to be authenticated - """ - self.data += data - - def digest(self): - """Get MAC tag of supplied data - - You have to provide at least single byte of data. - If you want to produce tag length of 3 bytes, then - ``digest()[:3]``. - """ - if not self.data: - raise ValueError("No data processed") - data = pad1(self.data, BLOCKSIZE) - prev = block2ns(self.iv)[::-1] - for i in xrange(0, len(data), BLOCKSIZE): - prev = xcrypt( - SEQ_MAC, self.sbox, self.key, block2ns(strxor( - data[i:i + BLOCKSIZE], - ns2block(prev), - )), - )[::-1] - return ns2block(prev) - - -def new(key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX): - return MAC(key, data, iv, sbox) diff --git a/pygost-5.13/build/lib/pygost/gost3410.py b/pygost-5.13/build/lib/pygost/gost3410.py deleted file mode 100644 index c12b170..0000000 --- a/pygost-5.13/build/lib/pygost/gost3410.py +++ /dev/null @@ -1,412 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.10 public-key signature function. - -This is implementation of GOST R 34.10-2001 (:rfc:`5832`), GOST R -34.10-2012 (:rfc:`7091`). The difference between 2001 and 2012 is the -key, digest and signature lengths. -""" - -from os import urandom - -from pygost.utils import bytes2long -from pygost.utils import hexdec -from pygost.utils import long2bytes -from pygost.utils import modinvert - - -def point_size(point): - """Determine is it either 256 or 512 bit point - """ - return (512 // 8) if point.bit_length() > 256 else (256 // 8) - - -class GOST3410Curve(object): - """GOST 34.10 validated curve - - >>> curve = CURVES["id-GostR3410-2001-TestParamSet"] - >>> prv = prv_unmarshal(urandom(32)) - >>> signature = sign(curve, prv, GOST341194(data).digest()) - >>> pub = public_key(curve, prv) - >>> verify(curve, pub, GOST341194(data).digest(), signature) - True - - :param long p: characteristic of the underlying prime field - :param long q: elliptic curve subgroup order - :param long a, b: coefficients of the equation of the elliptic curve in - the canonical form - :param long x, y: the coordinate of the point P (generator of the - subgroup of order q) of the elliptic curve in - the canonical form - :param long e, d: coefficients of the equation of the elliptic curve in - the twisted Edwards form - :param str name: human-readable curve name - """ - - def __init__(self, p, q, a, b, x, y, cofactor=1, e=None, d=None, name=None): - self.p = p - self.q = q - self.a = a - self.b = b - self.x = x - self.y = y - self.cofactor = cofactor - self.e = e - self.d = d - if not self.contains((x, y)): - raise ValueError("Invalid parameters") - self._st = None - self.name = name - - @property - def point_size(self): - return point_size(self.p) - - def __repr__(self): - return "<%s: %s>" % (self.__class__.__name__, self.name) - - def pos(self, v): - """Make positive number - """ - if v < 0: - return v + self.p - return v - - def contains(self, point): - """Is point on the curve? - - :type point: (long, long) - """ - x, y = point - r1 = y * y % self.p - r2 = ((x * x + self.a) * x + self.b) % self.p - return r1 == self.pos(r2) - - def _add(self, p1x, p1y, p2x, p2y): - if p1x == p2x and p1y == p2y: - # double - t = ((3 * p1x * p1x + self.a) * modinvert(2 * p1y, self.p)) % self.p - else: - tx = self.pos(p2x - p1x) % self.p - ty = self.pos(p2y - p1y) % self.p - t = (ty * modinvert(tx, self.p)) % self.p - tx = self.pos(t * t - p1x - p2x) % self.p - ty = self.pos(t * (p1x - tx) - p1y) % self.p - return tx, ty - - def exp(self, degree, x=None, y=None): - x = x or self.x - y = y or self.y - tx = x - ty = y - if degree == 0: - raise ValueError("Bad degree value") - degree -= 1 - while degree != 0: - if degree & 1 == 1: - tx, ty = self._add(tx, ty, x, y) - degree = degree >> 1 - x, y = self._add(x, y, x, y) - return tx, ty - - def st(self): - """Compute s/t parameters for twisted Edwards curve points conversion - """ - if self.e is None or self.d is None: - raise ValueError("Non twisted Edwards curve") - if self._st is not None: - return self._st - self._st = ( - self.pos(self.e - self.d) * modinvert(4, self.p) % self.p, - (self.e + self.d) * modinvert(6, self.p) % self.p, - ) - return self._st - - -CURVES = { - "GostR3410_2001_ParamSet_cc": GOST3410Curve( - p=bytes2long(hexdec("C0000000000000000000000000000000000000000000000000000000000003C7")), - q=bytes2long(hexdec("5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85")), - a=bytes2long(hexdec("C0000000000000000000000000000000000000000000000000000000000003c4")), - b=bytes2long(hexdec("2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000002")), - y=bytes2long(hexdec("a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c")), - ), - "id-GostR3410-2001-TestParamSet": GOST3410Curve( - p=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000431")), - q=bytes2long(hexdec("8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3")), - a=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000007")), - b=bytes2long(hexdec("5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000002")), - y=bytes2long(hexdec("08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8")), - ), - "id-tc26-gost-3410-12-256-paramSetA": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97")), - q=bytes2long(hexdec("400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67")), - a=bytes2long(hexdec("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335")), - b=bytes2long(hexdec("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513")), - x=bytes2long(hexdec("91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28")), - y=bytes2long(hexdec("32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C")), - cofactor=4, - e=0x01, - d=bytes2long(hexdec("0605F6B7C183FA81578BC39CFAD518132B9DF62897009AF7E522C32D6DC7BFFB")), - ), - "id-tc26-gost-3410-12-256-paramSetB": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97")), - q=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893")), - a=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94")), - b=bytes2long(hexdec("00000000000000000000000000000000000000000000000000000000000000a6")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000001")), - y=bytes2long(hexdec("8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14")), - ), - "id-tc26-gost-3410-12-256-paramSetC": GOST3410Curve( - p=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000C99")), - q=bytes2long(hexdec("800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F")), - a=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000C96")), - b=bytes2long(hexdec("3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000001")), - y=bytes2long(hexdec("3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC")), - ), - "id-tc26-gost-3410-12-256-paramSetD": GOST3410Curve( - p=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B")), - q=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9")), - a=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598")), - b=bytes2long(hexdec("000000000000000000000000000000000000000000000000000000000000805a")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000000")), - y=bytes2long(hexdec("41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67")), - ), - "id-tc26-gost-3410-12-512-paramSetTest": GOST3410Curve( - p=bytes2long(hexdec("4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DF1D852741AF4704A0458047E80E4546D35B8336FAC224DD81664BBF528BE6373")), - q=bytes2long(hexdec("4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DA82F2D7ECB1DBAC719905C5EECC423F1D86E25EDBE23C595D644AAF187E6E6DF")), - a=7, - b=bytes2long(hexdec("1CFF0806A31116DA29D8CFA54E57EB748BC5F377E49400FDD788B649ECA1AC4361834013B2AD7322480A89CA58E0CF74BC9E540C2ADD6897FAD0A3084F302ADC")), - x=bytes2long(hexdec("24D19CC64572EE30F396BF6EBBFD7A6C5213B3B3D7057CC825F91093A68CD762FD60611262CD838DC6B60AA7EEE804E28BC849977FAC33B4B530F1B120248A9A")), - y=bytes2long(hexdec("2BB312A43BD2CE6E0D020613C857ACDDCFBF061E91E5F2C3F32447C259F39B2C83AB156D77F1496BF7EB3351E1EE4E43DC1A18B91B24640B6DBB92CB1ADD371E")), - ), - "id-tc26-gost-3410-12-512-paramSetA": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7")), - q=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275")), - a=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4")), - b=bytes2long(hexdec("E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760")), - x=bytes2long(hexdec("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003")), - y=bytes2long(hexdec("7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4")), - ), - "id-tc26-gost-3410-12-512-paramSetB": GOST3410Curve( - p=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F")), - q=bytes2long(hexdec("800000000000000000000000000000000000000000000000000000000000000149A1EC142565A545ACFDB77BD9D40CFA8B996712101BEA0EC6346C54374F25BD")), - a=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C")), - b=bytes2long(hexdec("687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116")), - x=bytes2long(hexdec("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002")), - y=bytes2long(hexdec("1A8F7EDA389B094C2C071E3647A8940F3C123B697578C213BE6DD9E6C8EC7335DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD")), - ), - "id-tc26-gost-3410-12-512-paramSetC": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7")), - q=bytes2long(hexdec("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC98CDBA46506AB004C33A9FF5147502CC8EDA9E7A769A12694623CEF47F023ED")), - a=bytes2long(hexdec("DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3")), - b=bytes2long(hexdec("B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1")), - x=bytes2long(hexdec("E2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043AA27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148")), - y=bytes2long(hexdec("F5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9BE18E2D33E3021ED2EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F")), - cofactor=4, - e=0x01, - d=bytes2long(hexdec("9E4F5D8C017D8D9F13A5CF3CDF5BFE4DAB402D54198E31EBDE28A0621050439CA6B39E0A515C06B304E2CE43E79E369E91A0CFC2BC2A22B4CA302DBB33EE7550")), - ), -} -CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetB"] -CURVES["id-GostR3410-2001-CryptoPro-B-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetC"] -CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetD"] -CURVES["id-GostR3410-2001-CryptoPro-XchA-ParamSet"] = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] -CURVES["id-GostR3410-2001-CryptoPro-XchB-ParamSet"] = CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"] -CURVES["id-tc26-gost-3410-2012-256-paramSetA"] = CURVES["id-tc26-gost-3410-12-256-paramSetA"] -CURVES["id-tc26-gost-3410-2012-256-paramSetB"] = CURVES["id-tc26-gost-3410-12-256-paramSetB"] -CURVES["id-tc26-gost-3410-2012-256-paramSetC"] = CURVES["id-tc26-gost-3410-12-256-paramSetC"] -CURVES["id-tc26-gost-3410-2012-256-paramSetD"] = CURVES["id-tc26-gost-3410-12-256-paramSetD"] -CURVES["id-tc26-gost-3410-2012-512-paramSetTest"] = CURVES["id-tc26-gost-3410-12-512-paramSetTest"] -CURVES["id-tc26-gost-3410-2012-512-paramSetA"] = CURVES["id-tc26-gost-3410-12-512-paramSetA"] -CURVES["id-tc26-gost-3410-2012-512-paramSetB"] = CURVES["id-tc26-gost-3410-12-512-paramSetB"] -CURVES["id-tc26-gost-3410-2012-512-paramSetC"] = CURVES["id-tc26-gost-3410-12-512-paramSetC"] -for _name, _curve in CURVES.items(): - _curve.name = _name -DEFAULT_CURVE = CURVES["id-tc26-gost-3410-12-256-paramSetB"] - - -def public_key(curve, prv, mask=None): - """Generate public key from the private one - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :returns: public key's parts, X and Y - :rtype: (long, long) - """ - pub = curve.exp(prv) - if mask is not None: - pub = curve.exp(mask, pub[0], pub[1]) - return pub - - -def sign(curve, prv, digest, rand=None, mask=None): - """Calculate signature for provided digest - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param digest: digest for signing - :type digest: bytes, 32 or 64 bytes - :param rand: optional predefined random data used for k/r generation - :type rand: bytes, 32 or 64 bytes - :returns: signature, BE(S) || BE(R) - :rtype: bytes, 64 or 128 bytes - """ - size = curve.point_size - q = curve.q - e = bytes2long(digest) % q - if e == 0: - e = 1 - while True: - if rand is None: - rand = urandom(size) - elif len(rand) != size: - raise ValueError("rand length != %d" % size) - k = bytes2long(rand) % q - if k == 0: - continue - r, y = curve.exp(k) - if mask is not None: - r, y = curve.exp(mask, x=r, y=y) - r %= q - if r == 0: - continue - d = prv * r - k *= e - s = d + k - if mask is not None: - s *= mask - s %= q - if s == 0: - continue - break - return long2bytes(s, size) + long2bytes(r, size) - - -def verify(curve, pub, digest, signature): - """Verify provided digest with the signature - - :param GOST3410Curve curve: curve to use - :type pub: (long, long) - :param digest: digest needed to check - :type digest: bytes, 32 or 64 bytes - :param signature: signature to verify with - :type signature: bytes, 64 or 128 bytes - :rtype: bool - """ - size = curve.point_size - if len(signature) != size * 2: - raise ValueError("Invalid signature length") - q = curve.q - p = curve.p - s = bytes2long(signature[:size]) - r = bytes2long(signature[size:]) - if r <= 0 or r >= q or s <= 0 or s >= q: - return False - e = bytes2long(digest) % curve.q - if e == 0: - e = 1 - v = modinvert(e, q) - z1 = s * v % q - z2 = q - r * v % q - p1x, p1y = curve.exp(z1) - q1x, q1y = curve.exp(z2, pub[0], pub[1]) - lm = q1x - p1x - if lm < 0: - lm += p - lm = modinvert(lm, p) - z1 = q1y - p1y - lm = lm * z1 % p - lm = lm * lm % p - lm = lm - p1x - q1x - lm = lm % p - if lm < 0: - lm += p - lm %= q - # This is not constant time comparison! - return lm == r - - -def prv_unmarshal(prv): - """Unmarshal little-endian private key - - :param bytes prv: serialized private key - :rtype: long - - It is advisable to use :py:func:`pygost.gost3410.prv_marshal` to - assure that key i in curve's Q field for better compatibility with - some implementations. - """ - return bytes2long(prv[::-1]) - - -def prv_marshal(curve, prv): - """Marshal little-endian private key - - :param GOST3410Curve curve: curve to use - :param long prv: serialized private key - :rtype: bytes - - Key is in curve's Q field. - """ - return long2bytes(prv % curve.q, point_size(prv))[::-1] - - -def pub_marshal(pub): - """Marshal public key - - :type pub: (long, long) - :rtype: bytes - :returns: LE(X) || LE(Y) - """ - size = point_size(pub[0]) - return (long2bytes(pub[1], size) + long2bytes(pub[0], size))[::-1] - - -def pub_unmarshal(pub): - """Unmarshal public key - - :param pub: LE(X) || LE(Y) - :type pub: bytes - :rtype: (long, long) - """ - size = len(pub) // 2 - pub = pub[::-1] - return (bytes2long(pub[size:]), bytes2long(pub[:size])) - - -def uv2xy(curve, u, v): - """Convert twisted Edwards curve U,V coordinates to Weierstrass X,Y - """ - s, t = curve.st() - k1 = (s * (1 + v)) % curve.p - k2 = curve.pos(1 - v) - x = t + k1 * modinvert(k2, curve.p) - y = k1 * modinvert(u * k2, curve.p) - return x % curve.p, y % curve.p - - -def xy2uv(curve, x, y): - """Convert Weierstrass X,Y coordinates to twisted Edwards curve U,V - """ - s, t = curve.st() - xmt = curve.pos(x - t) - u = xmt * modinvert(y, curve.p) - v = curve.pos(xmt - s) * modinvert(xmt + s, curve.p) - return u % curve.p, v % curve.p diff --git a/pygost-5.13/build/lib/pygost/gost3410_vko.py b/pygost-5.13/build/lib/pygost/gost3410_vko.py deleted file mode 100644 index 3f169dc..0000000 --- a/pygost-5.13/build/lib/pygost/gost3410_vko.py +++ /dev/null @@ -1,97 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Key agreement functions, VKO GOST R 34.10-2001/2012 -""" - -from pygost.gost3410 import pub_marshal -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost341194 import GOST341194 -from pygost.utils import bytes2long - - -def ukm_unmarshal(ukm): - """Unmarshal UKM value - - :type ukm: little-endian bytes - :rtype: long - """ - return bytes2long(ukm[::-1]) - - -def kek(curve, prv, pub, ukm, mask=None): - if not curve.contains(pub): - raise ValueError("pub is not on the curve") - key = curve.exp(prv, pub[0], pub[1]) - key = curve.exp(curve.cofactor * ukm, key[0], key[1]) - if mask is not None: - key = curve.exp(mask, key[0], key[1]) - return pub_marshal(key) - - -def kek_34102001(curve, prv, pub, ukm): - """Key agreement (34.10-2001, 34.11-94) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param long ukm: user keying material, VKO-factor - :returns: Key Encryption Key (shared key) - :rtype: bytes, 32 bytes - - Shared Key Encryption Key computation is based on - :rfc:`4357` VKO GOST R 34.10-2001 with little-endian - hash output. - """ - return GOST341194( - kek(curve, prv, pub, ukm), - sbox="id-GostR3411-94-CryptoProParamSet", - ).digest() - - -def kek_34102012256(curve, prv, pub, ukm=1): - """Key agreement (34.10-2012, 34.11-2012 256 bit) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param long ukm: user keying material, VKO-factor - :returns: Key Encryption Key (shared key) - :rtype: bytes, 32 bytes - - Shared Key Encryption Key computation is based on - :rfc:`7836` VKO GOST R 34.10-2012. - """ - return GOST34112012256(kek(curve, prv, pub, ukm)).digest() - - -def kek_34102012512(curve, prv, pub, ukm=1): - """Key agreement (34.10-2012, 34.11-2012 512 bit) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param long ukm: user keying material, VKO-factor - :returns: Key Encryption Key (shared key) - :rtype: bytes, 32 bytes - - Shared Key Encryption Key computation is based on - :rfc:`7836` VKO GOST R 34.10-2012. - """ - return GOST34112012512(kek(curve, prv, pub, ukm)).digest() diff --git a/pygost-5.13/build/lib/pygost/gost34112012.py b/pygost-5.13/build/lib/pygost/gost34112012.py deleted file mode 100644 index 91782de..0000000 --- a/pygost-5.13/build/lib/pygost/gost34112012.py +++ /dev/null @@ -1,299 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.11-2012 (Streebog) hash function common files - -This is implementation of :rfc:`6986`. Most function and variable names are -taken according to specification's terminology. -""" - -from copy import copy -from struct import pack -from struct import unpack - -from pygost.iface import PEP247 -from pygost.utils import hexdec -from pygost.utils import strxor -from pygost.utils import xrange - - -BLOCKSIZE = 64 -Pi = bytearray(( - 252, 238, 221, 17, 207, 110, 49, 22, 251, 196, 250, - 218, 35, 197, 4, 77, 233, 119, 240, 219, 147, 46, - 153, 186, 23, 54, 241, 187, 20, 205, 95, 193, 249, - 24, 101, 90, 226, 92, 239, 33, 129, 28, 60, 66, - 139, 1, 142, 79, 5, 132, 2, 174, 227, 106, 143, - 160, 6, 11, 237, 152, 127, 212, 211, 31, 235, 52, - 44, 81, 234, 200, 72, 171, 242, 42, 104, 162, 253, - 58, 206, 204, 181, 112, 14, 86, 8, 12, 118, 18, - 191, 114, 19, 71, 156, 183, 93, 135, 21, 161, 150, - 41, 16, 123, 154, 199, 243, 145, 120, 111, 157, 158, - 178, 177, 50, 117, 25, 61, 255, 53, 138, 126, 109, - 84, 198, 128, 195, 189, 13, 87, 223, 245, 36, 169, - 62, 168, 67, 201, 215, 121, 214, 246, 124, 34, 185, - 3, 224, 15, 236, 222, 122, 148, 176, 188, 220, 232, - 40, 80, 78, 51, 10, 74, 167, 151, 96, 115, 30, - 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65, - 173, 69, 70, 146, 39, 94, 85, 47, 140, 163, 165, - 125, 105, 213, 149, 59, 7, 88, 179, 64, 134, 172, - 29, 247, 48, 55, 107, 228, 136, 217, 231, 137, 225, - 27, 131, 73, 76, 63, 248, 254, 141, 83, 170, 144, - 202, 216, 133, 97, 32, 113, 103, 164, 45, 43, 9, - 91, 203, 155, 37, 208, 190, 229, 108, 82, 89, 166, - 116, 210, 230, 244, 180, 192, 209, 102, 175, 194, 57, - 75, 99, 182, -)) - -A = [unpack(">Q", hexdec(s))[0] for s in ( - "8e20faa72ba0b470", "47107ddd9b505a38", "ad08b0e0c3282d1c", "d8045870ef14980e", - "6c022c38f90a4c07", "3601161cf205268d", "1b8e0b0e798c13c8", "83478b07b2468764", - "a011d380818e8f40", "5086e740ce47c920", "2843fd2067adea10", "14aff010bdd87508", - "0ad97808d06cb404", "05e23c0468365a02", "8c711e02341b2d01", "46b60f011a83988e", - "90dab52a387ae76f", "486dd4151c3dfdb9", "24b86a840e90f0d2", "125c354207487869", - "092e94218d243cba", "8a174a9ec8121e5d", "4585254f64090fa0", "accc9ca9328a8950", - "9d4df05d5f661451", "c0a878a0a1330aa6", "60543c50de970553", "302a1e286fc58ca7", - "18150f14b9ec46dd", "0c84890ad27623e0", "0642ca05693b9f70", "0321658cba93c138", - "86275df09ce8aaa8", "439da0784e745554", "afc0503c273aa42a", "d960281e9d1d5215", - "e230140fc0802984", "71180a8960409a42", "b60c05ca30204d21", "5b068c651810a89e", - "456c34887a3805b9", "ac361a443d1c8cd2", "561b0d22900e4669", "2b838811480723ba", - "9bcf4486248d9f5d", "c3e9224312c8c1a0", "effa11af0964ee50", "f97d86d98a327728", - "e4fa2054a80b329c", "727d102a548b194e", "39b008152acb8227", "9258048415eb419d", - "492c024284fbaec0", "aa16012142f35760", "550b8e9e21f7a530", "a48b474f9ef5dc18", - "70a6a56e2440598e", "3853dc371220a247", "1ca76e95091051ad", "0edd37c48a08a6d8", - "07e095624504536c", "8d70c431ac02a736", "c83862965601dd1b", "641c314b2b8ee083", -)] - -Tau = ( - 0, 8, 16, 24, 32, 40, 48, 56, - 1, 9, 17, 25, 33, 41, 49, 57, - 2, 10, 18, 26, 34, 42, 50, 58, - 3, 11, 19, 27, 35, 43, 51, 59, - 4, 12, 20, 28, 36, 44, 52, 60, - 5, 13, 21, 29, 37, 45, 53, 61, - 6, 14, 22, 30, 38, 46, 54, 62, - 7, 15, 23, 31, 39, 47, 55, 63, -) - -C = [hexdec("".join(s))[::-1] for s in ( - ( - "b1085bda1ecadae9ebcb2f81c0657c1f", - "2f6a76432e45d016714eb88d7585c4fc", - "4b7ce09192676901a2422a08a460d315", - "05767436cc744d23dd806559f2a64507", - ), - ( - "6fa3b58aa99d2f1a4fe39d460f70b5d7", - "f3feea720a232b9861d55e0f16b50131", - "9ab5176b12d699585cb561c2db0aa7ca", - "55dda21bd7cbcd56e679047021b19bb7", - ), - ( - "f574dcac2bce2fc70a39fc286a3d8435", - "06f15e5f529c1f8bf2ea7514b1297b7b", - "d3e20fe490359eb1c1c93a376062db09", - "c2b6f443867adb31991e96f50aba0ab2", - ), - ( - "ef1fdfb3e81566d2f948e1a05d71e4dd", - "488e857e335c3c7d9d721cad685e353f", - "a9d72c82ed03d675d8b71333935203be", - "3453eaa193e837f1220cbebc84e3d12e", - ), - ( - "4bea6bacad4747999a3f410c6ca92363", - "7f151c1f1686104a359e35d7800fffbd", - "bfcd1747253af5a3dfff00b723271a16", - "7a56a27ea9ea63f5601758fd7c6cfe57", - ), - ( - "ae4faeae1d3ad3d96fa4c33b7a3039c0", - "2d66c4f95142a46c187f9ab49af08ec6", - "cffaa6b71c9ab7b40af21f66c2bec6b6", - "bf71c57236904f35fa68407a46647d6e", - ), - ( - "f4c70e16eeaac5ec51ac86febf240954", - "399ec6c7e6bf87c9d3473e33197a93c9", - "0992abc52d822c3706476983284a0504", - "3517454ca23c4af38886564d3a14d493", - ), - ( - "9b1f5b424d93c9a703e7aa020c6e4141", - "4eb7f8719c36de1e89b4443b4ddbc49a", - "f4892bcb929b069069d18d2bd1a5c42f", - "36acc2355951a8d9a47f0dd4bf02e71e", - ), - ( - "378f5a541631229b944c9ad8ec165fde", - "3a7d3a1b258942243cd955b7e00d0984", - "800a440bdbb2ceb17b2b8a9aa6079c54", - "0e38dc92cb1f2a607261445183235adb", - ), - ( - "abbedea680056f52382ae548b2e4f3f3", - "8941e71cff8a78db1fffe18a1b336103", - "9fe76702af69334b7a1e6c303b7652f4", - "3698fad1153bb6c374b4c7fb98459ced", - ), - ( - "7bcd9ed0efc889fb3002c6cd635afe94", - "d8fa6bbbebab07612001802114846679", - "8a1d71efea48b9caefbacd1d7d476e98", - "dea2594ac06fd85d6bcaa4cd81f32d1b", - ), - ( - "378ee767f11631bad21380b00449b17a", - "cda43c32bcdf1d77f82012d430219f9b", - "5d80ef9d1891cc86e71da4aa88e12852", - "faf417d5d9b21b9948bc924af11bd720", - ), -)] - - -def _lcache(): - cache = [] - for byteN in xrange(8): - cache.append([0 for _ in xrange(256)]) - for byteN in xrange(8): - for byteVal in xrange(256): - res64 = 0 - val = byteVal - for bitN in xrange(8): - if val & 0x80 > 0: - res64 ^= A[(7 - byteN) * 8 + bitN] - val <<= 1 - cache[byteN][byteVal] = res64 - return cache - - -# Trade memory for CPU for part of L() calculations -LCache = _lcache() - - -def add512bit(a, b): - a = int.from_bytes(a, "little") - b = int.from_bytes(b, "little") - r = (a + b) % (1 << 512) - return r.to_bytes(512 // 8, "little") - - -def g(n, hsh, msg): - res = E(LPS(strxor(hsh[:8], pack(">> m = GOST34112012(digest_size=32) - >>> m.update("foo") - >>> m.update("bar") - >>> m.hexdigest() - 'e3c9fd89226d93b489a9fe27d686806e24a514e3787bca053c698ec4616ceb78' - """ - block_size = BLOCKSIZE - - def __init__(self, data=b"", digest_size=64): - """ - :param digest_size: hash digest size to compute - :type digest_size: 32 or 64 bytes - """ - self._digest_size = digest_size - self.hsh = BLOCKSIZE * (b"\x01" if digest_size == 32 else b"\x00") - self.chk = bytearray(BLOCKSIZE * b"\x00") - self.n = 0 - self.buf = b"" - self.update(data) - - def copy(self): - obj = GOST34112012() - obj._digest_size = self._digest_size - obj.hsh = self.hsh - obj.chk = copy(self.chk) - obj.n = self.n - obj.buf = self.buf - return obj - - @property - def digest_size(self): - return self._digest_size - - def _update_block(self, block): - self.hsh = g(self.n, self.hsh, block) - self.chk = add512bit(self.chk, block) - self.n += 512 - - def update(self, data): - """Update state with the new data - """ - if len(self.buf) > 0: - chunk_len = BLOCKSIZE - len(self.buf) - self.buf += data[:chunk_len] - data = data[chunk_len:] - if len(self.buf) == BLOCKSIZE: - self._update_block(self.buf) - self.buf = b"" - while len(data) >= BLOCKSIZE: - self._update_block(data[:BLOCKSIZE]) - data = data[BLOCKSIZE:] - self.buf += data - - def digest(self): - """Get hash of the provided data - """ - data = self.buf - - # Padding - padblock_size = len(data) * 8 - data += b"\x01" - padlen = BLOCKSIZE - len(data) - if padlen != BLOCKSIZE: - data += b"\x00" * padlen - - hsh = g(self.n, self.hsh, data) - n = self.n + padblock_size - chk = add512bit(self.chk, data) - hsh = g(0, hsh, pack(" -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.11-94 hash function - -This is implementation of :rfc:`5831`. Most function and variable names are -taken according to specification's terminology. -""" - -from copy import copy -from functools import partial -from struct import pack - -from pygost.gost28147 import block2ns -from pygost.gost28147 import encrypt -from pygost.gost28147 import ns2block -from pygost.gost28147 import validate_sbox -from pygost.iface import PEP247 -from pygost.pbkdf2 import pbkdf2 as pbkdf2_base -from pygost.utils import hexdec -from pygost.utils import hexenc -from pygost.utils import strxor -from pygost.utils import xrange - - -DEFAULT_SBOX = "id-GostR3411-94-CryptoProParamSet" -BLOCKSIZE = 32 -C2 = 32 * b"\x00" -C3 = hexdec(b"ff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00") -C4 = 32 * b"\x00" -digest_size = 32 - - -def A(x): - x4, x3, x2, x1 = x[0:8], x[8:16], x[16:24], x[24:32] - return b"".join((strxor(x1, x2), x4, x3, x2)) - - -def P(x): - return bytearray(( - x[0], x[8], x[16], x[24], x[1], x[9], x[17], x[25], x[2], - x[10], x[18], x[26], x[3], x[11], x[19], x[27], x[4], x[12], - x[20], x[28], x[5], x[13], x[21], x[29], x[6], x[14], x[22], - x[30], x[7], x[15], x[23], x[31], - )) - - -def _chi(Y): - """Chi function - - This is some kind of LFSR. - """ - (y16, y15, y14, y13, y12, y11, y10, y9, y8, y7, y6, y5, y4, y3, y2, y1) = ( - Y[0:2], Y[2:4], Y[4:6], Y[6:8], Y[8:10], Y[10:12], Y[12:14], - Y[14:16], Y[16:18], Y[18:20], Y[20:22], Y[22:24], Y[24:26], - Y[26:28], Y[28:30], Y[30:32], - ) - by1, by2, by3, by4, by13, by16, byx = ( - bytearray(y1), bytearray(y2), bytearray(y3), bytearray(y4), - bytearray(y13), bytearray(y16), bytearray(2), - ) - byx[0] = by1[0] ^ by2[0] ^ by3[0] ^ by4[0] ^ by13[0] ^ by16[0] - byx[1] = by1[1] ^ by2[1] ^ by3[1] ^ by4[1] ^ by13[1] ^ by16[1] - return b"".join(( - bytes(byx), y16, y15, y14, y13, y12, y11, y10, y9, y8, y7, y6, y5, y4, y3, y2 - )) - - -def _step(hin, m, sbox): - """Step function - - H_out = f(H_in, m) - """ - # Generate keys - u = hin - v = m - w = strxor(hin, m) - k1 = P(w) - - u = strxor(A(u), C2) - v = A(A(v)) - w = strxor(u, v) - k2 = P(w) - - u = strxor(A(u), C3) - v = A(A(v)) - w = strxor(u, v) - k3 = P(w) - - u = strxor(A(u), C4) - v = A(A(v)) - w = strxor(u, v) - k4 = P(w) - - # Encipher - h4, h3, h2, h1 = hin[0:8], hin[8:16], hin[16:24], hin[24:32] - s1 = ns2block(encrypt(sbox, k1[::-1], block2ns(h1[::-1])))[::-1] - s2 = ns2block(encrypt(sbox, k2[::-1], block2ns(h2[::-1])))[::-1] - s3 = ns2block(encrypt(sbox, k3[::-1], block2ns(h3[::-1])))[::-1] - s4 = ns2block(encrypt(sbox, k4[::-1], block2ns(h4[::-1])))[::-1] - s = b"".join((s4, s3, s2, s1)) - - # Permute - # H_out = chi^61(H_in XOR chi(m XOR chi^12(S))) - x = s - for _ in xrange(12): - x = _chi(x) - x = strxor(x, m) - x = _chi(x) - x = strxor(hin, x) - for _ in xrange(61): - x = _chi(x) - return x - - -class GOST341194(PEP247): - """GOST 34.11-94 big-endian hash - - >>> m = GOST341194() - >>> m.update("foo") - >>> m.update("bar") - >>> m.hexdigest() - '3bd8a3a35917871dfa0d49f9e73e7c57eea028dc061133eb560849ea20c133af' - >>> GOST341194("foobar").hexdigest() - '3bd8a3a35917871dfa0d49f9e73e7c57eea028dc061133eb560849ea20c133af' - """ - block_size = BLOCKSIZE - digest_size = digest_size - - def __init__(self, data=b"", sbox=DEFAULT_SBOX): - """ - :param bytes data: provide initial data - :param bytes sbox: S-box to use - """ - validate_sbox(sbox) - self.data = data - self.sbox = sbox - - def copy(self): - return GOST341194(copy(self.data), self.sbox) - - def update(self, data): - """Append data that has to be hashed - """ - self.data += data - - def digest(self): - """Get hash of the provided data - """ - _len = 0 - checksum = 0 - h = 32 * b"\x00" - m = self.data - for i in xrange(0, len(m), BLOCKSIZE): - part = m[i:i + BLOCKSIZE][::-1] - _len += len(part) * 8 - checksum = (checksum + int(hexenc(part), 16)) % (2 ** 256) - if len(part) < BLOCKSIZE: - part = b"\x00" * (BLOCKSIZE - len(part)) + part - h = _step(h, part, self.sbox) - h = _step(h, 24 * b"\x00" + pack(">Q", _len), self.sbox) - - checksum = hex(checksum)[2:].rstrip("L") - if len(checksum) % 2 != 0: - checksum = "0" + checksum - checksum = hexdec(checksum) - checksum = b"\x00" * (BLOCKSIZE - len(checksum)) + checksum - h = _step(h, checksum, self.sbox) - return h[::-1] - - -def new(data=b"", sbox=DEFAULT_SBOX): - return GOST341194(data, sbox) - - -PBKDF2_HASHER = partial(GOST341194, sbox="id-GostR3411-94-CryptoProParamSet") - - -def pbkdf2(password, salt, iterations, dklen): - return pbkdf2_base(PBKDF2_HASHER, password, salt, iterations, dklen) diff --git a/pygost-5.13/build/lib/pygost/gost3412.py b/pygost-5.13/build/lib/pygost/gost3412.py deleted file mode 100644 index b9472ee..0000000 --- a/pygost-5.13/build/lib/pygost/gost3412.py +++ /dev/null @@ -1,186 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST 34.12-2015 64 and 128 bit block ciphers (:rfc:`7801`) - -Several precalculations are performed during this module importing. -""" - -from pygost.gost28147 import block2ns as gost28147_block2ns -from pygost.gost28147 import decrypt as gost28147_decrypt -from pygost.gost28147 import encrypt as gost28147_encrypt -from pygost.gost28147 import ns2block as gost28147_ns2block -from pygost.utils import strxor -from pygost.utils import xrange - - -KEYSIZE = 32 - -LC = bytearray(( - 148, 32, 133, 16, 194, 192, 1, 251, 1, 192, 194, 16, 133, 32, 148, 1, -)) -PI = bytearray(( - 252, 238, 221, 17, 207, 110, 49, 22, 251, 196, 250, 218, 35, 197, 4, 77, - 233, 119, 240, 219, 147, 46, 153, 186, 23, 54, 241, 187, 20, 205, 95, 193, - 249, 24, 101, 90, 226, 92, 239, 33, 129, 28, 60, 66, 139, 1, 142, 79, 5, - 132, 2, 174, 227, 106, 143, 160, 6, 11, 237, 152, 127, 212, 211, 31, 235, - 52, 44, 81, 234, 200, 72, 171, 242, 42, 104, 162, 253, 58, 206, 204, 181, - 112, 14, 86, 8, 12, 118, 18, 191, 114, 19, 71, 156, 183, 93, 135, 21, 161, - 150, 41, 16, 123, 154, 199, 243, 145, 120, 111, 157, 158, 178, 177, 50, 117, - 25, 61, 255, 53, 138, 126, 109, 84, 198, 128, 195, 189, 13, 87, 223, 245, - 36, 169, 62, 168, 67, 201, 215, 121, 214, 246, 124, 34, 185, 3, 224, 15, - 236, 222, 122, 148, 176, 188, 220, 232, 40, 80, 78, 51, 10, 74, 167, 151, - 96, 115, 30, 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65, 173, 69, 70, - 146, 39, 94, 85, 47, 140, 163, 165, 125, 105, 213, 149, 59, 7, 88, 179, 64, - 134, 172, 29, 247, 48, 55, 107, 228, 136, 217, 231, 137, 225, 27, 131, 73, - 76, 63, 248, 254, 141, 83, 170, 144, 202, 216, 133, 97, 32, 113, 103, 164, - 45, 43, 9, 91, 203, 155, 37, 208, 190, 229, 108, 82, 89, 166, 116, 210, 230, - 244, 180, 192, 209, 102, 175, 194, 57, 75, 99, 182, -)) - -######################################################################## -# Precalculate inverted PI value as a performance optimization. -# Actually it can be computed only once and saved on the disk. -######################################################################## -PIinv = bytearray(256) -for x in xrange(256): - PIinv[PI[x]] = x - - -def gf(a, b): - c = 0 - while b: - if b & 1: - c ^= a - if a & 0x80: - a = (a << 1) ^ 0x1C3 - else: - a <<= 1 - b >>= 1 - return c - -######################################################################## -# Precalculate all possible gf(byte, byte) values as a performance -# optimization. -# Actually it can be computed only once and saved on the disk. -######################################################################## - - -GF = [bytearray(256) for _ in xrange(256)] - -for x in xrange(256): - for y in xrange(256): - GF[x][y] = gf(x, y) - - -def L(blk, rounds=16): - for _ in range(rounds): - t = blk[15] - for i in range(14, -1, -1): - blk[i + 1] = blk[i] - t ^= GF[blk[i]][LC[i]] - blk[0] = t - return blk - - -def Linv(blk): - for _ in range(16): - t = blk[0] - for i in range(15): - blk[i] = blk[i + 1] - t ^= GF[blk[i]][LC[i]] - blk[15] = t - return blk - -######################################################################## -# Precalculate values of the C -- it does not depend on key. -# Actually it can be computed only once and saved on the disk. -######################################################################## - - -C = [] - -for x in range(1, 33): - y = bytearray(16) - y[15] = x - C.append(L(y)) - - -def lp(blk): - return L([PI[v] for v in blk]) - - -class GOST3412Kuznechik(object): - """GOST 34.12-2015 128-bit block cipher Кузнечик (Kuznechik) - """ - blocksize = 16 - - def __init__(self, key): - """ - :param key: encryption/decryption key - :type key: bytes, 32 bytes - - Key scheduling (roundkeys precomputation) is performed here. - """ - kr0 = bytearray(key[:16]) - kr1 = bytearray(key[16:]) - self.ks = [kr0, kr1] - for i in range(4): - for j in range(8): - k = lp(bytearray(strxor(C[8 * i + j], kr0))) - kr0, kr1 = [strxor(k, kr1), kr0] - self.ks.append(kr0) - self.ks.append(kr1) - - def encrypt(self, blk): - blk = bytearray(blk) - for i in range(9): - blk = lp(bytearray(strxor(self.ks[i], blk))) - return bytes(strxor(self.ks[9], blk)) - - def decrypt(self, blk): - blk = bytearray(blk) - for i in range(9, 0, -1): - blk = [PIinv[v] for v in Linv(bytearray(strxor(self.ks[i], blk)))] - return bytes(strxor(self.ks[0], blk)) - - -class GOST3412Magma(object): - """GOST 34.12-2015 64-bit block cipher Магма (Magma) - """ - blocksize = 8 - - def __init__(self, key): - """ - :param key: encryption/decryption key - :type key: bytes, 32 bytes - """ - # Backward compatibility key preparation for 28147-89 key schedule - self.key = b"".join(key[i * 4:i * 4 + 4][::-1] for i in range(8)) - self.sbox = "id-tc26-gost-28147-param-Z" - - def encrypt(self, blk): - return gost28147_ns2block(gost28147_encrypt( - self.sbox, - self.key, - gost28147_block2ns(blk[::-1]), - ))[::-1] - - def decrypt(self, blk): - return gost28147_ns2block(gost28147_decrypt( - self.sbox, - self.key, - gost28147_block2ns(blk[::-1]), - ))[::-1] diff --git a/pygost-5.13/build/lib/pygost/gost3413.py b/pygost-5.13/build/lib/pygost/gost3413.py deleted file mode 100644 index f3cb5da..0000000 --- a/pygost-5.13/build/lib/pygost/gost3413.py +++ /dev/null @@ -1,392 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.13-2015: Modes of operation for block ciphers - -This module currently includes only padding methods. -""" - -from os import urandom - -from pygost.utils import bytes2long -from pygost.utils import long2bytes -from pygost.utils import strxor -from pygost.utils import xrange - - -KEYSIZE = 32 - - -def pad_size(data_size, blocksize): - """Calculate required pad size to full up blocksize - """ - if data_size < blocksize: - return blocksize - data_size - if data_size % blocksize == 0: - return 0 - return blocksize - data_size % blocksize - - -def pad1(data, blocksize): - """Padding method 1 - - Just fill up with zeros if necessary. - """ - return data + b"\x00" * pad_size(len(data), blocksize) - - -def pad2(data, blocksize): - """Padding method 2 (also known as ISO/IEC 7816-4) - - Add one bit and then fill up with zeros. - """ - return data + b"\x80" + b"\x00" * pad_size(len(data) + 1, blocksize) - - -def unpad2(data, blocksize): - """Unpad method 2 - """ - last_block = bytearray(data[-blocksize:]) - pad_index = last_block.rfind(b"\x80") - if pad_index == -1: - raise ValueError("Invalid padding") - for c in last_block[pad_index + 1:]: - if c != 0: - raise ValueError("Invalid padding") - return data[:-(blocksize - pad_index)] - - -def pad3(data, blocksize): - """Padding method 3 - """ - if pad_size(len(data), blocksize) == 0: - return data - return pad2(data, blocksize) - - -def ecb_encrypt(encrypter, bs, pt): - """ECB encryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes pt: already padded plaintext - """ - if not pt or len(pt) % bs != 0: - raise ValueError("Plaintext is not blocksize aligned") - ct = [] - for i in xrange(0, len(pt), bs): - ct.append(encrypter(pt[i:i + bs])) - return b"".join(ct) - - -def ecb_decrypt(decrypter, bs, ct): - """ECB decryption mode of operation - - :param decrypter: Decrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes ct: ciphertext - """ - if not ct or len(ct) % bs != 0: - raise ValueError("Ciphertext is not blocksize aligned") - pt = [] - for i in xrange(0, len(ct), bs): - pt.append(decrypter(ct[i:i + bs])) - return b"".join(pt) - - -def acpkm(encrypter, bs): - """Perform ACPKM key derivation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - """ - return b"".join([ - encrypter(bytes(bytearray(range(d, d + bs)))) - for d in range(0x80, 0x80 + bs * (KEYSIZE // bs), bs) - ]) - - -def ctr(encrypter, bs, data, iv, _acpkm=None): - """Counter mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes data: plaintext/ciphertext - :param bytes iv: half blocksize-sized initialization vector - - For decryption you use the same function again. - """ - if len(iv) != bs // 2: - raise ValueError("Invalid IV size") - if len(data) > bs * (1 << (8 * (bs // 2 - 1))): - raise ValueError("Too big data") - stream = [] - ctr_value = 0 - ctr_max_value = 1 << (8 * (bs // 2)) - if _acpkm is not None: - acpkm_algo_class, acpkm_section_size_in_bs = _acpkm - acpkm_section_size_in_bs //= bs - for _ in xrange(0, len(data) + pad_size(len(data), bs), bs): - if ( - _acpkm is not None and - ctr_value != 0 and - ctr_value % acpkm_section_size_in_bs == 0 - ): - encrypter = acpkm_algo_class(acpkm(encrypter, bs)).encrypt - stream.append(encrypter(iv + long2bytes(ctr_value, bs // 2))) - ctr_value = (ctr_value + 1) % ctr_max_value - return strxor(b"".join(stream), data) - - -def ctr_acpkm(algo_class, encrypter, section_size, bs, data, iv): - """CTR-ACPKM mode of operation - - :param algo_class: pygost.gost3412's algorithm class - :param encrypter: encrypting function, that takes block as an input - :param int section_size: ACPKM'es section size (N), in bytes - :param int bs: cipher's blocksize, bytes - :param bytes data: plaintext/ciphertext - :param bytes iv: half blocksize-sized initialization vector - - For decryption you use the same function again. - """ - if section_size % bs != 0: - raise ValueError("section_size must be multiple of bs") - return ctr(encrypter, bs, data, iv, _acpkm=(algo_class, section_size)) - - -def ofb(encrypter, bs, data, iv): - """OFB mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes data: plaintext/ciphertext - :param bytes iv: blocksize-sized initialization vector - - For decryption you use the same function again. - """ - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - result = [] - for i in xrange(0, len(data) + pad_size(len(data), bs), bs): - r = r[1:] + [encrypter(r[0])] - result.append(strxor(r[-1], data[i:i + bs])) - return b"".join(result) - - -def cbc_encrypt(encrypter, bs, pt, iv): - """CBC encryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes pt: already padded plaintext - :param bytes iv: blocksize-sized initialization vector - """ - if not pt or len(pt) % bs != 0: - raise ValueError("Plaintext is not blocksize aligned") - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - ct = [] - for i in xrange(0, len(pt), bs): - ct.append(encrypter(strxor(r[0], pt[i:i + bs]))) - r = r[1:] + [ct[-1]] - return b"".join(ct) - - -def cbc_decrypt(decrypter, bs, ct, iv): - """CBC decryption mode of operation - - :param decrypter: Decrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes ct: ciphertext - :param bytes iv: blocksize-sized initialization vector - """ - if not ct or len(ct) % bs != 0: - raise ValueError("Ciphertext is not blocksize aligned") - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - pt = [] - for i in xrange(0, len(ct), bs): - blk = ct[i:i + bs] - pt.append(strxor(r[0], decrypter(blk))) - r = r[1:] + [blk] - return b"".join(pt) - - -def cfb_encrypt(encrypter, bs, pt, iv): - """CFB encryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes pt: plaintext - :param bytes iv: blocksize-sized initialization vector - """ - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - ct = [] - for i in xrange(0, len(pt) + pad_size(len(pt), bs), bs): - ct.append(strxor(encrypter(r[0]), pt[i:i + bs])) - r = r[1:] + [ct[-1]] - return b"".join(ct) - - -def cfb_decrypt(encrypter, bs, ct, iv): - """CFB decryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes ct: ciphertext - :param bytes iv: blocksize-sized initialization vector - """ - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - pt = [] - for i in xrange(0, len(ct) + pad_size(len(ct), bs), bs): - blk = ct[i:i + bs] - pt.append(strxor(encrypter(r[0]), blk)) - r = r[1:] + [blk] - return b"".join(pt) - - -def _mac_shift(bs, data, xor_lsb=0): - num = (bytes2long(data) << 1) ^ xor_lsb - return long2bytes(num, bs)[-bs:] - - -Rb64 = 0b11011 -Rb128 = 0b10000111 - - -def _mac_ks(encrypter, bs): - Rb = Rb128 if bs == 16 else Rb64 - _l = encrypter(bs * b"\x00") - k1 = _mac_shift(bs, _l, Rb) if bytearray(_l)[0] & 0x80 > 0 else _mac_shift(bs, _l) - k2 = _mac_shift(bs, k1, Rb) if bytearray(k1)[0] & 0x80 > 0 else _mac_shift(bs, k1) - return k1, k2 - - -def mac(encrypter, bs, data): - """MAC (known here as CMAC, OMAC1) mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes data: data to authenticate - - Implementation is based on PyCrypto's CMAC one, that is in public domain. - """ - k1, k2 = _mac_ks(encrypter, bs) - if len(data) % bs == 0: - tail_offset = len(data) - bs - else: - tail_offset = len(data) - (len(data) % bs) - prev = bs * b"\x00" - for i in xrange(0, tail_offset, bs): - prev = encrypter(strxor(data[i:i + bs], prev)) - tail = data[tail_offset:] - return encrypter(strxor( - strxor(pad3(tail, bs), prev), - k1 if len(tail) == bs else k2, - )) - - -def acpkm_master(algo_class, encrypter, key_section_size, bs, keymat_len): - """ACPKM-Master key derivation - - :param algo_class: pygost.gost3412's algorithm class - :param encrypter: encrypting function, that takes block as an input - :param int key_section_size: ACPKM'es key section size (T*), in bytes - :param int bs: cipher's blocksize, bytes - :param int keymat_len: length of key material to produce - """ - return ctr_acpkm( - algo_class, - encrypter, - key_section_size, - bs, - data=b"\x00" * keymat_len, - iv=b"\xFF" * (bs // 2), - ) - - -def mac_acpkm_master(algo_class, encrypter, key_section_size, section_size, bs, data): - """OMAC-ACPKM-Master - - :param algo_class: pygost.gost3412's algorithm class - :param encrypter: encrypting function, that takes block as an input - :param int key_section_size: ACPKM'es key section size (T*), in bytes - :param int section_size: ACPKM'es section size (N), in bytes - :param int bs: cipher's blocksize, bytes - :param bytes data: data to authenticate - """ - if len(data) % bs == 0: - tail_offset = len(data) - bs - else: - tail_offset = len(data) - (len(data) % bs) - prev = bs * b"\x00" - sections = len(data) // section_size - if len(data) % section_size != 0: - sections += 1 - keymats = acpkm_master( - algo_class, - encrypter, - key_section_size, - bs, - (KEYSIZE + bs) * sections, - ) - for i in xrange(0, tail_offset, bs): - if i % section_size == 0: - keymat, keymats = keymats[:KEYSIZE + bs], keymats[KEYSIZE + bs:] - key, k1 = keymat[:KEYSIZE], keymat[KEYSIZE:] - encrypter = algo_class(key).encrypt - prev = encrypter(strxor(data[i:i + bs], prev)) - tail = data[tail_offset:] - if len(tail) == bs: - key, k1 = keymats[:KEYSIZE], keymats[KEYSIZE:] - encrypter = algo_class(key).encrypt - k2 = long2bytes(bytes2long(k1) << 1, size=bs) - if bytearray(k1)[0] & 0x80 != 0: - k2 = strxor(k2, long2bytes(Rb128 if bs == 16 else Rb64, size=bs)) - return encrypter(strxor( - strxor(pad3(tail, bs), prev), - k1 if len(tail) == bs else k2, - )) - - -def pad_iso10126(data, blocksize): - """ISO 10126 padding - - Does not exist in 34.13, but added for convenience. - It uses urandom call for getting the randomness. - """ - pad_len = blocksize - len(data) % blocksize - if pad_len == 0: - pad_len = blocksize - return b"".join((data, urandom(pad_len - 1), bytes((pad_len,)))) - - -def unpad_iso10126(data, blocksize): - """Unpad :py:func:`pygost.gost3413.pad_iso10126` - """ - if len(data) % blocksize != 0: - raise ValueError("Data length is not multiple of blocksize") - pad_len = bytearray(data)[-1] - if pad_len > blocksize: - raise ValueError("Padding length is bigger than blocksize") - return data[:-pad_len] diff --git a/pygost-5.13/build/lib/pygost/iface.py b/pygost-5.13/build/lib/pygost/iface.py deleted file mode 100644 index e2d6a4c..0000000 --- a/pygost-5.13/build/lib/pygost/iface.py +++ /dev/null @@ -1,50 +0,0 @@ -from abc import ABCMeta -from abc import abstractmethod - -from pygost.utils import hexenc - - -# This function is taken from six package as is -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get("__slots__") - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop("__dict__", None) - orig_vars.pop("__weakref__", None) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - -@add_metaclass(ABCMeta) -class PEP247(object): - @property - @abstractmethod - def digest_size(self): - """The size of the digest produced by the hashing objects. - """ - - @abstractmethod - def copy(self): - """Return a separate copy of this hashing object. - """ - - @abstractmethod - def update(self, data): - """Hash data into the current state of the hashing object. - """ - - @abstractmethod - def digest(self): - """Return the hash value as a string containing 8-bit data. - """ - - def hexdigest(self): - """Return the hash value as a string containing hexadecimal digits. - """ - return hexenc(self.digest()) diff --git a/pygost-5.13/build/lib/pygost/kdf.py b/pygost-5.13/build/lib/pygost/kdf.py deleted file mode 100644 index 4e404c6..0000000 --- a/pygost-5.13/build/lib/pygost/kdf.py +++ /dev/null @@ -1,81 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Key derivation functions, Р 50.1.113-2016, Р 1323565.1.020-2018 -""" - -import hmac - -from pygost.gost3410_vko import kek_34102012256 -from pygost.gost3410_vko import kek_34102012512 -from pygost.gost34112012256 import GOST34112012256 -from pygost.utils import bytes2long -from pygost.utils import long2bytes - - -def kdf_gostr3411_2012_256(key, label, seed): - """KDF_GOSTR3411_2012_256 - - :param bytes key: initial key - :param bytes label: label - :param bytes seed: seed - :returns: 32 bytes - """ - return hmac.new( - key=key, - msg=b"".join((b"\x01", label, b"\x00", seed, b"\x01\x00")), - digestmod=GOST34112012256, - ).digest() - - -def kdf_tree_gostr3411_2012_256(key, label, seed, keys, i_len=1): - """KDF_TREE_GOSTR3411_2012_256 - - :param bytes key: initial key - :param bytes label: label - :param bytes seed: seed - :param int keys: number of generated keys - :param int i_len: length of iterations value (called "R") - :returns: list of 256-bit keys - """ - keymat = [] - _len = long2bytes(keys * 32 * 8, size=1) - for i in range(keys): - keymat.append(hmac.new( - key=key, - msg=b"".join((long2bytes(i + 1, size=i_len), label, b"\x00", seed, _len)), - digestmod=GOST34112012256, - ).digest()) - return keymat - - -def keg(curve, prv, pub, h): - """Export key generation (Р 1323565.1.020-2018) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param bytes h: "h"-value, 32 bytes - """ - if len(h) != 32: - raise ValueError("h must be 32 bytes long") - ukm = bytes2long(h[:16]) - if ukm == 0: - ukm = 1 - if curve.point_size == 64: - return kek_34102012512(curve, prv, pub, ukm) - k_exp = kek_34102012256(curve, prv, pub, ukm) - return b"".join(kdf_tree_gostr3411_2012_256(k_exp, b"kdf tree", h[16:24], 2)) diff --git a/pygost-5.13/build/lib/pygost/mgm.py b/pygost-5.13/build/lib/pygost/mgm.py deleted file mode 100644 index fb51343..0000000 --- a/pygost-5.13/build/lib/pygost/mgm.py +++ /dev/null @@ -1,168 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Multilinear Galois Mode (MGM) block cipher mode. -""" - -from hmac import compare_digest - -from pygost.gost3413 import pad1 -from pygost.utils import bytes2long -from pygost.utils import long2bytes -from pygost.utils import strxor - - -def _incr(data, bs): - return long2bytes(bytes2long(data) + 1, size=bs // 2) - - -def incr_r(data, bs): - return data[:bs // 2] + _incr(data[bs // 2:], bs) - - -def incr_l(data, bs): - return _incr(data[:bs // 2], bs) + data[bs // 2:] - - -def nonce_prepare(nonce): - """Prepare nonce for MGM usage - - It just clears MSB. - """ - n = bytearray(nonce) - n[0] &= 0x7F - return bytes(n) - - -class MGM(object): - # Implementation is fully based on go.cypherpunks.ru/gogost/mgm - def __init__(self, encrypter, bs, tag_size=None): - """Multilinear Galois Mode (MGM) block cipher mode - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize - :param int tag_size: authentication tag size - (defaults to blocksize if not specified) - """ - if bs not in (8, 16): - raise ValueError("Only 64/128-bit blocksizes allowed") - self.tag_size = bs if tag_size is None else tag_size - if self.tag_size < 4 or self.tag_size > bs: - raise ValueError("Invalid tag_size") - self.encrypter = encrypter - self.bs = bs - self.max_size = (1 << (bs * 8 // 2)) - 1 - self.r = 0x1B if bs == 8 else 0x87 - - def _validate_nonce(self, nonce): - if len(nonce) != self.bs: - raise ValueError("nonce length must be equal to cipher's blocksize") - if bytearray(nonce)[0] & 0x80 > 0: - raise ValueError("nonce must not have higher bit set") - - def _validate_sizes(self, plaintext, additional_data): - if len(plaintext) == 0 and len(additional_data) == 0: - raise ValueError("At least one of plaintext or additional_data required") - if len(plaintext) + len(additional_data) > self.max_size: - raise ValueError("plaintext+additional_data are too big") - - def _mul(self, x, y): - x = bytes2long(x) - y = bytes2long(y) - z = 0 - max_bit = 1 << (self.bs * 8 - 1) - while y > 0: - if y & 1 == 1: - z ^= x - if x & max_bit > 0: - x = ((x ^ max_bit) << 1) ^ self.r - else: - x <<= 1 - y >>= 1 - return long2bytes(z, size=self.bs) - - def _crypt(self, icn, data): - icn[0] &= 0x7F - enc = self.encrypter(bytes(icn)) - res = [] - while len(data) > 0: - res.append(strxor(self.encrypter(enc), data)) - enc = incr_r(enc, self.bs) - data = data[self.bs:] - return b"".join(res) - - def _auth(self, icn, text, ad): - icn[0] |= 0x80 - enc = self.encrypter(bytes(icn)) - _sum = self.bs * b"\x00" - ad_len = len(ad) - text_len = len(text) - while len(ad) > 0: - _sum = strxor(_sum, self._mul( - self.encrypter(enc), - pad1(ad[:self.bs], self.bs), - )) - enc = incr_l(enc, self.bs) - ad = ad[self.bs:] - while len(text) > 0: - _sum = strxor(_sum, self._mul( - self.encrypter(enc), - pad1(text[:self.bs], self.bs), - )) - enc = incr_l(enc, self.bs) - text = text[self.bs:] - _sum = strxor(_sum, self._mul(self.encrypter(enc), ( - long2bytes(ad_len * 8, size=self.bs // 2) + - long2bytes(text_len * 8, size=self.bs // 2) - ))) - return self.encrypter(_sum)[:self.tag_size] - - def seal(self, nonce, plaintext, additional_data): - """Seal plaintext - - :param bytes nonce: blocksize-sized nonce. - Assure that it does not have MSB bit set - (:py:func:`pygost.mgm.nonce_prepare` helps) - :param bytes plaintext: plaintext to be encrypted and authenticated - :param bytes additional_data: additional data to be authenticated - """ - self._validate_nonce(nonce) - self._validate_sizes(plaintext, additional_data) - icn = bytearray(nonce) - ciphertext = self._crypt(icn, plaintext) - tag = self._auth(icn, ciphertext, additional_data) - return ciphertext + tag - - def open(self, nonce, ciphertext, additional_data): - """Open ciphertext - - :param bytes nonce: blocksize-sized nonce. - Assure that it does not have MSB bit set - (:py:func:`pygost.mgm.nonce_prepare` helps) - :param bytes ciphertext: ciphertext to be decrypted and authenticated - :param bytes additional_data: additional data to be authenticated - :raises ValueError: if ciphertext authentication fails - """ - self._validate_nonce(nonce) - self._validate_sizes(ciphertext, additional_data) - icn = bytearray(nonce) - ciphertext, tag_expected = ( - ciphertext[:-self.tag_size], - ciphertext[-self.tag_size:], - ) - tag = self._auth(icn, ciphertext, additional_data) - if not compare_digest(tag_expected, tag): - raise ValueError("Invalid authentication tag") - return self._crypt(icn, ciphertext) diff --git a/pygost-5.13/build/lib/pygost/pbkdf2.py b/pygost-5.13/build/lib/pygost/pbkdf2.py deleted file mode 100644 index 0fd6ddc..0000000 --- a/pygost-5.13/build/lib/pygost/pbkdf2.py +++ /dev/null @@ -1,41 +0,0 @@ -# coding: utf-8 -"""PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012. - -This implementation is based on Python 3.5.2 source code's one. -PyGOST does not register itself in hashlib anyway, so use it instead. -""" - - -from pygost.utils import bytes2long -from pygost.utils import long2bytes -from pygost.utils import strxor -from pygost.utils import xrange - - -def pbkdf2(hasher, password, salt, iterations, dklen): - """PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012 - """ - inner = hasher() - outer = hasher() - password = password + b"\x00" * (inner.block_size - len(password)) - inner.update(strxor(password, len(password) * b"\x36")) - outer.update(strxor(password, len(password) * b"\x5C")) - - def prf(msg): - icpy = inner.copy() - ocpy = outer.copy() - icpy.update(msg) - ocpy.update(icpy.digest()) - return ocpy.digest() - - dkey = b"" - loop = 1 - while len(dkey) < dklen: - prev = prf(salt + long2bytes(loop, 4)) - rkey = bytes2long(prev) - for _ in xrange(iterations - 1): - prev = prf(prev) - rkey ^= bytes2long(prev) - loop += 1 - dkey += long2bytes(rkey, inner.digest_size) - return dkey[:dklen] diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/__init__.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/__init__.pyi deleted file mode 100644 index e69de29..0000000 diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost28147.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost28147.pyi deleted file mode 100644 index be31261..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost28147.pyi +++ /dev/null @@ -1,101 +0,0 @@ -from typing import Callable -from typing import Dict -from typing import Sequence -from typing import Tuple - - -SBOXES = ... # type: Dict[str, Tuple[Tuple[int, ...], ...]] -BLOCKSIZE = ... # type: int - -Words = Tuple[int, int] - - -def block2ns(data: bytes) -> Words: ... - - -def ns2block(ns: Words) -> bytes: ... - - -def validate_key(key: bytes) -> None: ... - - -def validate_iv(iv: bytes) -> None: ... - - -def validate_sbox(sbox: str) -> None: ... - - -def xcrypt(seq: Sequence[int], sbox: str, key: bytes, ns: Words) -> Words: ... - - -def encrypt(sbox: str, key: bytes, ns: Words) -> Words: ... - - -def decrypt(sbox: str, key: bytes, ns: Words) -> Words: ... - - -def ecb( - key: bytes, - data: bytes, - action: Callable[[str, bytes, Words], Words], - sbox: str = ..., -) -> bytes: ... - - -def ecb_encrypt( - key: bytes, - data: bytes, - sbox: str = ..., -) -> bytes: ... - - -def ecb_decrypt( - key: bytes, - data: bytes, - sbox: str = ..., -) -> bytes: ... - - -def cbc_encrypt( - key: bytes, - data: bytes, - iv: bytes = ..., - pad: bool = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... - - -def cbc_decrypt( - key: bytes, - data: bytes, - pad: bool = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... - - -def cnt( - key: bytes, - data: bytes, - iv: bytes = ..., - sbox: str = ..., -) -> bytes: ... - - -def cfb_encrypt( - key: bytes, - data: bytes, - iv: bytes = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... - - -def cfb_decrypt( - key: bytes, - data: bytes, - iv: bytes = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost28147_mac.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost28147_mac.pyi deleted file mode 100644 index 70d90d6..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost28147_mac.pyi +++ /dev/null @@ -1,25 +0,0 @@ -from pygost.iface import PEP247 - - -class MAC(PEP247): - def __init__( - self, - key: bytes, - data: bytes = ..., - iv: bytes = ..., - sbox: str = ..., - ) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "MAC": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(key: bytes, data: bytes = ..., iv: bytes = ..., sbox: str = ...) -> MAC: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3410.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost3410.pyi deleted file mode 100644 index 8f0dcb8..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3410.pyi +++ /dev/null @@ -1,72 +0,0 @@ -from typing import Dict -from typing import Tuple - - -DEFAULT_CURVE = ... # type: GOST3410Curve -CURVES = ... # type: Dict[str, GOST3410Curve] -PublicKey = Tuple[int, int] - - -class GOST3410Curve(object): - p = ... # type: int - q = ... # type: int - a = ... # type: int - b = ... # type: int - x = ... # type: int - y = ... # type: int - cofactor = ... # type: int - e = ... # type: int - d = ... # type: int - name = ... # type: str - - def __init__( - self, - p: int, - q: int, - a: int, - b: int, - x: int, - y: int, - cofactor: int = 1, - e: int = None, - d: int = None, - name: str = None, - ) -> None: ... - - def pos(self, v: int) -> int: ... - - def exp(self, degree: int, x: int = ..., y: int = ...) -> int: ... - - def st(self) -> Tuple[int, int]: ... - - @property - def point_size(self) -> int: ... - - def contains(self, point: Tuple[int, int]) -> bool: ... - - -def public_key(curve: GOST3410Curve, prv: int) -> PublicKey: ... - - -def sign(curve: GOST3410Curve, prv: int, digest: bytes, rand: bytes = None) -> bytes: ... - - -def verify(curve: GOST3410Curve, pub: PublicKey, digest: bytes, signature: bytes) -> bool: ... - - -def prv_unmarshal(prv: bytes) -> int: ... - - -def prv_marshal(curve: GOST3410Curve, prv: int) -> bytes: ... - - -def pub_marshal(pub: PublicKey) -> bytes: ... - - -def pub_unmarshal(pub: bytes) -> PublicKey: ... - - -def uv2xy(curve: GOST3410Curve, u: int, v: int) -> Tuple[int, int]: ... - - -def xy2uv(curve: GOST3410Curve, x: int, y: int) -> Tuple[int, int]: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3410_vko.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost3410_vko.pyi deleted file mode 100644 index 6ea9b82..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3410_vko.pyi +++ /dev/null @@ -1,17 +0,0 @@ -from pygost.gost3410 import GOST3410Curve -from pygost.gost3410 import PublicKey - - -def ukm_unmarshal(ukm: bytes) -> int: ... - - -def kek(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int) -> bytes: ... - - -def kek_34102001(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int) -> bytes: ... - - -def kek_34102012256(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int = ...) -> bytes: ... - - -def kek_34102012512(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int = ...) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012.pyi deleted file mode 100644 index 3d5cc41..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012.pyi +++ /dev/null @@ -1,18 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST34112012(PEP247): - block_size = ... # type: int - - def __init__(self, data: bytes = ..., digest_size: int = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST34112012": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012256.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012256.pyi deleted file mode 100644 index a1d2a01..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012256.pyi +++ /dev/null @@ -1,21 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST34112012256(PEP247): - block_size = ... # type: int - - def __init__(self, data: bytes = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST34112012256": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(data: bytes = ...) -> GOST34112012256: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012512.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012512.pyi deleted file mode 100644 index 349bddd..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost34112012512.pyi +++ /dev/null @@ -1,24 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST34112012512(PEP247): - block_size = ... # type: int - - def __init__(self, data: bytes = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST34112012512": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(data: bytes = ...) -> GOST34112012512: ... - - -def pbkdf2(password: bytes, salt: bytes, iterations: int, dklen: int) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost341194.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost341194.pyi deleted file mode 100644 index 24de2e4..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost341194.pyi +++ /dev/null @@ -1,25 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST341194(PEP247): - sbox = ... # type: str - block_size = ... # type: int - - def __init__(self, data: bytes = ..., sbox: str = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST341194": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(data: bytes = ..., sbox: str = ...) -> GOST341194: ... - - -def pbkdf2(password: bytes, salt: bytes, iterations: int, dklen: int) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3412.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost3412.pyi deleted file mode 100644 index ef278b7..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3412.pyi +++ /dev/null @@ -1,18 +0,0 @@ -class GOST3412Kuznechik(object): - blocksize = ... # type: int - - def __init__(self, key: bytes) -> None: ... - - def encrypt(self, blk: bytes) -> bytes: ... - - def decrypt(self, blk: bytes) -> bytes: ... - - -class GOST3412Magma(object): - blocksize = ... # type: int - - def __init__(self, key: bytes) -> None: ... - - def encrypt(self, blk: bytes) -> bytes: ... - - def decrypt(self, blk: bytes) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3413.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/gost3413.pyi deleted file mode 100644 index 4cfd694..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/gost3413.pyi +++ /dev/null @@ -1,81 +0,0 @@ -from typing import Callable - - -def pad_size(data_size: int, blocksize: int) -> int: ... - - -def pad1(data: bytes, blocksize: int) -> bytes: ... - - -def pad2(data: bytes, blocksize: int) -> bytes: ... - - -def unpad2(data: bytes, blocksize: int) -> bytes: ... - - -def pad3(data: bytes, blocksize: int) -> bytes: ... - - -def ecb_encrypt(encrypter: Callable[[bytes], bytes], bs: int, pt: bytes) -> bytes: ... - - -def ecb_decrypt(decrypter: Callable[[bytes], bytes], bs: int, ct: bytes) -> bytes: ... - - -def acpkm(encrypter: Callable[[bytes], bytes], bs: int) -> bytes: ... - - -def ctr(encrypter: Callable[[bytes], bytes], bs: int, data: bytes, iv: bytes) -> bytes: ... - - -def ctr_acpkm( - algo_class: object, - encrypter: Callable[[bytes], bytes], - section_size: int, - bs: int, - data: bytes, - iv: bytes, -) -> bytes: ... - - -def ofb(encrypter: Callable[[bytes], bytes], bs: int, data: bytes, iv: bytes) -> bytes: ... - - -def cbc_encrypt(encrypter: Callable[[bytes], bytes], bs: int, pt: bytes, iv: bytes) -> bytes: ... - - -def cbc_decrypt(decrypter: Callable[[bytes], bytes], bs: int, ct: bytes, iv: bytes) -> bytes: ... - - -def cfb_encrypt(encrypter: Callable[[bytes], bytes], bs: int, pt: bytes, iv: bytes) -> bytes: ... - - -def cfb_decrypt(encrypter: Callable[[bytes], bytes], bs: int, ct: bytes, iv: bytes) -> bytes: ... - - -def mac(encrypter: Callable[[bytes], bytes], bs: int, data: bytes) -> bytes: ... - - -def acpkm_master( - algo_class: object, - encrypter: Callable[[bytes], bytes], - key_section_size: int, - bs: int, - keymat_len: int, -) -> bytes: ... - - -def mac_acpkm_master( - algo_class: object, - encrypter: Callable[[bytes], bytes], - key_section_size: int, - section_size: int, - bs: int, - data: bytes, -) -> bytes: ... - - -def pad_iso10126(data: bytes, blocksize: int) -> bytes: ... - - -def unpad_iso10126(data: bytes, blocksize: int) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/iface.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/iface.pyi deleted file mode 100644 index a5c2a85..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/iface.pyi +++ /dev/null @@ -1,19 +0,0 @@ -from abc import ABCMeta -from abc import abstractmethod - - -class PEP247(metaclass=ABCMeta): - @abstractmethod - @property - def digest_size(self) -> int: ... - - @abstractmethod - def copy(self) -> "PEP247": ... - - @abstractmethod - def update(self, data: bytes) -> None: ... - - @abstractmethod - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/kdf.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/kdf.pyi deleted file mode 100644 index ccab8af..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/kdf.pyi +++ /dev/null @@ -1,22 +0,0 @@ -from typing import Sequence -from typing import Tuple - -from pygost.gost3410 import GOST3410Curve - - -PublicKey = Tuple[int, int] - - -def kdf_gostr3411_2012_256(key: bytes, label: bytes, seed: bytes) -> bytes: ... - - -def kdf_tree_gostr3411_2012_256( - key: bytes, - label: bytes, - seed: bytes, - keys: int, - i_len: int = 1, -) -> Sequence[bytes]: ... - - -def keg(curve: GOST3410Curve, prv: int, pub: PublicKey, h: bytes) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/mgm.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/mgm.pyi deleted file mode 100644 index 81906b7..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/mgm.pyi +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Callable - - -def nonce_prepare(nonce: bytes) -> bytes: ... - - -class MGM(object): - def __init__( - self, - encrypter: Callable[[bytes], bytes], - bs: int, - tag_size: int = None, - ) -> None: ... - - def seal(self, nonce: bytes, plaintext: bytes, additional_data: bytes) -> bytes: ... - - def open(self, nonce: bytes, ciphertext: bytes, additional_data: bytes) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/utils.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/utils.pyi deleted file mode 100644 index 76460e5..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/utils.pyi +++ /dev/null @@ -1,19 +0,0 @@ -from typing import AnyStr - - -def strxor(a: bytes, b: bytes) -> bytes: ... - - -def hexdec(data: AnyStr) -> bytes: ... - - -def hexenc(data: bytes) -> str: ... - - -def bytes2long(raw: bytes) -> int: ... - - -def long2bytes(n: int, size: int = ...) -> bytes: ... - - -def modinvert(a: int, n: int) -> int: ... diff --git a/pygost-5.13/build/lib/pygost/stubs/pygost/wrap.pyi b/pygost-5.13/build/lib/pygost/stubs/pygost/wrap.pyi deleted file mode 100644 index 776a6e7..0000000 --- a/pygost-5.13/build/lib/pygost/stubs/pygost/wrap.pyi +++ /dev/null @@ -1,31 +0,0 @@ -from typing import Callable - - -def wrap_gost(ukm: bytes, kek: bytes, cek: bytes, sbox: str = ...) -> bytes: ... - - -def unwrap_gost(kek: bytes, data: bytes, sbox: str = ...) -> bytes: ... - - -def wrap_cryptopro(ukm: bytes, kek: bytes, cek: bytes, sbox: str = ...) -> bytes: ... - - -def unwrap_cryptopro(kek: bytes, data: bytes, sbox: str = ...) -> bytes: ... - - -def kexp15( - encrypter_key: Callable[[bytes], bytes], - encrypter_mac: Callable[[bytes], bytes], - bs: int, - key: bytes, - iv: bytes, -) -> bytes: ... - - -def kimp15( - encrypter_key: Callable[[bytes], bytes], - encrypter_mac: Callable[[bytes], bytes], - bs: int, - kexp: bytes, - iv: bytes, -) -> bytes: ... diff --git a/pygost-5.13/build/lib/pygost/test_cms.py b/pygost-5.13/build/lib/pygost/test_cms.py deleted file mode 100644 index 7e5781a..0000000 --- a/pygost-5.13/build/lib/pygost/test_cms.py +++ /dev/null @@ -1,1078 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from base64 import b64decode -from unittest import skipIf -from unittest import TestCase - -from six import text_type - -from pygost.gost28147 import cfb_decrypt -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_marshal -from pygost.gost3410 import pub_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410 import verify -from pygost.gost3410_vko import kek_34102012256 -from pygost.gost3410_vko import ukm_unmarshal -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3413 import ctr_acpkm -from pygost.gost3413 import KEYSIZE -from pygost.gost3413 import mac as omac -from pygost.kdf import kdf_tree_gostr3411_2012_256 -from pygost.kdf import keg -from pygost.utils import hexdec -from pygost.wrap import kimp15 -from pygost.wrap import unwrap_cryptopro -from pygost.wrap import unwrap_gost - -try: - from pyderasn import DecodePathDefBy - from pyderasn import OctetString - - from pygost.asn1schemas.cms import ContentInfo - from pygost.asn1schemas.cms import SignedAttributes - from pygost.asn1schemas.oids import id_cms_mac_attr - from pygost.asn1schemas.oids import id_envelopedData - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm_omac - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_wrap_kexp15 - from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm - from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm_omac - from pygost.asn1schemas.oids import id_gostr3412_2015_magma_wrap_kexp15 - from pygost.asn1schemas.oids import id_messageDigest - from pygost.asn1schemas.oids import id_tc26_agreement_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_agreement_gost3410_2012_512 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetA - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_512 - from pygost.asn1schemas.x509 import Certificate - from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters -except ImportError: - pyderasn_exists = False -else: - pyderasn_exists = True - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestSigned(TestCase): - """SignedData test vectors from "Использование - алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 в - криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms( - self, - content_info_raw, - prv_key_raw, - curve_name, - hasher, - ): - content_info, tail = ContentInfo().decode(content_info_raw) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, signed_data = content_info["content"].defined - self.assertEqual(len(signed_data["signerInfos"]), 1) - curve = CURVES[curve_name] - self.assertTrue(verify( - curve, - public_key(curve, prv_unmarshal(prv_key_raw)), - hasher(bytes(signed_data["encapContentInfo"]["eContent"])).digest()[::-1], - bytes(signed_data["signerInfos"][0]["signature"]), - )) - - def test_256(self): - content_info_raw = b64decode(""" -MIIBBQYJKoZIhvcNAQcCoIH3MIH0AgEBMQ4wDAYIKoUDBwEBAgIFADAbBgkqhkiG -9w0BBwGgDgQMVGVzdCBtZXNzYWdlMYHBMIG+AgEBMFswVjEpMCcGCSqGSIb3DQEJ -ARYaR29zdFIzNDEwLTIwMTJAZXhhbXBsZS5jb20xKTAnBgNVBAMTIEdvc3RSMzQx -MC0yMDEyICgyNTYgYml0KSBleGFtcGxlAgEBMAwGCCqFAwcBAQICBQAwDAYIKoUD -BwEBAQEFAARAkptb2ekZbC94FaGDQeP70ExvTkXtOY9zgz3cCco/hxPhXUVo3eCx -VNwDQ8enFItJZ8DEX4blZ8QtziNCMl5HbA== - """) - prv_key_raw = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - self.process_cms( - content_info_raw, - prv_key_raw, - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - GOST34112012256, - ) - - def test_512(self): - content_info_raw = b64decode(""" -MIIBSQYJKoZIhvcNAQcCoIIBOjCCATYCAQExDjAMBggqhQMHAQECAwUAMBsGCSqG -SIb3DQEHAaAOBAxUZXN0IG1lc3NhZ2UxggECMIH/AgEBMFswVjEpMCcGCSqGSIb3 -DQEJARYaR29zdFIzNDEwLTIwMTJAZXhhbXBsZS5jb20xKTAnBgNVBAMTIEdvc3RS -MzQxMC0yMDEyICg1MTIgYml0KSBleGFtcGxlAgEBMAwGCCqFAwcBAQIDBQAwDAYI -KoUDBwEBAQIFAASBgFyVohNhMHUi/+RAF3Gh/cC7why6v+4jPWVlx1TYlXtV8Hje -hI2Y+rP52/LO6EUHG/XcwCBbUxmRWsbUSRRBAexmaafkSdvv2FFwC8kHOcti+UPX -PS+KRYxT8vhcsBLWWxDkc1McI7aF09hqtED36mQOfACzeJjEoUjALpmJob1V - """) - prv_key_raw = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - self.process_cms( - content_info_raw, - prv_key_raw, - "id-tc26-gost-3410-12-512-paramSetB", - GOST34112012512, - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestDigested(TestCase): - """DigestedData test vectors from "Использование - алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 в - криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms(self, content_info_raw, hasher): - content_info, tail = ContentInfo().decode(content_info_raw) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, digested_data = content_info["content"].defined - self.assertSequenceEqual( - hasher(bytes(digested_data["encapContentInfo"]["eContent"])).digest(), - bytes(digested_data["digest"]), - ) - - def test_256(self): - content_info_raw = b64decode(""" -MIGdBgkqhkiG9w0BBwWggY8wgYwCAQAwDAYIKoUDBwEBAgIFADBXBgkqhkiG9w0B -BwGgSgRI0eUg4uXy8OgsINHy8Ojh7uboIOLt8/boLCDi5f7y+iDxIOzu8P8g8fLw -5evg7Ogg7eAg9fDg4fD7/yDv6/rq+yDI4+7w5eL7BCCd0v5OkECeXah/U5dtdAWw -wMrGKPxmmnQdUAY8VX6PUA== - """) - self.process_cms(content_info_raw, GOST34112012256) - - def test_512(self): - content_info_raw = b64decode(""" -MIG0BgkqhkiG9w0BBwWggaYwgaMCAQAwDAYIKoUDBwEBAgMFADBOBgkqhkiG9w0B -BwGgQQQ/MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAx -MjM0NTY3ODkwMTIzNDU2Nzg5MDEyBEAbVNAaSvW51cw9htaNKFRisZq8JHUiLzXA -hRIr5Lof+gCtMPh2ezqCOExldPAkwxHipIEzKwjvf0F5eJHBZG9I - """) - self.process_cms(content_info_raw, GOST34112012512) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestEnvelopedKTRI(TestCase): - """EnvelopedData KeyTransRecipientInfo-based test vectors from - "Использование алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 - в криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms( - self, - content_info_raw, - prv_key_our, - curve_name, - keker, - plaintext_expected, - ): - sbox = "id-tc26-gost-28147-param-Z" - content_info, tail = ContentInfo().decode(content_info_raw, ctx={ - "defines_by_path": [ - ( - ( - "content", - DecodePathDefBy(id_envelopedData), - "recipientInfos", - any, - "ktri", - "encryptedKey", - DecodePathDefBy(spki_algorithm), - "transportParameters", - "ephemeralPublicKey", - "algorithm", - "algorithm", - ), - ( - ( - ("..", "subjectPublicKey"), - { - id_tc26_gost3410_2012_256: OctetString(), - id_tc26_gost3410_2012_512: OctetString(), - }, - ), - ), - ) for spki_algorithm in ( - id_tc26_gost3410_2012_256, - id_tc26_gost3410_2012_512, - ) - ], - }) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, enveloped_data = content_info["content"].defined - eci = enveloped_data["encryptedContentInfo"] - ri = enveloped_data["recipientInfos"][0] - self.assertIsNotNone(ri["ktri"]["encryptedKey"].defined) - _, encrypted_key = ri["ktri"]["encryptedKey"].defined - ukm = bytes(encrypted_key["transportParameters"]["ukm"]) - spk = encrypted_key["transportParameters"]["ephemeralPublicKey"]["subjectPublicKey"] - self.assertIsNotNone(spk.defined) - _, pub_key_their = spk.defined - curve = CURVES[curve_name] - kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) - key_wrapped = bytes(encrypted_key["sessionEncryptedKey"]["encryptedKey"]) - mac = bytes(encrypted_key["sessionEncryptedKey"]["macKey"]) - cek = unwrap_cryptopro(kek, ukm + key_wrapped + mac, sbox=sbox) - ciphertext = bytes(eci["encryptedContent"]) - self.assertIsNotNone(eci["contentEncryptionAlgorithm"]["parameters"].defined) - _, encryption_params = eci["contentEncryptionAlgorithm"]["parameters"].defined - iv = bytes(encryption_params["iv"]) - self.assertSequenceEqual( - cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), - plaintext_expected, - ) - - def test_256(self): - content_info_raw = b64decode(""" -MIIKGgYJKoZIhvcNAQcDoIIKCzCCCgcCAQAxggE0MIIBMAIBADBbMFYxKTAnBgkq -hkiG9w0BCQEWGkdvc3RSMzQxMC0yMDEyQGV4YW1wbGUuY29tMSkwJwYDVQQDEyBH -b3N0UjM0MTAtMjAxMiAyNTYgYml0cyBleGNoYW5nZQIBATAfBggqhQMHAQEBATAT -BgcqhQMCAiQABggqhQMHAQECAgSBrDCBqTAoBCCVJxUMdbKRzCJ5K1NWJIXnN7Ul -zaceeFlblA2qH4wZrgQEsHnIG6B9BgkqhQMHAQIFAQGgZjAfBggqhQMHAQEBATAT -BgcqhQMCAiQABggqhQMHAQECAgNDAARAFoqoLg1lV780co6GdwtjLtS4KCXv9VGR -sd7PTPHCT/5iGbvOlKNW2I8UhayJ0dv7RV7Nb1lDIxPxf4Mbp2CikgQI1b4+WpGE -sfQwggjIBgkqhkiG9w0BBwEwHwYGKoUDAgIVMBUECHYNkdvFoYdyBgkqhQMHAQIF -AQGAggiYvFFpJKILAFdXjcdLLYv4eruXzL/wOXL8y9HHIDMbSzV1GM033J5Yt/p4 -H6JYe1L1hjAfE/BAAYBndof2sSUxC3/I7xj+b7M8BZ3GYPqATPtR4aCQDK6z91lx -nDBAWx0HdsStT5TOj/plMs4zJDadvIJLfjmGkt0Np8FSnSdDPOcJAO/jcwiOPopg -+Z8eIuZNmY4seegTLue+7DGqvqi1GdZdMnvXBFIKc9m5DUsC7LdyboqKImh6giZE -YZnxb8a2naersPylhrf+zp4Piwwv808yOrD6LliXUiH0RojlmuaQP4wBkb7m073h -MeAWEWSvyXzOvOOuFST/hxPEupiTRoHPUdfboJT3tNpizUhE384SrvXHpwpgivQ4 -J0zF2/uzTBEupXR6dFC9rTHAK3X79SltqBNnHyIXBwe+BMqTmKTfnlPVHBUfTXZg -oakDItwKwa1MBOZeciwtUFza+7o9FZhKIandb848chGdgd5O9ksaXvPJDIPxQjZd -EBVhnXLlje4TScImwTdvYB8GsI8ljKb2bL3FjwQWGbPaOjXc2D9w+Ore8bk1E4TA -ayhypU7MH3Mq1EBZ4j0iROEFBQmYRZn8vAKZ0K7aPxcDeAnKAJxdokqrMkLgI6WX -0glh/3Cs9dI+0D2GqMSygauKCD0vTIo3atkEQswDZR4pMx88gB4gmx7iIGrc/ZXs -ZqHI7NQqeKtBwv2MCIj+/UTqdYDqbaniDwdVS8PE9nQnNU4gKffq3JbT+wRjJv6M -Dr231bQHgAsFTVKbZgoL4gj4V7bLQUmW06+W1BQUJ2+Sn7fp+Xet9Xd3cGtNdxzQ -zl6sGuiOlTNe0bfKP7QIMC7ekjflLBx8nwa2GZG19k3O0Z9JcDdN/kz6bGpPNssY -AIOkTvLQjxIM9MhRqIv6ee0rowTWQPwXJP7yHApop4XZvVX6h9gG2gazqbDej2lo -tAcfRAKj/LJ/bk9+OlNXOXVCKnwE1kXxZDsNJ51GdCungC56U/hmd3C1RhSLTpEc -FlOWgXKNjbn6SQrlq1yASKKr80T0fL7PFoYwKZoQbKMAVZQC1VBWQltHkEzdL73x -FwgZULNfdflF8sEhFC/zsVqckD/UnhzJz88PtCslMArJ7ntbEF1GzsSSfRfjBqnl -kSUreE5XX6+c9yp5HcJBiMzp6ZqqWWaED5Y5xp1hZeYjuKbDMfY4tbWVc7Hy0dD2 -KGfZLp5umqvPNs7aVBPmvuxtrnxcJlUB8u2HoiHc6/TuhrpaopYGBhxL9+kezuLR -v18nsAg8HOmcCNUS46NXQj/Mdpx8W+RsyzCQkJjieT/Yed20Zxq1zJoXIS0xAaUH -TdE2dWqiT6TGlh/KQYk3KyFPNnDmzJm04a2VWIwpp4ypXyxrB7XxnVY6Q4YBYbZs -FycxGjJWqj7lwc+lgZ8YV2WJ4snEo2os8SsA2GFWcUMiVTHDnEJvphDHmhWsf26A -bbRqwaRXNjhj05DamTRsczgvfjdl1pk4lJYE4ES3nixtMe4s1X8nSmM4KvfyVDul -J8uTpw1ZFnolTdfEL63BSf4FREoEqKB7cKuD7cpn7Rg4kRdM0/BLZGuxkH+pGMsI -Bb8LecUWyjGsI6h74Wz/U2uBrfgdRqhR+UsfB2QLaRgM6kCXZ4vM0auuzBViFCwK -tYMHzZWWz8gyVtJ0mzt1DrHCMx4pTS4yOhv4RkXBS/rub4VhVIsOGOGar5ZYtH47 -uBbdw3NC05JIFM7lI31d0s1fvvkTUR7eaqRW+SnR2c2oHpWlSO+Q0mrzx+vvOTdj -xa713YtklBvyUUQr2SIbsXGpFnwjn+sXK1onAavp/tEax8sNZvxg5yeseFcWn+gD -4rjk9FiSd1wp4fTDQFJ19evqruqKlq6k18l/ZAyUcEbIWSz2s3HfAAoAQyFPX1Q2 -95gVhRRw6lP4S6VPCfn/f+5jV4TcT6W/giRaHIk9Hty+g8bx1bFXaKVkQZ5R2Vmk -qsZ65ZgCrYQJmcErPmYybvP7NBeDS4AOSgBQAGMQF4xywdNm6bniWWo3N/xkFv32 -/25x8okGgD8QcYKmhzieLSSzOvM/exB14RO84YZOkZzm01Jll0nac/LEazKoVWbn -0VdcQ7pYEOqeMBXipsicNVYA/uhonp6op9cpIVYafPr0npCGwwhwcRuOrgSaZyCn -VG2tPkEOv9LKmUbhnaDA2YUSzOOjcCpIVvTSBnUEiorYpfRYgQLrbcd2qhVvNCLX -8ujZfMqXQXK8n5BK8JxNtczvaf+/2dfv1dQl0lHEAQhbNcsJ0t5GPhsSCC5oMBJl -ZJuOEO/8PBWKEnMZOM+Dz7gEgsBhGyMFFrKpiwQRpyEshSD2QpnK6Lp0t5C8Za2G -lhyZsEr+93AYOb5mm5+z02B4Yq9+RpepvjoqVeq/2uywZNq9MS98zVgNsmpryvTZ -3HJHHB20u2jcVu0G3Nhiv22lD70JWCYFAOupjgVcUcaBxjxwUMAvgHg7JZqs6mC6 -tvTKwQ4NtDhoAhARlDeWSwCWb2vPH2H7Lmqokif1RfvJ0hrLzkJuHdWrzIYzXpPs -+v9XJxLvbdKi9KU1Halq9S8dXT1fvs9DJTpUV/KW7QkRsTQJhTJBkQ07WUSJ4gBS -Qp4efxSRNIfMj7DR6qLLf13RpIPTJO9/+gNuBIFcupWVfUL7tJZt8Qsf9eGwZfP+ -YyhjC8AyZjH4/9RzLHSjuq6apgw3Mzw0j572Xg6xDLMK8C3Tn/vrLOvAd96b9MkF -3+ZHSLW3IgOiy+1jvK/20CZxNWc+pey8v4zji1hI17iohsipX/uZKRxhxF6+Xn2R -UQp6qoxHAspNXgWQ57xg7C3+gmi4ciVr0fT9pg54ogcowrRH+I6wd0EpeWPbzfnQ -pRmMVN+YtRsrEHwH3ToQ/i4vrtgA+eONuKT2uKZFikxA+VNmeeGdhkgqETMihQ== - """) - prv_key_our = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - keker, - b"Test data to encrypt.\n" * 100, - ) - - def test_512(self): - content_info_raw = b64decode(""" -MIIB0gYJKoZIhvcNAQcDoIIBwzCCAb8CAQAxggF8MIIBeAIBADBbMFYxKTAnBgkq -hkiG9w0BCQEWGkdvc3RSMzQxMC0yMDEyQGV4YW1wbGUuY29tMSkwJwYDVQQDEyBH -b3N0UjM0MTAtMjAxMiA1MTIgYml0cyBleGNoYW5nZQIBATAhBggqhQMHAQEBAjAV -BgkqhQMHAQIBAgIGCCqFAwcBAQIDBIHyMIHvMCgEIIsYzbVLn33aLinQ7SLNA7y+ -Lrm02khqDCfXrNS9iiMhBATerS8zoIHCBgkqhQMHAQIFAQGggaowIQYIKoUDBwEB -AQIwFQYJKoUDBwECAQICBggqhQMHAQECAwOBhAAEgYAYiTVLKpSGaAvjJEDQ0hdK -qR/jek5Q9Q2pXC+NkOimQh7dpCi+wcaHlPcBk96hmpnOFvLaiokX8V6jqtBl5gdk -M40kOXv8kcDdTzEVKA/ZLxA8xanL+gTD6ZjaPsUu06nsA2MoMBWcHLUzueaP3bGT -/yHTV+Za5xdcQehag/lNBgQIvCw4uUl0XC4wOgYJKoZIhvcNAQcBMB8GBiqFAwIC -FTAVBAj+1QzaXaN9FwYJKoUDBwECBQEBgAyK54euw0sHhEVEkA0= - """) - prv_key_our = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-tc26-gost-3410-12-512-paramSetB", - keker, - b"Test message", - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestEnvelopedKARI(TestCase): - """EnvelopedData KeyAgreeRecipientInfo-based test vectors from - "Использование алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 - в криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms( - self, - content_info_raw, - prv_key_our, - curve_name, - keker, - plaintext_expected, - ): - sbox = "id-tc26-gost-28147-param-Z" - content_info, tail = ContentInfo().decode(content_info_raw, ctx={ - "defines_by_path": [ - ( - ( - "content", - DecodePathDefBy(id_envelopedData), - "recipientInfos", - any, - "kari", - "originator", - "originatorKey", - "algorithm", - "algorithm", - ), - ( - ( - ("..", "publicKey"), - { - id_tc26_gost3410_2012_256: OctetString(), - id_tc26_gost3410_2012_512: OctetString(), - }, - ), - ), - ) for _ in ( - id_tc26_gost3410_2012_256, - id_tc26_gost3410_2012_512, - ) - ], - }) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, enveloped_data = content_info["content"].defined - eci = enveloped_data["encryptedContentInfo"] - kari = enveloped_data["recipientInfos"][0]["kari"] - self.assertIsNotNone(kari["originator"]["originatorKey"]["publicKey"].defined) - _, pub_key_their = kari["originator"]["originatorKey"]["publicKey"].defined - ukm = bytes(kari["ukm"]) - rek = kari["recipientEncryptedKeys"][0] - curve = CURVES[curve_name] - kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) - self.assertIsNotNone(rek["encryptedKey"].defined) - _, encrypted_key = rek["encryptedKey"].defined - key_wrapped = bytes(encrypted_key["encryptedKey"]) - mac = bytes(encrypted_key["macKey"]) - cek = unwrap_gost(kek, ukm + key_wrapped + mac, sbox=sbox) - ciphertext = bytes(eci["encryptedContent"]) - self.assertIsNotNone(eci["contentEncryptionAlgorithm"]["parameters"].defined) - _, encryption_params = eci["contentEncryptionAlgorithm"]["parameters"].defined - iv = bytes(encryption_params["iv"]) - self.assertSequenceEqual( - cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), - plaintext_expected, - ) - - def test_256(self): - content_info_raw = b64decode(""" -MIIBhgYJKoZIhvcNAQcDoIIBdzCCAXMCAQIxggEwoYIBLAIBA6BooWYwHwYIKoUD -BwEBAQEwEwYHKoUDAgIkAAYIKoUDBwEBAgIDQwAEQPAdWM4pO38iZ49UjaXQpq+a -jhTa4KwY4B9TFMK7AiYmbFKE0eX/wvu69kFMQ2o3OJTnMOlr1WHiPYOmNO6C5hOh -CgQIX+vNomZakEIwIgYIKoUDBwEBAQEwFgYHKoUDAgINADALBgkqhQMHAQIFAQEw -gYwwgYkwWzBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxl -LmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgMjU2IGJpdHMgZXhjaGFuZ2UC -AQEEKjAoBCCNhrZOr7x2fsjjQAeDMv/tSoNRQSSQzzxgqdnYxJ3fIAQEgYLqVDA6 -BgkqhkiG9w0BBwEwHwYGKoUDAgIVMBUECHVmR/S+hlYiBgkqhQMHAQIFAQGADEI9 -UNjyuY+54uVcHw== - """) - prv_key_our = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - keker, - b"Test message", - ) - - def test_512(self): - content_info_raw = b64decode(""" -MIIBzAYJKoZIhvcNAQcDoIIBvTCCAbkCAQIxggF2oYIBcgIBA6CBraGBqjAhBggq -hQMHAQEBAjAVBgkqhQMHAQIBAgIGCCqFAwcBAQIDA4GEAASBgCB0nQy/Ljva/mRj -w6o+eDKIvnxwYIQB5XCHhZhCpHNZiWcFxFpYXZLWRPKifOxV7NStvqGE1+fkfhBe -btkQu0tdC1XL3LO2Cp/jX16XhW/IP5rKV84qWr1Owy/6tnSsNRb+ez6IttwVvaVV -pA6ONFy9p9gawoC8nitvAVJkWW0PoQoECDVfxzxgMTAHMCIGCCqFAwcBAQECMBYG -ByqFAwICDQAwCwYJKoUDBwECBQEBMIGMMIGJMFswVjEpMCcGCSqGSIb3DQEJARYa -R29zdFIzNDEwLTIwMTJAZXhhbXBsZS5jb20xKTAnBgNVBAMTIEdvc3RSMzQxMC0y -MDEyIDUxMiBiaXRzIGV4Y2hhbmdlAgEBBCowKAQg8C/OcxRR0Uq8nDjHrQlayFb3 -WFUZEnEuAKcuG6dTOawEBLhi9hIwOgYJKoZIhvcNAQcBMB8GBiqFAwICFTAVBAiD -1wH+CX6CwgYJKoUDBwECBQEBgAzUvQI4H2zRfgNgdlY= - """) - prv_key_our = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-tc26-gost-3410-12-512-paramSetB", - keker, - b"Test message", - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestR132356510252019(TestCase): - """Test vectors from Р 1323565.1.025-2019 - """ - def setUp(self): - self.curve256 = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - self.curve512 = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - self.psk = hexdec("8F5EEF8814D228FB2BBC5612323730CFA33DB7263CC2C0A01A6C6953F33D61D5")[::-1] - - self.ca_prv = prv_unmarshal(hexdec("092F8D059E97E22B90B1AE99F0087FC4D26620B91550CBB437C191005A290810")[::-1]) - self.ca_pub = public_key(self.curve256, self.ca_prv) - self.ca_cert = Certificate().decod(b64decode(""" -MIIB8DCCAZ2gAwIBAgIEAYy6gTAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA4MQ0wCwYDVQQKEwRUSzI2MScwJQYD -VQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwaDAhBggqhQMHAQEB -ATAVBgkqhQMHAQIBAQEGCCqFAwcBAQICA0MABEAaSoKcjw54UACci6svELNF0IYM -RIW8urUsqamIpoG46XCqrVOuI6Q13N4dwcRsbZdqByf+GC2f5ZfO3baN5bTKo4GF -MIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJjsCecS2npzESoTowODENMAsGA1UE -ChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0 -ggQBjLqBMB0GA1UdDgQWBBSA2Qz3mfhmTZNTiY7AnnEtp6cxEjAKBggqhQMHAQED -AgNBAAgv248F4OeNCkhlzJWec0evHYnMBlSzk1lDm0F875B7CqMrKh2MtJHXenbj -Gc2uRn2IwgmSf/LZDrYsKKqZSxk= -""")) - - self.sender256_prv = prv_unmarshal(hexdec("0B20810E449978C7C3B76C6FF77A16C532421139344A058EF56310B6B6F377E8")[::-1]) - self.sender256_pub = public_key(self.curve256, self.sender256_prv) - self.sender256_cert = Certificate().decod(b64decode(""" -MIIB8zCCAaCgAwIBAgIEAYy6gjAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYD -VQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwaDAhBggqhQMH -AQEBATAVBgkqhQMHAQIBAQEGCCqFAwcBAQICA0MABECWKQ0TYllqg4GmY3tBJiyz -pXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZhuJaJfqZ6VbT -o4GFMIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJjsCecS2npzESoTowODENMAsG -A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt -Yml0ggQBjLqBMB0GA1UdDgQWBBTRnChHSWbQYwnJC62n2zu5Njd03zAKBggqhQMH -AQEDAgNBAB41oijaXSEn58l78y2rhxY35/lKEq4XWZ70FtsNlVxWATyzgO5Wliwn -t1O4GoZsxx8r6T/i7VG65UNmQlwdOKQ= -""")) - - self.recipient256_prv = prv_unmarshal(hexdec("0DC8DC1FF2BC114BABC3F1CA8C51E4F58610427E197B1C2FBDBA4AE58CBFB7CE")[::-1]) - self.recipient256_pub = public_key(self.curve256, self.recipient256_prv) - self.recipient256_cert = Certificate().decod(b64decode(""" -MIIB8jCCAZ+gAwIBAgIEAYy6gzAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA6MQ0wCwYDVQQKEwRUSzI2MSkwJwYD -VQQDEyBSRUNJUElFTlQ6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdDBoMCEGCCqFAwcB -AQEBMBUGCSqFAwcBAgEBAQYIKoUDBwEBAgIDQwAEQL8nghlzLGMKWHuWhNMPMN5u -L6SkGqRiJ6qZxZb+4dPKbBT9LNVvNKtwUed+BeE5kfqOfolPgFusnL1rnO9yREOj -gYUwgYIwYQYDVR0BBFowWIAUgNkM95n4Zk2TU4mOwJ5xLaenMRKhOjA4MQ0wCwYD -VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1i -aXSCBAGMuoEwHQYDVR0OBBYEFLue+PUb9Oe+pziBU+MvNejjgrzFMAoGCCqFAwcB -AQMCA0EAPP9Oad1/5jwokSjPpccsQ0xCdVYM+mGQ0IbpiZxQj8gnkt8sq4jR6Ya+ -I/BDkbZNDNE27TU1p3t5rE9NMEeViA== -""")) - - self.sender512_prv = prv_unmarshal(hexdec("F95A5D44C5245F63F2E7DF8E782C1924EADCB8D06C52D91023179786154CBDB1561B4DF759D69F67EE1FBD5B68800E134BAA12818DA4F3AC75B0E5E6F9256911")[::-1]) - self.sender512_pub = public_key(self.curve512, self.sender512_prv) - self.sender512_cert = Certificate().decod(b64decode(""" -MIICNjCCAeOgAwIBAgIEAYy6hDAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYD -VQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDUxMi1iaXQwgaowIQYIKoUD -BwEBAQIwFQYJKoUDBwECAQIBBggqhQMHAQECAwOBhAAEgYC0i7davCkOGGVcYqFP -tS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO+K21LDpYVfDPs2Sqa13ZN+Ts -/JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0EmZf8T3ae/J1Jo6xGunecH1/G4 -hMts9HYLnxbwJDMNVGuIHV6gzqOBhTCBgjBhBgNVHQEEWjBYgBSA2Qz3mfhmTZNT -iY7AnnEtp6cxEqE6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6 -IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQUK+l9HAscONGx -zCcRpxRAmFHvlXowCgYIKoUDBwEBAwIDQQAbjA0Q41/rIKOOvjHKsAsoEJM+WJf6 -/PKXg2JaStthmw99bdtwwkU/qDbcje2tF6mt+XWyQBXwvfeES1GFY9fJ -""")) - - self.recipient512_prv = prv_unmarshal(hexdec("A50315981F0A7C7FC05B4EB9591A62B1F84BD6FD518ACFCEDF0A7C9CF388D1F18757C056ADA5B38CBF24CDDB0F1519EF72DB1712CEF1920952E94AF1F9C575DC")[::-1]) - self.recipient512_pub = public_key(self.curve512, self.recipient512_prv) - self.recipient512_cert = Certificate().decod(b64decode(""" -MIICNTCCAeKgAwIBAgIEAYy6hTAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA6MQ0wCwYDVQQKEwRUSzI2MSkwJwYD -VQQDEyBSRUNJUElFTlQ6IEdPU1QgMzQuMTAtMTIgNTEyLWJpdDCBqjAhBggqhQMH -AQEBAjAVBgkqhQMHAQIBAgEGCCqFAwcBAQIDA4GEAASBgKauwGYvUkzz19g0LP/p -zeRdmwy1m+QSy9W5ZrL/AGuJofm2ARjz40ozNbW6bp9hkHu8x66LX7u5zz+QeS2+ -X5om18UXriComgO0+qhZbc+Hzu0eQ8FjOd8LpLk3TzzfBltfLOX5IiPLjeum+pSP -0QjoXAVcrop//B4yvZIukvROo4GFMIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJ -jsCecS2npzESoTowODENMAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjog -R09TVCAzNC4xMC0xMiAyNTYtYml0ggQBjLqBMB0GA1UdDgQWBBSrXT5VKhm/5uff -kwW0XpG19k6AajAKBggqhQMHAQEDAgNBAAJBpsHRrQKZGb22LOzaReEB8rl2MbIR -ja64NaM5h+cAFoHm6t/k+ziLh2A11rTakR+5of4NQ3EjEhuPtomP2tc= -""")) - - def test_certs(self): - """Certificates signatures - """ - for prv, pub, curve, cert in ( - (self.ca_prv, self.ca_pub, self.curve256, self.ca_cert), - (self.sender256_prv, self.sender256_pub, self.curve256, self.sender256_cert), - (self.recipient256_prv, self.recipient256_pub, self.curve256, self.recipient256_cert), - (self.sender512_prv, self.sender512_pub, self.curve512, self.sender512_cert), - (self.recipient512_prv, self.recipient512_pub, self.curve512, self.recipient512_cert), - ): - pub_our = public_key(curve, prv) - self.assertEqual(pub_our, pub) - self.assertSequenceEqual( - pub_marshal(pub_our), - bytes(OctetString().decod(bytes( - cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - ))), - ) - - for cert in ( - self.ca_cert, - self.sender256_cert, - self.recipient256_cert, - self.sender512_cert, - self.recipient512_cert, - ): - self.assertTrue(verify( - self.curve256, - self.ca_pub, - GOST34112012256(cert["tbsCertificate"].encode()).digest()[::-1], - bytes(cert["signatureValue"]), - )) - - def test_signed_with_attrs(self): - ci = ContentInfo().decod(b64decode(""" -MIIENwYJKoZIhvcNAQcCoIIEKDCCBCQCAQExDDAKBggqhQMHAQECAzA7BgkqhkiG -9w0BBwGgLgQsyu7t8vDu6/zt++kg7/Do7OXwIOTr/yDx8vDz6vLz8PsgU2lnbmVk -RGF0YS6gggI6MIICNjCCAeOgAwIBAgIEAYy6hDAKBggqhQMHAQEDAjA4MQ0wCwYD -VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1i -aXQwHhcNMDEwMTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRU -SzI2MSowKAYDVQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDUxMi1iaXQw -gaowIQYIKoUDBwEBAQIwFQYJKoUDBwECAQIBBggqhQMHAQECAwOBhAAEgYC0i7da -vCkOGGVcYqFPtS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO+K21LDpYVfDP -s2Sqa13ZN+Ts/JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0EmZf8T3ae/J1Jo -6xGunecH1/G4hMts9HYLnxbwJDMNVGuIHV6gzqOBhTCBgjBhBgNVHQEEWjBYgBSA -2Qz3mfhmTZNTiY7AnnEtp6cxEqE6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMT -HkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQU -K+l9HAscONGxzCcRpxRAmFHvlXowCgYIKoUDBwEBAwIDQQAbjA0Q41/rIKOOvjHK -sAsoEJM+WJf6/PKXg2JaStthmw99bdtwwkU/qDbcje2tF6mt+XWyQBXwvfeES1GF -Y9fJMYIBlDCCAZACAQEwQDA4MQ0wCwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBU -SzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQCBAGMuoQwCgYIKoUDBwEBAgOgga0w -GAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzIw -MTk1NTIyWjAiBgkqhkiG9w0BCWIxFQQTU2lnbmVkIGF0dHIncyB2YWx1ZTBPBgkq -hkiG9w0BCQQxQgRAUdPHEukF5BIfo9DoQIMdnB0ZLkzq0RueEUZSNv07A7C+GKWi -G62fueArg8uPCHPTUN6d/42p33fgMkEwH7f7cDAKBggqhQMHAQEBAgSBgGUnVka8 -FvTlClmOtj/FUUacBdE/nEBeMLOO/535VDYrXlftPE6zQf/4ghS7TQG2VRGQ3GWD -+L3+W09A7d5uyyTEbvgtdllUG0OyqFwKmJEaYsMin87SFVs0cn1PGV1fOKeLluZa -bLx5whxd+mzlpekL5i6ImRX+TpERxrA/xSe5 -""")) - _, sd = ci["content"].defined - content = bytes(sd["encapContentInfo"]["eContent"]) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры SignedData."), - ) - si = sd["signerInfos"][0] - self.assertEqual( - si["digestAlgorithm"]["algorithm"], - id_tc26_gost3411_2012_512, - ) - digest = [ - bytes(attr["attrValues"][0].defined[1]) for attr in si["signedAttrs"] - if attr["attrType"] == id_messageDigest - ][0] - self.assertSequenceEqual(digest, GOST34112012512(content).digest()) - self.assertTrue(verify( - self.curve512, - self.sender512_pub, - GOST34112012512( - SignedAttributes(si["signedAttrs"]).encode() - ).digest()[::-1], - bytes(si["signature"]), - )) - - def test_signed_without_attrs(self): - ci = ContentInfo().decod(b64decode(""" -MIIDAQYJKoZIhvcNAQcCoIIC8jCCAu4CAQExDDAKBggqhQMHAQECAjA7BgkqhkiG -9w0BBwGgLgQsyu7t8vDu6/zt++kg7/Do7OXwIOTr/yDx8vDz6vLz8PsgU2lnbmVk -RGF0YS6gggH3MIIB8zCCAaCgAwIBAgIEAYy6gjAKBggqhQMHAQEDAjA4MQ0wCwYD -VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1i -aXQwHhcNMDEwMTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRU -SzI2MSowKAYDVQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQw -aDAhBggqhQMHAQEBATAVBgkqhQMHAQIBAQEGCCqFAwcBAQICA0MABECWKQ0TYllq -g4GmY3tBJiyzpXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZ -huJaJfqZ6VbTo4GFMIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJjsCecS2npzES -oTowODENMAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4x -MC0xMiAyNTYtYml0ggQBjLqBMB0GA1UdDgQWBBTRnChHSWbQYwnJC62n2zu5Njd0 -3zAKBggqhQMHAQEDAgNBAB41oijaXSEn58l78y2rhxY35/lKEq4XWZ70FtsNlVxW -ATyzgO5Wliwnt1O4GoZsxx8r6T/i7VG65UNmQlwdOKQxgaIwgZ8CAQEwQDA4MQ0w -CwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1 -Ni1iaXQCBAGMuoIwCgYIKoUDBwEBAgIwCgYIKoUDBwEBAQEEQC6jZPA59szL9FiA -0wC71EBE42ap6gKxklT800cu2FvbLu972GJYNSI7+UeanVU37OVWyenEXi2E5HkU -94kBe8Q= -""")) - _, sd = ci["content"].defined - content = bytes(sd["encapContentInfo"]["eContent"]) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры SignedData."), - ) - si = sd["signerInfos"][0] - self.assertEqual( - si["digestAlgorithm"]["algorithm"], - id_tc26_gost3411_2012_256, - ) - self.assertTrue(verify( - self.curve256, - self.sender256_pub, - GOST34112012256(content).digest()[::-1], - bytes(si["signature"]), - )) - - def test_kari_ephemeral(self): - ci = ContentInfo().decod(b64decode(""" -MIIB/gYJKoZIhvcNAQcDoIIB7zCCAesCAQIxggFioYIBXgIBA6CBo6GBoDAXBggq -hQMHAQEBAjALBgkqhQMHAQIBAgEDgYQABIGAe+itJVNbHM35RHfzuwFJPYdPXqtW -8hNEF7Z/XFEE2T71SRkhFX7ozYKQNh/TkVY9D4vG0LnD9Znr/pJyOjpsNb+dPcKX -Kbk/0JQxoPGHxFzASVAFq0ov/yBe2XGFWMeKUqtaAr7SvoYS0oEhT5EuT8BXmecd -nRe7NqOzESpb15ahIgQgsqHxOcdOp03l11S7k3OH1k1HNa5F8m9ctrOzH2846FMw -FwYJKoUDBwEBBwIBMAoGCCqFAwcBAQYCMHYwdDBAMDgxDTALBgNVBAoTBFRLMjYx -JzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdAIEAYy6hQQw -SxLc18zMwzLwXbcKqYhV/VzsdBgVArOHsSBIbaThJWE7zI37VGPMQJM5VXJ7GVcL -MF0GCSqGSIb3DQEHATAfBgkqhQMHAQEFAgIwEgQQ6EeVlADDCz2cdEWKy+tM94Av -yIFl/Ie4VeFFuczTsMsIaOUEe3Jn9GeVp8hZSj3O2q4hslQ/u/+Gj4QkSHm/M0ih -ITAfBgkqhQMHAQAGAQExEgQQs1t6D3J3WCEvxunnEE15NQ== -""")) - _, ed = ci["content"].defined - kari = ed["recipientInfos"][0]["kari"] - orig_key = kari["originator"]["originatorKey"] - self.assertEqual(orig_key["algorithm"]["algorithm"], id_tc26_gost3410_2012_512) - self.assertEqual( - GostR34102012PublicKeyParameters().decod( - bytes(orig_key["algorithm"]["parameters"]) - )["publicKeyParamSet"], - id_tc26_gost3410_2012_512_paramSetA, - ) - orig_pub = pub_unmarshal( - bytes(OctetString().decod(bytes(orig_key["publicKey"]))), - ) - ukm = bytes(kari["ukm"]) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_wrap_kexp15, - ) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_512, - ) - kexp = bytes(kari["recipientEncryptedKeys"][0]["encryptedKey"]) - keymat = keg(self.curve512, self.recipient512_prv, orig_pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Kuznechik(kek).encrypt, - GOST3412Kuznechik(kim).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - ukm[24:24 + GOST3412Kuznechik.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm_omac, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - self.assertEqual(ed["unprotectedAttrs"][0]["attrType"], id_cms_mac_attr) - encrypted_mac = bytes(ed["unprotectedAttrs"][0]["attrValues"][0].defined[1]) - encrypted_content = bytes(eci["encryptedContent"]) - cek_enc, cek_mac = kdf_tree_gostr3411_2012_256( - cek, b"kdf tree", eci_ukm[GOST3412Kuznechik.blocksize // 2:], 2, - ) - content_and_tag = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(cek_enc).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - encrypted_content + encrypted_mac, - eci_ukm[:GOST3412Kuznechik.blocksize // 2], - ) - content = content_and_tag[:-GOST3412Kuznechik.blocksize] - tag_expected = content_and_tag[-GOST3412Kuznechik.blocksize:] - self.assertSequenceEqual( - omac( - GOST3412Kuznechik(cek_mac).encrypt, - GOST3412Kuznechik.blocksize, - content, - ), - tag_expected, - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_kari_static(self): - ci = ContentInfo().decod(b64decode(""" -MIIBawYJKoZIhvcNAQcDoIIBXDCCAVgCAQIxgfehgfQCAQOgQjBAMDgxDTALBgNV -BAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJp -dAIEAYy6gqEiBCBvcfyuSF57y8vVyaw8Z0ch3wjC4lPKTrpVRXty4Rhk5DAXBgkq -hQMHAQEHAQEwCgYIKoUDBwEBBgEwbjBsMEAwODENMAsGA1UEChMEVEsyNjEnMCUG -A1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0AgQBjLqDBChPbi6B -krXuLPexPAL2oUGCFWDGQHqINL5ExuMBG7/5XQRqriKARVa0MFkGCSqGSIb3DQEH -ATAbBgkqhQMHAQEFAQEwDgQMdNdCKnYAAAAwqTEDgC9O2bYyTGQJ8WUQGq0zHwzX -L0jFhWHTF1tcAxYmd9pX5i89UwIxhtYqyjX1QHju2g== -""")) - _, ed = ci["content"].defined - kari = ed["recipientInfos"][0]["kari"] - ukm = bytes(kari["ukm"]) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_wrap_kexp15, - ) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_256, - ) - kexp = bytes(kari["recipientEncryptedKeys"][0]["encryptedKey"]) - keymat = keg( - self.curve256, - self.recipient256_prv, - self.sender256_pub, - ukm, - ) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Magma(kek).encrypt, - GOST3412Magma(kim).encrypt, - GOST3412Magma.blocksize, - kexp, - ukm[24:24 + GOST3412Magma.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_ctracpkm, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(cek).encrypt, - 8 * 1024, - GOST3412Magma.blocksize, - bytes(eci["encryptedContent"]), - eci_ukm[:GOST3412Magma.blocksize // 2], - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_ktri_256(self): - ci = ContentInfo().decod(b64decode(""" -MIIBlQYJKoZIhvcNAQcDoIIBhjCCAYICAQAxggEcMIIBGAIBADBAMDgxDTALBgNV -BAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJp -dAIEAYy6gzAXBgkqhQMHAQEHAgEwCgYIKoUDBwEBBgEEgbcwgbQEMFiMredFR3Mv -3g2wqyVXRnrhYEBMNFaqqgBpHwPQh3bF98tt9HZPxRDCww0OPfxeuTBeMBcGCCqF -AwcBAQEBMAsGCSqFAwcBAgEBAQNDAARAdFJ9ww+3ptvQiaQpizCldNYhl4DB1rl8 -Fx/2FIgnwssCbYRQ+UuRsTk9dfLLTGJG3JIEXKFxXWBgOrK965A5pAQg9f2/EHxG -DfetwCe1a6uUDCWD+wp5dYOpfkry8YRDEJgwXQYJKoZIhvcNAQcBMB8GCSqFAwcB -AQUCATASBBDUHNxmVclO/v3OaY9P7jxOgC+sD9CHGlEMRUpfGn6yfFDMExmYeby8 -LzdPJe1MkYV0qQgdC1zI3nQ7/4taf+4zRA== -""")) - _, ed = ci["content"].defined - ktri = ed["recipientInfos"][0]["ktri"] - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_wrap_kexp15, - ) - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_256, - ) - _, encrypted_key = ktri["encryptedKey"].defined - self.assertEqual( - encrypted_key["ephemeralPublicKey"]["algorithm"]["algorithm"], - id_tc26_gost3410_2012_256, - ) - pub = pub_unmarshal(bytes(OctetString().decod( - bytes(encrypted_key["ephemeralPublicKey"]["subjectPublicKey"]) - ))) - ukm = bytes(encrypted_key["ukm"]) - kexp = bytes(encrypted_key["encryptedKey"]) - keymat = keg(self.curve256, self.recipient256_prv, pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Kuznechik(kek).encrypt, - GOST3412Kuznechik(kim).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - ukm[24:24 + GOST3412Kuznechik.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(cek).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - bytes(eci["encryptedContent"]), - eci_ukm[:GOST3412Kuznechik.blocksize // 2], - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_ktri_512(self): - ci = ContentInfo().decod(b64decode(""" -MIIB5wYJKoZIhvcNAQcDoIIB2DCCAdQCAQAxggFXMIIBUwIBADBAMDgxDTALBgNVBAoTBFRL -MjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdAIEAYy6hTAXBgkq -hQMHAQEHAQEwCgYIKoUDBwEBBgIEgfIwge8EKDof9JLTJVuIfP+c+imDCGyOLtAYENkoXpeU -CdiGn0Lt65t3TN9G0bUwgaAwFwYIKoUDBwEBAQIwCwYJKoUDBwECAQIBA4GEAASBgDD9XXHn -0j4EwY3DGB1wzHeThPRDlCwIvpmqWy00QDhS3fLRWiETSe9uMLeg27zI/EiserKMasNZum/i -d09cmP8aTNIDNRtI5H9M0mH7LpEtY8L901MszvOKHLDYdemvz0JUqOvBtvoeQ6sV4Gl45zXx -HTzBWlBw1FLX/ITWLapaBCAa09foTeA+PObBznGuCOPoKy+xz/9IIVmZidI6EYkIrzBZBgkq -hkiG9w0BBwEwGwYJKoUDBwEBBQECMA4EDA4z1UwRL4WYzKFX/oAv8eEX3fWt6hxDpjO0rI7/ -CiJ/CwYGCKODJ9h63vAwlsWwcPwAjxcsLvCNlv6i4NqhGTAXBgkqhQMHAQAGAQExCgQIs2DT -LuZ22Yw= -""")) - _, ed = ci["content"].defined - ktri = ed["recipientInfos"][0]["ktri"] - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_wrap_kexp15, - ) - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_512, - ) - _, encrypted_key = ktri["encryptedKey"].defined - self.assertEqual( - encrypted_key["ephemeralPublicKey"]["algorithm"]["algorithm"], - id_tc26_gost3410_2012_512, - ) - pub = pub_unmarshal( - bytes(OctetString().decod( - bytes(encrypted_key["ephemeralPublicKey"]["subjectPublicKey"]) - )), - ) - ukm = bytes(encrypted_key["ukm"]) - kexp = bytes(encrypted_key["encryptedKey"]) - keymat = keg(self.curve512, self.recipient512_prv, pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Magma(kek).encrypt, - GOST3412Magma(kim).encrypt, - GOST3412Magma.blocksize, - kexp, - ukm[24:24 + GOST3412Magma.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_ctracpkm_omac, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - self.assertEqual(ed["unprotectedAttrs"][0]["attrType"], id_cms_mac_attr) - encrypted_mac = bytes(ed["unprotectedAttrs"][0]["attrValues"][0].defined[1]) - encrypted_content = bytes(eci["encryptedContent"]) - cek_enc, cek_mac = kdf_tree_gostr3411_2012_256( - cek, b"kdf tree", eci_ukm[GOST3412Magma.blocksize // 2:], 2, - ) - content_and_tag = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(cek_enc).encrypt, - 8 * 1024, - GOST3412Magma.blocksize, - encrypted_content + encrypted_mac, - eci_ukm[:GOST3412Magma.blocksize // 2], - ) - content = content_and_tag[:-GOST3412Magma.blocksize] - tag_expected = content_and_tag[-GOST3412Magma.blocksize:] - self.assertSequenceEqual( - omac( - GOST3412Magma(cek_mac).encrypt, - GOST3412Magma.blocksize, - content, - ), - tag_expected, - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_digested256(self): - ci = ContentInfo().decod(b64decode(""" -MH0GCSqGSIb3DQEHBaBwMG4CAQAwCgYIKoUDBwEBAgIwOwYJKoZIhvcNAQcBoC4ELMru7fLw -7uv87fvpIO/w6Ozl8CDk6/8g8fLw8+ry8/D7IERpZ2VzdERhdGEuBCD/esPQYsGkzxZV8uUM -IAWt6SI8KtxBP8NyG8AGbJ8i/Q== -""")) - _, dd = ci["content"].defined - eci = dd["encapContentInfo"] - self.assertSequenceEqual( - GOST34112012256(bytes(eci["eContent"])).digest(), - bytes(dd["digest"]), - ) - - def test_digested512(self): - ci = ContentInfo().decod(b64decode(""" -MIGfBgkqhkiG9w0BBwWggZEwgY4CAQAwCgYIKoUDBwEBAgMwOwYJKoZIhvcNAQcBoC4ELMru -7fLw7uv87fvpIO/w6Ozl8CDk6/8g8fLw8+ry8/D7IERpZ2VzdERhdGEuBEDe4VUvcKSRvU7R -FVhFjajXY+nJSUkUsoi3oOeJBnru4PErt8RusPrCJs614ciHCM+ehrC4a+M1Nbq77F/Wsa/v -""")) - _, dd = ci["content"].defined - eci = dd["encapContentInfo"] - self.assertSequenceEqual( - GOST34112012512(bytes(eci["eContent"])).digest(), - bytes(dd["digest"]), - ) - - def test_encrypted_kuznechik(self): - ci = ContentInfo().decod(b64decode(""" -MHEGCSqGSIb3DQEHBqBkMGICAQAwXQYJKoZIhvcNAQcBMB8GCSqFAwcBAQUCATASBBBSwX+z -yOEPPuGyfpsRG4AigC/P8ftTdQMStfIThVkE/vpJlwaHgGv83m2bsPayeyuqpoTeEMOaqGcO -0MxHWsC9hQ== -""")) - _, ed = ci["content"].defined - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm, - ) - ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(self.psk).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - bytes(eci["encryptedContent"]), - ukm[:GOST3412Kuznechik.blocksize // 2], - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EncryptedData."), - ) - - def test_encrypted_magma(self): - ci = ContentInfo().decod(b64decode(""" -MIGIBgkqhkiG9w0BBwagezB5AgEAMFkGCSqGSIb3DQEHATAbBgkqhQMHAQEFAQIwDgQMuncO -u3uYPbI30vFCgC9Nsws4R09yLp6jUtadncWUPZGmCGpPKnXGgNHvEmUArgKJvu4FPHtLkHuL -eQXZg6EZMBcGCSqFAwcBAAYBATEKBAjCbQoH632oGA== -""")) - _, ed = ci["content"].defined - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_ctracpkm_omac, - ) - ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - self.assertEqual(ed["unprotectedAttrs"][0]["attrType"], id_cms_mac_attr) - encrypted_mac = bytes(ed["unprotectedAttrs"][0]["attrValues"][0].defined[1]) - cek_enc, cek_mac = kdf_tree_gostr3411_2012_256( - self.psk, b"kdf tree", ukm[GOST3412Magma.blocksize // 2:], 2, - ) - content_and_tag = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(cek_enc).encrypt, - 8 * 1024, - GOST3412Magma.blocksize, - bytes(eci["encryptedContent"]) + encrypted_mac, - ukm[:GOST3412Magma.blocksize // 2], - ) - content = content_and_tag[:-GOST3412Magma.blocksize] - tag_expected = content_and_tag[-GOST3412Magma.blocksize:] - self.assertSequenceEqual( - omac( - GOST3412Magma(cek_mac).encrypt, - GOST3412Magma.blocksize, - content, - ), - tag_expected, - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EncryptedData."), - ) diff --git a/pygost-5.13/build/lib/pygost/test_gost28147.py b/pygost-5.13/build/lib/pygost/test_gost28147.py deleted file mode 100644 index a83e930..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost28147.py +++ /dev/null @@ -1,384 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost28147 import block2ns -from pygost.gost28147 import BLOCKSIZE -from pygost.gost28147 import cbc_decrypt -from pygost.gost28147 import cbc_encrypt -from pygost.gost28147 import cfb_decrypt -from pygost.gost28147 import cfb_encrypt -from pygost.gost28147 import cnt -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost28147 import ecb_decrypt -from pygost.gost28147 import ecb_encrypt -from pygost.gost28147 import encrypt -from pygost.gost28147 import KEYSIZE -from pygost.gost28147 import MESH_MAX_DATA -from pygost.gost28147 import ns2block -from pygost.utils import hexdec -from pygost.utils import strxor - - -class ECBTest(TestCase): - def test_gcl(self): - """Test vectors from libgcl3 - """ - sbox = "id-Gost28147-89-TestParamSet" - key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd") - plaintext = bytes(bytearray(( - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, - 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, - 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, - 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, - 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, - 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, - 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, - 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, - 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, - 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, - 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, - 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, - 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, - 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, - 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, - 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, - 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0, - 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8, - 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0, - 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8, - 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, - 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, - 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, - 0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8, - 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, - 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, - ))) - ciphertext = bytes(bytearray(( - 0x4b, 0x8c, 0x4c, 0x98, 0x15, 0xf2, 0x4a, 0xea, - 0x1e, 0xc3, 0x57, 0x09, 0xb3, 0xbc, 0x2e, 0xd1, - 0xe0, 0xd1, 0xf2, 0x22, 0x65, 0x2d, 0x59, 0x18, - 0xf7, 0xdf, 0xfc, 0x80, 0x4b, 0xde, 0x5c, 0x68, - 0x46, 0x53, 0x75, 0x53, 0xa7, 0x46, 0x0d, 0xec, - 0x05, 0x1f, 0x1b, 0xd3, 0x0a, 0x63, 0x1a, 0xb7, - 0x78, 0xc4, 0x43, 0xe0, 0x5d, 0x3e, 0xa4, 0x0e, - 0x2d, 0x7e, 0x23, 0xa9, 0x1b, 0xc9, 0x02, 0xbc, - 0x21, 0x0c, 0x84, 0xcb, 0x0d, 0x0a, 0x07, 0xc8, - 0x7b, 0xd0, 0xfb, 0xb5, 0x1a, 0x14, 0x04, 0x5c, - 0xa2, 0x53, 0x97, 0x71, 0x2e, 0x5c, 0xc2, 0x8f, - 0x39, 0x3f, 0x6f, 0x52, 0xf2, 0x30, 0x26, 0x4e, - 0x8c, 0xe0, 0xd1, 0x01, 0x75, 0x6d, 0xdc, 0xd3, - 0x03, 0x79, 0x1e, 0xca, 0xd5, 0xc1, 0x0e, 0x12, - 0x53, 0x0a, 0x78, 0xe2, 0x0a, 0xb1, 0x1c, 0xea, - 0x3a, 0xf8, 0x55, 0xb9, 0x7c, 0xe1, 0x0b, 0xba, - 0xa0, 0xc8, 0x96, 0xeb, 0x50, 0x5a, 0xd3, 0x60, - 0x43, 0xa3, 0x0f, 0x98, 0xdb, 0xd9, 0x50, 0x6d, - 0x63, 0x91, 0xaf, 0x01, 0x40, 0xe9, 0x75, 0x5a, - 0x46, 0x5c, 0x1f, 0x19, 0x4a, 0x0b, 0x89, 0x9b, - 0xc4, 0xf6, 0xf8, 0xf5, 0x2f, 0x87, 0x3f, 0xfa, - 0x26, 0xd4, 0xf8, 0x25, 0xba, 0x1f, 0x98, 0x82, - 0xfc, 0x26, 0xaf, 0x2d, 0xc0, 0xf9, 0xc4, 0x58, - 0x49, 0xfa, 0x09, 0x80, 0x02, 0x62, 0xa4, 0x34, - 0x2d, 0xcb, 0x5a, 0x6b, 0xab, 0x61, 0x5d, 0x08, - 0xd4, 0x26, 0xe0, 0x08, 0x13, 0xd6, 0x2e, 0x02, - 0x2a, 0x37, 0xe8, 0xd0, 0xcf, 0x36, 0xf1, 0xc7, - 0xc0, 0x3f, 0x9b, 0x21, 0x60, 0xbd, 0x29, 0x2d, - 0x2e, 0x01, 0x48, 0x4e, 0xf8, 0x8f, 0x20, 0x16, - 0x8a, 0xbf, 0x82, 0xdc, 0x32, 0x7a, 0xa3, 0x18, - 0x69, 0xd1, 0x50, 0x59, 0x31, 0x91, 0xf2, 0x6c, - 0x5a, 0x5f, 0xca, 0x58, 0x9a, 0xb2, 0x2d, 0xb2, - ))) - encrypted = ecb_encrypt(key, plaintext, sbox=sbox) - self.assertSequenceEqual(encrypted, ciphertext) - decrypted = ecb_decrypt(key, encrypted, sbox=sbox) - self.assertSequenceEqual(decrypted, plaintext) - - def test_cryptopp(self): - """Test vectors from Crypto++ 5.6.2 - """ - sbox = "AppliedCryptography" - data = ( - (b"BE5EC2006CFF9DCF52354959F1FF0CBFE95061B5A648C10387069C25997C0672", b"0DF82802B741A292", b"07F9027DF7F7DF89"), - (b"B385272AC8D72A5A8B344BC80363AC4D09BF58F41F540624CBCB8FDCF55307D7", b"1354EE9C0A11CD4C", b"4FB50536F960A7B1"), - (b"AEE02F609A35660E4097E546FD3026B032CD107C7D459977ADF489BEF2652262", b"6693D492C4B0CC39", b"670034AC0FA811B5"), - (b"320E9D8422165D58911DFC7D8BBB1F81B0ECD924023BF94D9DF7DCF7801240E0", b"99E2D13080928D79", b"8118FF9D3B3CFE7D"), - (b"C9F703BBBFC63691BFA3B7B87EA8FD5E8E8EF384EF733F1A61AEF68C8FFA265F", b"D1E787749C72814C", b"A083826A790D3E0C"), - (b"728FEE32F04B4C654AD7F607D71C660C2C2670D7C999713233149A1C0C17A1F0", b"D4C05323A4F7A7B5", b"4D1F2E6B0D9DE2CE"), - (b"35FC96402209500FCFDEF5352D1ABB038FE33FC0D9D58512E56370B22BAA133B", b"8742D9A05F6A3AF6", b"2F3BB84879D11E52"), - (b"D416F630BE65B7FE150656183370E07018234EE5DA3D89C4CE9152A03E5BFB77", b"F86506DA04E41CB8", b"96F0A5C77A04F5CE"), - ) - for key, pt, ct in data: - key = hexdec(key) - pt = hexdec(pt) - ct = hexdec(ct) - self.assertSequenceEqual(ecb_encrypt(key, pt, sbox=sbox), ct) - - def test_cryptomanager(self): - """Test vector from http://cryptomanager.com/tv.html - """ - sbox = "id-GostR3411-94-TestParamSet" - key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B") - self.assertSequenceEqual( - ecb_encrypt(key, hexdec(b"1122334455667788"), sbox=sbox), - hexdec(b"03251E14F9D28ACB"), - ) - - -class CFBTest(TestCase): - def test_cryptomanager(self): - """Test vector from http://cryptomanager.com/tv.html - """ - key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B") - sbox = "id-GostR3411-94-TestParamSet" - self.assertSequenceEqual( - cfb_encrypt( - key, - hexdec(b"112233445566778899AABBCCDD800000"), - iv=hexdec(b"0102030405060708"), - sbox=sbox, - ), - hexdec(b"6EE84586DD2BCA0CAD3616940E164242"), - ) - self.assertSequenceEqual( - cfb_decrypt( - key, - hexdec(b"6EE84586DD2BCA0CAD3616940E164242"), - iv=hexdec(b"0102030405060708"), - sbox=sbox, - ), - hexdec(b"112233445566778899AABBCCDD800000"), - ) - - def test_steps(self): - """Check step-by-step operation manually - """ - key = urandom(KEYSIZE) - iv = urandom(BLOCKSIZE) - plaintext = urandom(20) - ciphertext = cfb_encrypt(key, plaintext, iv) - - # First full block - step = encrypt(DEFAULT_SBOX, key, block2ns(iv)) - step = strxor(plaintext[:8], ns2block(step)) - self.assertSequenceEqual(step, ciphertext[:8]) - - # Second full block - step = encrypt(DEFAULT_SBOX, key, block2ns(step)) - step = strxor(plaintext[8:16], ns2block(step)) - self.assertSequenceEqual(step, ciphertext[8:16]) - - # Third non-full block - step = encrypt(DEFAULT_SBOX, key, block2ns(step)) - step = strxor(plaintext[16:] + 4 * b"\x00", ns2block(step)) - self.assertSequenceEqual(step[:4], ciphertext[16:]) - - def test_random(self): - """Random data with various sizes - """ - key = urandom(KEYSIZE) - iv = urandom(BLOCKSIZE) - for size in (5, 8, 16, 120): - pt = urandom(size) - self.assertSequenceEqual( - cfb_decrypt(key, cfb_encrypt(key, pt, iv), iv), - pt, - ) - - -class CTRTest(TestCase): - def test_gcl(self): - """Test vectors from libgcl3 - """ - sbox = "id-Gost28147-89-TestParamSet" - key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd") - plaintext = bytes(bytearray(( - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, - 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, - 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, - 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, - 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, - 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, - 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, - 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, - 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, - 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, - 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, - 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, - 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, - 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, - 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, - 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, - 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0, - 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8, - 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0, - 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8, - 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, - 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, - 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, - 0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8, - 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, - 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0xff, 0xfe, 0xfd, 0xfc, 0xfb, - ))) - ciphertext = bytes(bytearray(( - 0x4a, 0x5e, 0x37, 0x6c, 0xa1, 0x12, 0xd3, 0x55, - 0x09, 0x13, 0x1a, 0x21, 0xac, 0xfb, 0xb2, 0x1e, - 0x8c, 0x24, 0x9b, 0x57, 0x20, 0x68, 0x46, 0xd5, - 0x23, 0x2a, 0x26, 0x35, 0x12, 0x56, 0x5c, 0x69, - 0x2a, 0x2f, 0xd1, 0xab, 0xbd, 0x45, 0xdc, 0x3a, - 0x1a, 0xa4, 0x57, 0x64, 0xd5, 0xe4, 0x69, 0x6d, - 0xb4, 0x8b, 0xf1, 0x54, 0x78, 0x3b, 0x10, 0x8f, - 0x7a, 0x4b, 0x32, 0xe0, 0xe8, 0x4c, 0xbf, 0x03, - 0x24, 0x37, 0x95, 0x6a, 0x55, 0xa8, 0xce, 0x6f, - 0x95, 0x62, 0x12, 0xf6, 0x79, 0xe6, 0xf0, 0x1b, - 0x86, 0xef, 0x36, 0x36, 0x05, 0xd8, 0x6f, 0x10, - 0xa1, 0x41, 0x05, 0x07, 0xf8, 0xfa, 0xa4, 0x0b, - 0x17, 0x2c, 0x71, 0xbc, 0x8b, 0xcb, 0xcf, 0x3d, - 0x74, 0x18, 0x32, 0x0b, 0x1c, 0xd2, 0x9e, 0x75, - 0xba, 0x3e, 0x61, 0xe1, 0x61, 0x96, 0xd0, 0xee, - 0x8f, 0xf2, 0x9a, 0x5e, 0xb7, 0x7a, 0x15, 0xaa, - 0x4e, 0x1e, 0x77, 0x7c, 0x99, 0xe1, 0x41, 0x13, - 0xf4, 0x60, 0x39, 0x46, 0x4c, 0x35, 0xde, 0x95, - 0xcc, 0x4f, 0xd5, 0xaf, 0xd1, 0x4d, 0x84, 0x1a, - 0x45, 0xc7, 0x2a, 0xf2, 0x2c, 0xc0, 0xb7, 0x94, - 0xa3, 0x08, 0xb9, 0x12, 0x96, 0xb5, 0x97, 0x99, - 0x3a, 0xb7, 0x0c, 0x14, 0x56, 0xb9, 0xcb, 0x49, - 0x44, 0xa9, 0x93, 0xa9, 0xfb, 0x19, 0x10, 0x8c, - 0x6a, 0x68, 0xe8, 0x7b, 0x06, 0x57, 0xf0, 0xef, - 0x88, 0x44, 0xa6, 0xd2, 0x98, 0xbe, 0xd4, 0x07, - 0x41, 0x37, 0x45, 0xa6, 0x71, 0x36, 0x76, 0x69, - 0x4b, 0x75, 0x15, 0x33, 0x90, 0x29, 0x6e, 0x33, - 0xcb, 0x96, 0x39, 0x78, 0x19, 0x2e, 0x96, 0xf3, - 0x49, 0x4c, 0x89, 0x3d, 0xa1, 0x86, 0x82, 0x00, - 0xce, 0xbd, 0x54, 0x29, 0x65, 0x00, 0x1d, 0x16, - 0x13, 0xc3, 0xfe, 0x1f, 0x8c, 0x55, 0x63, 0x09, - 0x1f, 0xcd, 0xd4, 0x28, 0xca, - ))) - iv = b"\x02\x01\x01\x01\x01\x01\x01\x01" - encrypted = cnt(key, plaintext, iv=iv, sbox=sbox) - self.assertSequenceEqual(encrypted, ciphertext) - decrypted = cnt(key, encrypted, iv=iv, sbox=sbox) - self.assertSequenceEqual(decrypted, plaintext) - - def test_gcl2(self): - """Test vectors 2 from libgcl3 - """ - sbox = "id-Gost28147-89-TestParamSet" - key = hexdec(b"fc7ad2886f455b50d29008fa622b57d5c65b3c637202025799cadf0768519e8a") - plaintext = bytes(bytearray(( - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, - 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, - 0xff, 0xfe, 0xfd, 0xfc, 0xfb, - ))) - ciphertext = bytes(bytearray(( - 0xd0, 0xbe, 0x60, 0x1a, 0x2c, 0xf1, 0x90, 0x26, - 0x9b, 0x7b, 0x23, 0xb4, 0xd2, 0xcc, 0xe1, 0x15, - 0xf6, 0x05, 0x57, 0x28, 0x88, 0x75, 0xeb, 0x1e, - 0xd3, 0x62, 0xdc, 0xda, 0x9b, 0x62, 0xee, 0x9a, - 0x57, 0x87, 0x8a, 0xf1, 0x82, 0x37, 0x9c, 0x7f, - 0x13, 0xcc, 0x55, 0x38, 0xb5, 0x63, 0x32, 0xc5, - 0x23, 0xa4, 0xcb, 0x7d, 0x51, - ))) - iv = BLOCKSIZE * b"\x00" - encrypted = cnt(key, plaintext, iv=iv, sbox=sbox) - self.assertSequenceEqual(encrypted, ciphertext) - decrypted = cnt(key, encrypted, iv=iv, sbox=sbox) - self.assertSequenceEqual(decrypted, plaintext) - - -class CBCTest(TestCase): - def test_pad_requirement(self): - key = KEYSIZE * b"x" - for s in (b"", b"foo", b"foobarbaz"): - with self.assertRaises(ValueError): - cbc_encrypt(key, s, pad=False) - with self.assertRaises(ValueError): - cbc_decrypt(key, s, pad=False) - - def test_passes(self): - iv = urandom(BLOCKSIZE) - key = KEYSIZE * b"x" - for pt in (b"foo", b"foobarba", b"foobarbaz", 16 * b"x"): - ct = cbc_encrypt(key, pt, iv) - dt = cbc_decrypt(key, ct) - self.assertSequenceEqual(pt, dt) - - def test_iv_existence_check(self): - key = KEYSIZE * b"x" - with self.assertRaises(ValueError): - cbc_decrypt(key, BLOCKSIZE * b"x") - iv = urandom(BLOCKSIZE) - cbc_decrypt(key, cbc_encrypt(key, BLOCKSIZE * b"x", iv)) - - def test_meshing(self): - pt = urandom(MESH_MAX_DATA * 3) - key = urandom(KEYSIZE) - ct = cbc_encrypt(key, pt) - dt = cbc_decrypt(key, ct) - self.assertSequenceEqual(pt, dt) - - -class CFBMeshingTest(TestCase): - def setUp(self): - self.key = urandom(KEYSIZE) - self.iv = urandom(BLOCKSIZE) - - def test_single(self): - pt = b"\x00" - ct = cfb_encrypt(self.key, pt, mesh=True) - dec = cfb_decrypt(self.key, ct, mesh=True) - self.assertSequenceEqual(pt, dec) - - def test_short(self): - pt = urandom(MESH_MAX_DATA - 1) - ct = cfb_encrypt(self.key, pt, mesh=True) - dec = cfb_decrypt(self.key, ct, mesh=True) - dec_plain = cfb_decrypt(self.key, ct) - self.assertSequenceEqual(pt, dec) - self.assertSequenceEqual(pt, dec_plain) - - def test_short_iv(self): - pt = urandom(MESH_MAX_DATA - 1) - ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True) - dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True) - dec_plain = cfb_decrypt(self.key, ct, iv=self.iv) - self.assertSequenceEqual(pt, dec) - self.assertSequenceEqual(pt, dec_plain) - - def test_longer_iv(self): - pt = urandom(MESH_MAX_DATA * 3) - ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True) - dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True) - dec_plain = cfb_decrypt(self.key, ct, iv=self.iv) - self.assertSequenceEqual(pt, dec) - self.assertNotEqual(pt, dec_plain) diff --git a/pygost-5.13/build/lib/pygost/test_gost28147_mac.py b/pygost-5.13/build/lib/pygost/test_gost28147_mac.py deleted file mode 100644 index ec1af3f..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost28147_mac.py +++ /dev/null @@ -1,63 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import TestCase - -from pygost.gost28147_mac import MAC - - -class TestMAC(TestCase): - """Test vectors generated with libgcl3 library - """ - k = b"This is message\xFF length\x0032 bytes" - - def test_a(self): - self.assertSequenceEqual( - MAC(self.k, b"a").hexdigest(), - "bd5d3b5b2b7b57af", - ) - - def test_abc(self): - self.assertSequenceEqual( - MAC(self.k, b"abc").hexdigest(), - "28661e40805b1ff9", - ) - - def test_128U(self): - self.assertSequenceEqual( - MAC(self.k, 128 * b"U").hexdigest(), - "1a06d1bad74580ef", - ) - - def test_13x(self): - self.assertSequenceEqual( - MAC(self.k, 13 * b"x").hexdigest(), - "917ee1f1a668fbd3", - ) - - def test_parts(self): - m = MAC(self.k) - m.update(b"foo") - m.update(b"bar") - self.assertSequenceEqual(m.digest(), MAC(self.k, b"foobar").digest()) - - def test_copy(self): - m = MAC(self.k, b"foo") - c = m.copy() - m.update(b"barbaz") - c.update(b"bar") - c.update(b"baz") - self.assertSequenceEqual(m.digest(), c.digest()) diff --git a/pygost-5.13/build/lib/pygost/test_gost3410.py b/pygost-5.13/build/lib/pygost/test_gost3410.py deleted file mode 100644 index cd71535..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost3410.py +++ /dev/null @@ -1,495 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost3410 import CURVES -from pygost.gost3410 import GOST3410Curve -from pygost.gost3410 import prv_marshal -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410 import sign -from pygost.gost3410 import uv2xy -from pygost.gost3410 import verify -from pygost.gost3410 import xy2uv -from pygost.utils import bytes2long -from pygost.utils import hexdec -from pygost.utils import hexenc -from pygost.utils import long2bytes - - -class Test341001(TestCase): - def test_rfc(self): - """Test vector from :rfc:`5832` - """ - prv = bytes(bytearray(( - 0x7A, 0x92, 0x9A, 0xDE, 0x78, 0x9B, 0xB9, 0xBE, - 0x10, 0xED, 0x35, 0x9D, 0xD3, 0x9A, 0x72, 0xC1, - 0x1B, 0x60, 0x96, 0x1F, 0x49, 0x39, 0x7E, 0xEE, - 0x1D, 0x19, 0xCE, 0x98, 0x91, 0xEC, 0x3B, 0x28 - ))) - pub_x = bytes(bytearray(( - 0x7F, 0x2B, 0x49, 0xE2, 0x70, 0xDB, 0x6D, 0x90, - 0xD8, 0x59, 0x5B, 0xEC, 0x45, 0x8B, 0x50, 0xC5, - 0x85, 0x85, 0xBA, 0x1D, 0x4E, 0x9B, 0x78, 0x8F, - 0x66, 0x89, 0xDB, 0xD8, 0xE5, 0x6F, 0xD8, 0x0B - ))) - pub_y = bytes(bytearray(( - 0x26, 0xF1, 0xB4, 0x89, 0xD6, 0x70, 0x1D, 0xD1, - 0x85, 0xC8, 0x41, 0x3A, 0x97, 0x7B, 0x3C, 0xBB, - 0xAF, 0x64, 0xD1, 0xC5, 0x93, 0xD2, 0x66, 0x27, - 0xDF, 0xFB, 0x10, 0x1A, 0x87, 0xFF, 0x77, 0xDA - ))) - digest = bytes(bytearray(( - 0x2D, 0xFB, 0xC1, 0xB3, 0x72, 0xD8, 0x9A, 0x11, - 0x88, 0xC0, 0x9C, 0x52, 0xE0, 0xEE, 0xC6, 0x1F, - 0xCE, 0x52, 0x03, 0x2A, 0xB1, 0x02, 0x2E, 0x8E, - 0x67, 0xEC, 0xE6, 0x67, 0x2B, 0x04, 0x3E, 0xE5 - ))) - signature = bytes(bytearray(( - 0x41, 0xAA, 0x28, 0xD2, 0xF1, 0xAB, 0x14, 0x82, - 0x80, 0xCD, 0x9E, 0xD5, 0x6F, 0xED, 0xA4, 0x19, - 0x74, 0x05, 0x35, 0x54, 0xA4, 0x27, 0x67, 0xB8, - 0x3A, 0xD0, 0x43, 0xFD, 0x39, 0xDC, 0x04, 0x93, - 0x01, 0x45, 0x6C, 0x64, 0xBA, 0x46, 0x42, 0xA1, - 0x65, 0x3C, 0x23, 0x5A, 0x98, 0xA6, 0x02, 0x49, - 0xBC, 0xD6, 0xD3, 0xF7, 0x46, 0xB6, 0x31, 0xDF, - 0x92, 0x80, 0x14, 0xF6, 0xC5, 0xBF, 0x9C, 0x40 - ))) - prv = bytes2long(prv) - signature = signature[32:] + signature[:32] - - c = CURVES["id-GostR3410-2001-TestParamSet"] - pubX, pubY = public_key(c, prv) - self.assertSequenceEqual(long2bytes(pubX), pub_x) - self.assertSequenceEqual(long2bytes(pubY), pub_y) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - self.assertTrue(verify(c, (pubX, pubY), digest, signature)) - - def test_sequence(self): - c = CURVES["id-GostR3410-2001-TestParamSet"] - prv = prv_unmarshal(urandom(32)) - pubX, pubY = public_key(c, prv_unmarshal(prv_marshal(c, prv))) - for _ in range(20): - digest = urandom(32) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - - -class Test34102012(TestCase): - def test_1(self): - """Test vector from 34.10-2012 standard itself - """ - curve = CURVES["id-GostR3410-2001-TestParamSet"] - prv = bytes2long(hexdec("7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28")) - digest = hexdec("2DFBC1B372D89A1188C09C52E0EEC61FCE52032AB1022E8E67ECE6672B043EE5") - rand = hexdec("77105C9B20BCD3122823C8CF6FCC7B956DE33814E95B7FE64FED924594DCEAB3") - signature = sign(curve, prv, digest, rand) - r = "41aa28d2f1ab148280cd9ed56feda41974053554a42767b83ad043fd39dc0493" - s = "01456c64ba4642a1653c235a98a60249bcd6d3f746b631df928014f6c5bf9c40" - self.assertSequenceEqual(hexenc(signature), s + r) - - def test_2(self): - """Test vector from 34.10-2012 standard itself - """ - curve = GOST3410Curve( - p=3623986102229003635907788753683874306021320925534678605086546150450856166624002482588482022271496854025090823603058735163734263822371964987228582907372403, - q=3623986102229003635907788753683874306021320925534678605086546150450856166623969164898305032863068499961404079437936585455865192212970734808812618120619743, - a=7, - b=1518655069210828534508950034714043154928747527740206436194018823352809982443793732829756914785974674866041605397883677596626326413990136959047435811826396, - x=1928356944067022849399309401243137598997786635459507974357075491307766592685835441065557681003184874819658004903212332884252335830250729527632383493573274, - y=2288728693371972859970012155529478416353562327329506180314497425931102860301572814141997072271708807066593850650334152381857347798885864807605098724013854, - ) - prv = bytes2long(hexdec("0BA6048AADAE241BA40936D47756D7C93091A0E8514669700EE7508E508B102072E8123B2200A0563322DAD2827E2714A2636B7BFD18AADFC62967821FA18DD4")) - digest = hexdec("3754F3CFACC9E0615C4F4A7C4D8DAB531B09B6F9C170C533A71D147035B0C5917184EE536593F4414339976C647C5D5A407ADEDB1D560C4FC6777D2972075B8C") - rand = hexdec("0359E7F4B1410FEACC570456C6801496946312120B39D019D455986E364F365886748ED7A44B3E794434006011842286212273A6D14CF70EA3AF71BB1AE679F1") - signature = sign(curve, prv, digest, rand) - r = "2f86fa60a081091a23dd795e1e3c689ee512a3c82ee0dcc2643c78eea8fcacd35492558486b20f1c9ec197c90699850260c93bcbcd9c5c3317e19344e173ae36" - s = "1081b394696ffe8e6585e7a9362d26b6325f56778aadbc081c0bfbe933d52ff5823ce288e8c4f362526080df7f70ce406a6eeb1f56919cb92a9853bde73e5b4a" - self.assertSequenceEqual(hexenc(signature), s + r) - - def test_gcl3(self): - """Test vector from libgcl3 - """ - p = bytes2long(bytes(bytearray(( - 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7, - 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80, - 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04, - 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D, - 0xF1, 0xD8, 0x52, 0x74, 0x1A, 0xF4, 0x70, 0x4A, - 0x04, 0x58, 0x04, 0x7E, 0x80, 0xE4, 0x54, 0x6D, - 0x35, 0xB8, 0x33, 0x6F, 0xAC, 0x22, 0x4D, 0xD8, - 0x16, 0x64, 0xBB, 0xF5, 0x28, 0xBE, 0x63, 0x73, - )))) - q = bytes2long(bytes(bytearray(( - 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7, - 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80, - 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04, - 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D, - 0xA8, 0x2F, 0x2D, 0x7E, 0xCB, 0x1D, 0xBA, 0xC7, - 0x19, 0x90, 0x5C, 0x5E, 0xEC, 0xC4, 0x23, 0xF1, - 0xD8, 0x6E, 0x25, 0xED, 0xBE, 0x23, 0xC5, 0x95, - 0xD6, 0x44, 0xAA, 0xF1, 0x87, 0xE6, 0xE6, 0xDF, - )))) - a = bytes2long(bytes(bytearray(( - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - )))) - b = bytes2long(bytes(bytearray(( - 0x1C, 0xFF, 0x08, 0x06, 0xA3, 0x11, 0x16, 0xDA, - 0x29, 0xD8, 0xCF, 0xA5, 0x4E, 0x57, 0xEB, 0x74, - 0x8B, 0xC5, 0xF3, 0x77, 0xE4, 0x94, 0x00, 0xFD, - 0xD7, 0x88, 0xB6, 0x49, 0xEC, 0xA1, 0xAC, 0x43, - 0x61, 0x83, 0x40, 0x13, 0xB2, 0xAD, 0x73, 0x22, - 0x48, 0x0A, 0x89, 0xCA, 0x58, 0xE0, 0xCF, 0x74, - 0xBC, 0x9E, 0x54, 0x0C, 0x2A, 0xDD, 0x68, 0x97, - 0xFA, 0xD0, 0xA3, 0x08, 0x4F, 0x30, 0x2A, 0xDC, - )))) - x = bytes2long(bytes(bytearray(( - 0x24, 0xD1, 0x9C, 0xC6, 0x45, 0x72, 0xEE, 0x30, - 0xF3, 0x96, 0xBF, 0x6E, 0xBB, 0xFD, 0x7A, 0x6C, - 0x52, 0x13, 0xB3, 0xB3, 0xD7, 0x05, 0x7C, 0xC8, - 0x25, 0xF9, 0x10, 0x93, 0xA6, 0x8C, 0xD7, 0x62, - 0xFD, 0x60, 0x61, 0x12, 0x62, 0xCD, 0x83, 0x8D, - 0xC6, 0xB6, 0x0A, 0xA7, 0xEE, 0xE8, 0x04, 0xE2, - 0x8B, 0xC8, 0x49, 0x97, 0x7F, 0xAC, 0x33, 0xB4, - 0xB5, 0x30, 0xF1, 0xB1, 0x20, 0x24, 0x8A, 0x9A, - )))) - y = bytes2long(bytes(bytearray(( - 0x2B, 0xB3, 0x12, 0xA4, 0x3B, 0xD2, 0xCE, 0x6E, - 0x0D, 0x02, 0x06, 0x13, 0xC8, 0x57, 0xAC, 0xDD, - 0xCF, 0xBF, 0x06, 0x1E, 0x91, 0xE5, 0xF2, 0xC3, - 0xF3, 0x24, 0x47, 0xC2, 0x59, 0xF3, 0x9B, 0x2C, - 0x83, 0xAB, 0x15, 0x6D, 0x77, 0xF1, 0x49, 0x6B, - 0xF7, 0xEB, 0x33, 0x51, 0xE1, 0xEE, 0x4E, 0x43, - 0xDC, 0x1A, 0x18, 0xB9, 0x1B, 0x24, 0x64, 0x0B, - 0x6D, 0xBB, 0x92, 0xCB, 0x1A, 0xDD, 0x37, 0x1E, - )))) - prv = bytes(bytearray(( - 0x0B, 0xA6, 0x04, 0x8A, 0xAD, 0xAE, 0x24, 0x1B, - 0xA4, 0x09, 0x36, 0xD4, 0x77, 0x56, 0xD7, 0xC9, - 0x30, 0x91, 0xA0, 0xE8, 0x51, 0x46, 0x69, 0x70, - 0x0E, 0xE7, 0x50, 0x8E, 0x50, 0x8B, 0x10, 0x20, - 0x72, 0xE8, 0x12, 0x3B, 0x22, 0x00, 0xA0, 0x56, - 0x33, 0x22, 0xDA, 0xD2, 0x82, 0x7E, 0x27, 0x14, - 0xA2, 0x63, 0x6B, 0x7B, 0xFD, 0x18, 0xAA, 0xDF, - 0xC6, 0x29, 0x67, 0x82, 0x1F, 0xA1, 0x8D, 0xD4, - ))) - pub_x = bytes(bytearray(( - 0x11, 0x5D, 0xC5, 0xBC, 0x96, 0x76, 0x0C, 0x7B, - 0x48, 0x59, 0x8D, 0x8A, 0xB9, 0xE7, 0x40, 0xD4, - 0xC4, 0xA8, 0x5A, 0x65, 0xBE, 0x33, 0xC1, 0x81, - 0x5B, 0x5C, 0x32, 0x0C, 0x85, 0x46, 0x21, 0xDD, - 0x5A, 0x51, 0x58, 0x56, 0xD1, 0x33, 0x14, 0xAF, - 0x69, 0xBC, 0x5B, 0x92, 0x4C, 0x8B, 0x4D, 0xDF, - 0xF7, 0x5C, 0x45, 0x41, 0x5C, 0x1D, 0x9D, 0xD9, - 0xDD, 0x33, 0x61, 0x2C, 0xD5, 0x30, 0xEF, 0xE1, - ))) - pub_y = bytes(bytearray(( - 0x37, 0xC7, 0xC9, 0x0C, 0xD4, 0x0B, 0x0F, 0x56, - 0x21, 0xDC, 0x3A, 0xC1, 0xB7, 0x51, 0xCF, 0xA0, - 0xE2, 0x63, 0x4F, 0xA0, 0x50, 0x3B, 0x3D, 0x52, - 0x63, 0x9F, 0x5D, 0x7F, 0xB7, 0x2A, 0xFD, 0x61, - 0xEA, 0x19, 0x94, 0x41, 0xD9, 0x43, 0xFF, 0xE7, - 0xF0, 0xC7, 0x0A, 0x27, 0x59, 0xA3, 0xCD, 0xB8, - 0x4C, 0x11, 0x4E, 0x1F, 0x93, 0x39, 0xFD, 0xF2, - 0x7F, 0x35, 0xEC, 0xA9, 0x36, 0x77, 0xBE, 0xEC, - ))) - digest = bytes(bytearray(( - 0x37, 0x54, 0xF3, 0xCF, 0xAC, 0xC9, 0xE0, 0x61, - 0x5C, 0x4F, 0x4A, 0x7C, 0x4D, 0x8D, 0xAB, 0x53, - 0x1B, 0x09, 0xB6, 0xF9, 0xC1, 0x70, 0xC5, 0x33, - 0xA7, 0x1D, 0x14, 0x70, 0x35, 0xB0, 0xC5, 0x91, - 0x71, 0x84, 0xEE, 0x53, 0x65, 0x93, 0xF4, 0x41, - 0x43, 0x39, 0x97, 0x6C, 0x64, 0x7C, 0x5D, 0x5A, - 0x40, 0x7A, 0xDE, 0xDB, 0x1D, 0x56, 0x0C, 0x4F, - 0xC6, 0x77, 0x7D, 0x29, 0x72, 0x07, 0x5B, 0x8C, - ))) - signature = bytes(bytearray(( - 0x2F, 0x86, 0xFA, 0x60, 0xA0, 0x81, 0x09, 0x1A, - 0x23, 0xDD, 0x79, 0x5E, 0x1E, 0x3C, 0x68, 0x9E, - 0xE5, 0x12, 0xA3, 0xC8, 0x2E, 0xE0, 0xDC, 0xC2, - 0x64, 0x3C, 0x78, 0xEE, 0xA8, 0xFC, 0xAC, 0xD3, - 0x54, 0x92, 0x55, 0x84, 0x86, 0xB2, 0x0F, 0x1C, - 0x9E, 0xC1, 0x97, 0xC9, 0x06, 0x99, 0x85, 0x02, - 0x60, 0xC9, 0x3B, 0xCB, 0xCD, 0x9C, 0x5C, 0x33, - 0x17, 0xE1, 0x93, 0x44, 0xE1, 0x73, 0xAE, 0x36, - 0x10, 0x81, 0xB3, 0x94, 0x69, 0x6F, 0xFE, 0x8E, - 0x65, 0x85, 0xE7, 0xA9, 0x36, 0x2D, 0x26, 0xB6, - 0x32, 0x5F, 0x56, 0x77, 0x8A, 0xAD, 0xBC, 0x08, - 0x1C, 0x0B, 0xFB, 0xE9, 0x33, 0xD5, 0x2F, 0xF5, - 0x82, 0x3C, 0xE2, 0x88, 0xE8, 0xC4, 0xF3, 0x62, - 0x52, 0x60, 0x80, 0xDF, 0x7F, 0x70, 0xCE, 0x40, - 0x6A, 0x6E, 0xEB, 0x1F, 0x56, 0x91, 0x9C, 0xB9, - 0x2A, 0x98, 0x53, 0xBD, 0xE7, 0x3E, 0x5B, 0x4A, - ))) - prv = bytes2long(prv) - signature = signature[64:] + signature[:64] - c = GOST3410Curve(p, q, a, b, x, y) - pubX, pubY = public_key(c, prv) - self.assertSequenceEqual(long2bytes(pubX), pub_x) - self.assertSequenceEqual(long2bytes(pubY), pub_y) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - self.assertTrue(verify(c, (pubX, pubY), digest, signature)) - - def test_sequence(self): - c = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - prv = bytes2long(urandom(64)) - pubX, pubY = public_key(c, prv_unmarshal(prv_marshal(c, prv))) - for _ in range(20): - digest = urandom(64) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - self.assertNotIn(b"\x00" * 8, s) - - -class TestUVXYConversion(TestCase): - """Twisted Edwards to Weierstrass coordinates conversion and vice versa - """ - def test_curve1(self): - c = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - u, v = (0x0D, bytes2long(hexdec("60CA1E32AA475B348488C38FAB07649CE7EF8DBE87F22E81F92B2592DBA300E7"))) - self.assertEqual(uv2xy(c, u, v), (c.x, c.y)) - self.assertEqual(xy2uv(c, c.x, c.y), (u, v)) - - def test_curve2(self): - c = CURVES["id-tc26-gost-3410-2012-512-paramSetC"] - u, v = (0x12, bytes2long(hexdec("469AF79D1FB1F5E16B99592B77A01E2A0FDFB0D01794368D9A56117F7B38669522DD4B650CF789EEBF068C5D139732F0905622C04B2BAAE7600303EE73001A3D"))) - self.assertEqual(uv2xy(c, u, v), (c.x, c.y)) - self.assertEqual(xy2uv(c, c.x, c.y), (u, v)) - - -class Test34102012SESPAKE(TestCase): - """Test vectors for multiplication from :rfc:`8133` - """ - def test_curve1(self): - c = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] - q_ind = ( - 0xA69D51CAF1A309FA9E9B66187759B0174C274E080356F23CFCBFE84D396AD7BB, - 0x5D26F29ECC2E9AC0404DCF7986FA55FE94986362170F54B9616426A659786DAC, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x59495655D1E7C7424C622485F575CCF121F3122D274101E8AB734CC9C9A9B45E, - 0x48D1C311D33C9B701F3B03618562A4A07A044E3AF31E3999E67B487778B53C62, - ) - ) - self.assertEqual( - c.exp(0x1F2538097D5A031FA68BBB43C84D12B3DE47B7061C0D5E24993E0C873CDBA6B3), - ( - 0xBBC77CF42DC1E62D06227935379B4AA4D14FEA4F565DDF4CB4FA4D31579F9676, - 0x8E16604A4AFDF28246684D4996274781F6CB80ABBBA1414C1513EC988509DABF, - ) - ) - self.assertEqual( - c.exp(0xDC497D9EF6324912FD367840EE509A2032AEDB1C0A890D133B45F596FCCBD45D), - ( - 0x6097341C1BE388E83E7CA2DF47FAB86E2271FD942E5B7B2EB2409E49F742BC29, - 0xC81AA48BDB4CA6FA0EF18B9788AE25FE30857AA681B3942217F9FED151BAB7D0, - ), - ) - - def test_curve2(self): - c = CURVES["id-GostR3410-2001-CryptoPro-B-ParamSet"] - q_ind = ( - 0x3D715A874A4B17CB3B517893A9794A2B36C89D2FFC693F01EE4CC27E7F49E399, - 0x1C5A641FCF7CE7E87CDF8CEA38F3DB3096EACE2FAD158384B53953365F4FE7FE, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x6DC2AE26BC691FCA5A73D9C452790D15E34BA5404D92955B914C8D2662ABB985, - 0x3B02AAA9DD65AE30C335CED12F3154BBAC059F66B088306747453EDF6E5DB077, - ) - ) - self.assertEqual( - c.exp(0x499D72B90299CAB0DA1F8BE19D9122F622A13B32B730C46BD0664044F2144FAD), - ( - 0x61D6F916DB717222D74877F179F7EBEF7CD4D24D8C1F523C048E34A1DF30F8DD, - 0x3EC48863049CFCFE662904082E78503F4973A4E105E2F1B18C69A5E7FB209000, - ) - ) - self.assertEqual( - c.exp(0x0F69FF614957EF83668EDC2D7ED614BE76F7B253DB23C5CC9C52BF7DF8F4669D), - ( - 0x33BC6F7E9C0BA10CFB2B72546C327171295508EA97F8C8BA9F890F2478AB4D6C, - 0x75D57B396C396F492F057E9222CCC686437A2AAD464E452EF426FC8EEED1A4A6, - ), - ) - - def test_curve3(self): - c = CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"] - q_ind = ( - 0x1E36383E43BB6CFA2917167D71B7B5DD3D6D462B43D7C64282AE67DFBEC2559D, - 0x137478A9F721C73932EA06B45CF72E37EB78A63F29A542E563C614650C8B6399, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x945821DAF91E158B839939630655A3B21FF3E146D27041E86C05650EB3B46B59, - 0x3A0C2816AC97421FA0E879605F17F0C9C3EB734CFF196937F6284438D70BDC48, - ) - ) - self.assertEqual( - c.exp(0x3A54AC3F19AD9D0B1EAC8ACDCEA70E581F1DAC33D13FEAFD81E762378639C1A8), - ( - 0x96B7F09C94D297C257A7DA48364C0076E59E48D221CBA604AE111CA3933B446A, - 0x54E4953D86B77ECCEB578500931E822300F7E091F79592CA202A020D762C34A6, - ) - ) - self.assertEqual( - c.exp(0x448781782BF7C0E52A1DD9E6758FD3482D90D3CFCCF42232CF357E59A4D49FD4), - ( - 0x4B9C0AB55A938121F282F48A2CC4396EB16E7E0068B495B0C1DD4667786A3EB7, - 0x223460AA8E09383E9DF9844C5A0F2766484738E5B30128A171B69A77D9509B96, - ), - ) - - def test_curve4(self): - c = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - q_ind = ( - 0x2A17F8833A32795327478871B5C5E88AEFB91126C64B4B8327289BEA62559425D18198F133F400874328B220C74497CD240586CB249E158532CB8090776CD61C, - 0x728F0C4A73B48DA41CE928358FAD26B47A6E094E9362BAE82559F83CDDC4EC3A4676BD3707EDEAF4CD85E99695C64C241EDC622BE87DC0CF87F51F4367F723C5, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x0C0AB53D0E0A9C607CAD758F558915A0A7DC5DC87B45E9A58FDDF30EC3385960283E030CD322D9E46B070637785FD49D2CD711F46807A24C40AF9A42C8E2D740, - 0xDF93A8012B86D3A3D4F8A4D487DA15FC739EB31B20B3B0E8C8C032AAF8072C6337CF7D5B404719E5B4407C41D9A3216A08CA69C271484E9ED72B8AAA52E28B8B, - ) - ) - self.assertEqual( - c.exp(0x3CE54325DB52FE798824AEAD11BB16FA766857D04A4AF7D468672F16D90E7396046A46F815693E85B1CE5464DA9270181F82333B0715057BBE8D61D400505F0E), - ( - 0xB93093EB0FCC463239B7DF276E09E592FCFC9B635504EA4531655D76A0A3078E2B4E51CFE2FA400CC5DE9FBE369DB204B3E8ED7EDD85EE5CCA654C1AED70E396, - 0x809770B8D910EA30BD2FA89736E91DC31815D2D9B31128077EEDC371E9F69466F497DC64DD5B1FADC587F860EE256109138C4A9CD96B628E65A8F590520FC882, - ) - ) - self.assertEqual( - c.exp(0xB5C286A79AA8E97EC0E19BC1959A1D15F12F8C97870BA9D68CC12811A56A3BB11440610825796A49D468CDC9C2D02D76598A27973D5960C5F50BCE28D8D345F4), - ( - 0x238B38644E440452A99FA6B93D9FD7DA0CB83C32D3C1E3CFE5DF5C3EB0F9DB91E588DAEDC849EA2FB867AE855A21B4077353C0794716A6480995113D8C20C7AF, - 0xB2273D5734C1897F8D15A7008B862938C8C74CA7E877423D95243EB7EBD02FD2C456CF9FC956F078A59AA86F19DD1075E5167E4ED35208718EA93161C530ED14, - ), - ) - - def test_curve5(self): - c = CURVES["id-tc26-gost-3410-12-512-paramSetB"] - q_ind = ( - 0x7E1FAE8285E035BEC244BEF2D0E5EBF436633CF50E55231DEA9C9CF21D4C8C33DF85D4305DE92971F0A4B4C07E00D87BDBC720EB66E49079285AAF12E0171149, - 0x2CC89998B875D4463805BA0D858A196592DB20AB161558FF2F4EF7A85725D20953967AE621AFDEAE89BB77C83A2528EF6FCE02F68BDA4679D7F2704947DBC408, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x7D03E65B8050D1E12CBB601A17B9273B0E728F5021CD47C8A4DD822E4627BA5F9C696286A2CDDA9A065509866B4DEDEDC4A118409604AD549F87A60AFA621161, - 0x16037DAD45421EC50B00D50BDC6AC3B85348BC1D3A2F85DB27C3373580FEF87C2C743B7ED30F22BE22958044E716F93A61CA3213A361A2797A16A3AE62957377, - ) - ) - self.assertEqual( - c.exp(0x715E893FA639BF341296E0623E6D29DADF26B163C278767A7982A989462A3863FE12AEF8BD403D59C4DC4720570D4163DB0805C7C10C4E818F9CB785B04B9997), - ( - 0x10C479EA1C04D3C2C02B0576A9C42D96226FF033C1191436777F66916030D87D02FB93738ED7669D07619FFCE7C1F3C4DB5E5DF49E2186D6FA1E2EB5767602B9, - 0x039F6044191404E707F26D59D979136A831CCE43E1C5F0600D1DDF8F39D0CA3D52FBD943BF04DDCED1AA2CE8F5EBD7487ACDEF239C07D015084D796784F35436, - ) - ) - self.assertEqual( - c.exp(0x30FA8C2B4146C2DBBE82BED04D7378877E8C06753BD0A0FF71EBF2BEFE8DA8F3DC0836468E2CE7C5C961281B6505140F8407413F03C2CB1D201EA1286CE30E6D), - ( - 0x34C0149E7BB91AE377B02573FCC48AF7BFB7B16DEB8F9CE870F384688E3241A3A868588CC0EF4364CCA67D17E3260CD82485C202ADC76F895D5DF673B1788E67, - 0x608E944929BD643569ED5189DB871453F13333A1EAF82B2FE1BE8100E775F13DD9925BD317B63BFAF05024D4A738852332B64501195C1B2EF789E34F23DDAFC5, - ), - ) - - def test_curve6(self): - c = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - q_ind = ( - 0xB51ADF93A40AB15792164FAD3352F95B66369EB2A4EF5EFAE32829320363350E, - 0x74A358CC08593612F5955D249C96AFB7E8B0BB6D8BD2BBE491046650D822BE18, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0xDBF99827078956812FA48C6E695DF589DEF1D18A2D4D35A96D75BF6854237629, - 0x9FDDD48BFBC57BEE1DA0CFF282884F284D471B388893C48F5ECB02FC18D67589, - ) - ) - self.assertEqual( - c.exp(0x147B72F6684FB8FD1B418A899F7DBECAF5FCE60B13685BAA95328654A7F0707F), - ( - 0x33FBAC14EAE538275A769417829C431BD9FA622B6F02427EF55BD60EE6BC2888, - 0x22F2EBCF960A82E6CDB4042D3DDDA511B2FBA925383C2273D952EA2D406EAE46, - ) - ) - self.assertEqual( - c.exp(0x30D5CFADAA0E31B405E6734C03EC4C5DF0F02F4BA25C9A3B320EE6453567B4CB), - ( - 0x2B2D89FAB735433970564F2F28CFA1B57D640CB902BC6334A538F44155022CB2, - 0x10EF6A82EEF1E70F942AA81D6B4CE5DEC0DDB9447512962874870E6F2849A96F, - ), - ) - - def test_curve7(self): - c = CURVES["id-tc26-gost-3410-2012-512-paramSetC"] - q_ind = ( - 0x489C91784E02E98F19A803ABCA319917F37689E5A18965251CE2FF4E8D8B298F5BA7470F9E0E713487F96F4A8397B3D09A270C9D367EB5E0E6561ADEEB51581D, - 0x684EA885ACA64EAF1B3FEE36C0852A3BE3BD8011B0EF18E203FF87028D6EB5DB2C144A0DCC71276542BFD72CA2A43FA4F4939DA66D9A60793C704A8C94E16F18, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x0185AE6271A81BB7F236A955F7CAA26FB63849813C0287D96C83A15AE6B6A86467AB13B6D88CE8CD7DC2E5B97FF5F28FAC2C108F2A3CF3DB5515C9E6D7D210E8, - 0xED0220F92EF771A71C64ECC77986DB7C03D37B3E2AB3E83F32CE5E074A762EC08253C9E2102B87532661275C4B1D16D2789CDABC58ACFDF7318DE70AB64F09B8, - ) - ) - self.assertEqual( - c.exp(0x332F930421D14CFE260042159F18E49FD5A54167E94108AD80B1DE60B13DE7999A34D611E63F3F870E5110247DF8EC7466E648ACF385E52CCB889ABF491EDFF0), - ( - 0x561655966D52952E805574F4281F1ED3A2D498932B00CBA9DECB42837F09835BFFBFE2D84D6B6B242FE7B57F92E1A6F2413E12DDD6383E4437E13D72693469AD, - 0xF6B18328B2715BD7F4178615273A36135BC0BF62F7D8BB9F080164AD36470AD03660F51806C64C6691BADEF30F793720F8E3FEAED631D6A54A4C372DCBF80E82, - ) - ) - self.assertEqual( - c.exp(0x38481771E7D054F96212686B613881880BD8A6C89DDBC656178F014D2C093432A033EE10415F13A160D44C2AD61E6E2E05A7F7EC286BCEA3EA4D4D53F8634FA2), - ( - 0xB7C5818687083433BC1AFF61CB5CA79E38232025E0C1F123B8651E62173CE6873F3E6FFE7281C2E45F4F524F66B0C263616ED08FD210AC4355CA3292B51D71C3, - 0x497F14205DBDC89BDDAF50520ED3B1429AD30777310186BE5E68070F016A44E0C766DB08E8AC23FBDFDE6D675AA4DF591EB18BA0D348DF7AA40973A2F1DCFA55, - ), - ) diff --git a/pygost-5.13/build/lib/pygost/test_gost3410_vko.py b/pygost-5.13/build/lib/pygost/test_gost3410_vko.py deleted file mode 100644 index a8e298e..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost3410_vko.py +++ /dev/null @@ -1,125 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410_vko import kek_34102001 -from pygost.gost3410_vko import kek_34102012256 -from pygost.gost3410_vko import kek_34102012512 -from pygost.gost3410_vko import ukm_unmarshal -from pygost.utils import bytes2long -from pygost.utils import hexdec - - -class TestVKO34102001(TestCase): - def test_vector(self): - curve = CURVES["id-GostR3410-2001-TestParamSet"] - ukm = ukm_unmarshal(hexdec("5172be25f852a233")) - prv1 = prv_unmarshal(hexdec("1df129e43dab345b68f6a852f4162dc69f36b2f84717d08755cc5c44150bf928")) - prv2 = prv_unmarshal(hexdec("5b9356c6474f913f1e83885ea0edd5df1a43fd9d799d219093241157ac9ed473")) - kek = hexdec("ee4618a0dbb10cb31777b4b86a53d9e7ef6cb3e400101410f0c0f2af46c494a6") - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - self.assertSequenceEqual(kek_34102001(curve, prv1, pub2, ukm), kek) - self.assertSequenceEqual(kek_34102001(curve, prv2, pub1, ukm), kek) - - def test_sequence(self): - curve = CURVES["id-GostR3410-2001-TestParamSet"] - for _ in range(10): - ukm = ukm_unmarshal(urandom(8)) - prv1 = bytes2long(urandom(32)) - prv2 = bytes2long(urandom(32)) - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - kek1 = kek_34102001(curve, prv1, pub2, ukm) - kek2 = kek_34102001(curve, prv2, pub1, ukm) - self.assertSequenceEqual(kek1, kek2) - kek1 = kek_34102001(curve, prv1, pub1, ukm) - kek2 = kek_34102001(curve, prv2, pub2, ukm) - self.assertNotEqual(kek1, kek2) - - -class TestVKO34102012256(TestCase): - """RFC 7836 - """ - def test_vector(self): - curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - ukm = ukm_unmarshal(hexdec("1d80603c8544c727")) - prvA = prv_unmarshal(hexdec("c990ecd972fce84ec4db022778f50fcac726f46708384b8d458304962d7147f8c2db41cef22c90b102f2968404f9b9be6d47c79692d81826b32b8daca43cb667")) - pubA = pub_unmarshal(hexdec("aab0eda4abff21208d18799fb9a8556654ba783070eba10cb9abb253ec56dcf5d3ccba6192e464e6e5bcb6dea137792f2431f6c897eb1b3c0cc14327b1adc0a7914613a3074e363aedb204d38d3563971bd8758e878c9db11403721b48002d38461f92472d40ea92f9958c0ffa4c93756401b97f89fdbe0b5e46e4a4631cdb5a")) - prvB = prv_unmarshal(hexdec("48c859f7b6f11585887cc05ec6ef1390cfea739b1a18c0d4662293ef63b79e3b8014070b44918590b4b996acfea4edfbbbcccc8c06edd8bf5bda92a51392d0db")) - pubB = pub_unmarshal(hexdec("192fe183b9713a077253c72c8735de2ea42a3dbc66ea317838b65fa32523cd5efca974eda7c863f4954d1147f1f2b25c395fce1c129175e876d132e94ed5a65104883b414c9b592ec4dc84826f07d0b6d9006dda176ce48c391e3f97d102e03bb598bf132a228a45f7201aba08fc524a2d77e43a362ab022ad4028f75bde3b79")) - vko = hexdec("c9a9a77320e2cc559ed72dce6f47e2192ccea95fa648670582c054c0ef36c221") - self.assertSequenceEqual(kek_34102012256(curve, prvA, pubB, ukm), vko) - self.assertSequenceEqual(kek_34102012256(curve, prvB, pubA, ukm), vko) - - def test_sequence(self): - curve = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - for _ in range(10): - ukm = ukm_unmarshal(urandom(8)) - prv1 = bytes2long(urandom(32)) - prv2 = bytes2long(urandom(32)) - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - kek1 = kek_34102012256(curve, prv1, pub2, ukm) - kek2 = kek_34102012256(curve, prv2, pub1, ukm) - self.assertSequenceEqual(kek1, kek2) - kek1 = kek_34102012256(curve, prv1, pub1, ukm) - kek2 = kek_34102012256(curve, prv2, pub2, ukm) - self.assertNotEqual(kek1, kek2) - - def test_pub_is_not_on_curve(self): - with self.assertRaises(ValueError): - kek_34102012256( - CURVES["id-tc26-gost-3410-2012-256-paramSetA"], - bytes2long(urandom(32)), - pub_unmarshal(urandom(64)), - ) - - -class TestVKO34102012512(TestCase): - """RFC 7836 - """ - def test_vector(self): - curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - ukm = ukm_unmarshal(hexdec("1d80603c8544c727")) - prvA = prv_unmarshal(hexdec("c990ecd972fce84ec4db022778f50fcac726f46708384b8d458304962d7147f8c2db41cef22c90b102f2968404f9b9be6d47c79692d81826b32b8daca43cb667")) - pubA = pub_unmarshal(hexdec("aab0eda4abff21208d18799fb9a8556654ba783070eba10cb9abb253ec56dcf5d3ccba6192e464e6e5bcb6dea137792f2431f6c897eb1b3c0cc14327b1adc0a7914613a3074e363aedb204d38d3563971bd8758e878c9db11403721b48002d38461f92472d40ea92f9958c0ffa4c93756401b97f89fdbe0b5e46e4a4631cdb5a")) - prvB = prv_unmarshal(hexdec("48c859f7b6f11585887cc05ec6ef1390cfea739b1a18c0d4662293ef63b79e3b8014070b44918590b4b996acfea4edfbbbcccc8c06edd8bf5bda92a51392d0db")) - pubB = pub_unmarshal(hexdec("192fe183b9713a077253c72c8735de2ea42a3dbc66ea317838b65fa32523cd5efca974eda7c863f4954d1147f1f2b25c395fce1c129175e876d132e94ed5a65104883b414c9b592ec4dc84826f07d0b6d9006dda176ce48c391e3f97d102e03bb598bf132a228a45f7201aba08fc524a2d77e43a362ab022ad4028f75bde3b79")) - vko = hexdec("79f002a96940ce7bde3259a52e015297adaad84597a0d205b50e3e1719f97bfa7ee1d2661fa9979a5aa235b558a7e6d9f88f982dd63fc35a8ec0dd5e242d3bdf") - self.assertSequenceEqual(kek_34102012512(curve, prvA, pubB, ukm), vko) - self.assertSequenceEqual(kek_34102012512(curve, prvB, pubA, ukm), vko) - - def test_sequence(self): - curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - for _ in range(10): - ukm = ukm_unmarshal(urandom(8)) - prv1 = bytes2long(urandom(32)) - prv2 = bytes2long(urandom(32)) - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - kek1 = kek_34102012512(curve, prv1, pub2, ukm) - kek2 = kek_34102012512(curve, prv2, pub1, ukm) - self.assertSequenceEqual(kek1, kek2) - kek1 = kek_34102012512(curve, prv1, pub1, ukm) - kek2 = kek_34102012512(curve, prv2, pub2, ukm) - self.assertNotEqual(kek1, kek2) diff --git a/pygost-5.13/build/lib/pygost/test_gost34112012.py b/pygost-5.13/build/lib/pygost/test_gost34112012.py deleted file mode 100644 index c7c2df9..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost34112012.py +++ /dev/null @@ -1,159 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from random import randint -from unittest import skip -from unittest import TestCase -import hmac - -from pygost import gost34112012256 -from pygost import gost34112012512 -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost34112012512 import pbkdf2 -from pygost.utils import hexdec -from pygost.utils import hexenc - - -class TestCopy(TestCase): - def runTest(self): - m = GOST34112012256() - c = m.copy() - m.update(b"foobar") - c.update(b"foo") - c.update(b"bar") - self.assertSequenceEqual(m.digest(), c.digest()) - - -class TestSymmetric(TestCase): - def runTest(self): - chunks = [] - for _ in range(randint(1, 10)): - chunks.append(urandom(randint(20, 80))) - m = GOST34112012256() - for chunk in chunks: - m.update(chunk) - self.assertSequenceEqual( - m.hexdigest(), - GOST34112012256(b"".join(chunks)).hexdigest(), - ) - - -class TestHMAC(TestCase): - """RFC 7836 - """ - def test_256(self): - for digestmod in (GOST34112012256, gost34112012256): - self.assertSequenceEqual( - hmac.new( - key=hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - msg=hexdec("0126bdb87800af214341456563780100"), - digestmod=digestmod, - ).hexdigest(), - "a1aa5f7de402d7b3d323f2991c8d4534013137010a83754fd0af6d7cd4922ed9", - ) - - def test_512(self): - for digestmod in (GOST34112012512, gost34112012512): - self.assertSequenceEqual( - hmac.new( - key=hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - msg=hexdec("0126bdb87800af214341456563780100"), - digestmod=digestmod, - ).hexdigest(), - "a59bab22ecae19c65fbde6e5f4e9f5d8549d31f037f9df9b905500e171923a773d5f1530f2ed7e964cb2eedc29e9ad2f3afe93b2814f79f5000ffc0366c251e6", - ) - - -class TestVectors(TestCase): - def test_m1(self): - m = hexdec("323130393837363534333231303938373635343332313039383736353433323130393837363534333231303938373635343332313039383736353433323130")[::-1] - self.assertSequenceEqual( - GOST34112012512(m).digest(), - hexdec("486f64c1917879417fef082b3381a4e211c324f074654c38823a7b76f830ad00fa1fbae42b1285c0352f227524bc9ab16254288dd6863dccd5b9f54a1ad0541b")[::-1] - ) - self.assertSequenceEqual( - GOST34112012256(m).digest(), - hexdec("00557be5e584fd52a449b16b0251d05d27f94ab76cbaa6da890b59d8ef1e159d")[::-1] - ) - - def test_m2(self): - m = u"Се ветри, Стрибожи внуци, веютъ с моря стрелами на храбрыя плъкы Игоревы".encode("cp1251") - self.assertSequenceEqual(m, hexdec("fbe2e5f0eee3c820fbeafaebef20fffbf0e1e0f0f520e0ed20e8ece0ebe5f0f2f120fff0eeec20f120faf2fee5e2202ce8f6f3ede220e8e6eee1e8f0f2d1202ce8f0f2e5e220e5d1")[::-1]) - self.assertSequenceEqual( - GOST34112012512(m).digest(), - hexdec("28fbc9bada033b1460642bdcddb90c3fb3e56c497ccd0f62b8a2ad4935e85f037613966de4ee00531ae60f3b5a47f8dae06915d5f2f194996fcabf2622e6881e")[::-1] - ) - self.assertSequenceEqual( - GOST34112012256(m).digest(), - hexdec("508f7e553c06501d749a66fc28c6cac0b005746d97537fa85d9e40904efed29d")[::-1] - ) - - def test_habr144(self): - """Test vector from https://habr.com/ru/post/452200/ - """ - m = hexdec("d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000002400000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") - self.assertSequenceEqual( - GOST34112012256(m).hexdigest(), - "c766085540caaa8953bfcf7a1ba220619cee50d65dc242f82f23ba4b180b18e0", - ) - - -class TestPBKDF2(TestCase): - """http://tc26.ru/.../R_50.1.111-2016.pdf - """ - def test_1(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 1, 64)), - "64770af7f748c3b1c9ac831dbcfd85c26111b30a8a657ddc3056b80ca73e040d2854fd36811f6d825cc4ab66ec0a68a490a9e5cf5156b3a2b7eecddbf9a16b47", - ) - - def test_2(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 2, 64)), - "5a585bafdfbb6e8830d6d68aa3b43ac00d2e4aebce01c9b31c2caed56f0236d4d34b2b8fbd2c4e89d54d46f50e47d45bbac301571743119e8d3c42ba66d348de", - ) - - def test_3(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 4096, 64)), - "e52deb9a2d2aaff4e2ac9d47a41f34c20376591c67807f0477e32549dc341bc7867c09841b6d58e29d0347c996301d55df0d34e47cf68f4e3c2cdaf1d9ab86c3", - ) - - @skip("it takes too long") - def test_4(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 1677216, 64)), - "49e4843bba76e300afe24c4d23dc7392def12f2c0e244172367cd70a8982ac361adb601c7e2a314e8cb7b1e9df840e36ab5615be5d742b6cf203fb55fdc48071", - ) - - def test_5(self): - self.assertSequenceEqual( - hexenc(pbkdf2( - b"passwordPASSWORDpassword", - b"saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - 100, - )), - "b2d8f1245fc4d29274802057e4b54e0a0753aa22fc53760b301cf008679e58fe4bee9addcae99ba2b0b20f431a9c5e50f395c89387d0945aedeca6eb4015dfc2bd2421ee9bb71183ba882ceebfef259f33f9e27dc6178cb89dc37428cf9cc52a2baa2d3a", - ) - - def test_6(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"pass\x00word", b"sa\x00lt", 4096, 64)), - "50df062885b69801a3c10248eb0a27ab6e522ffeb20c991c660f001475d73a4e167f782c18e97e92976d9c1d970831ea78ccb879f67068cdac1910740844e830", - ) diff --git a/pygost-5.13/build/lib/pygost/test_gost341194.py b/pygost-5.13/build/lib/pygost/test_gost341194.py deleted file mode 100644 index 4ffa6d6..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost341194.py +++ /dev/null @@ -1,200 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import skip -from unittest import TestCase -import hmac - -from pygost import gost341194 -from pygost.gost341194 import GOST341194 -from pygost.gost341194 import pbkdf2 -from pygost.utils import hexenc - - -class TestCopy(TestCase): - def runTest(self): - m = GOST341194() - c = m.copy() - m.update(b"foobar") - c.update(b"foo") - c.update(b"bar") - self.assertSequenceEqual(m.digest(), c.digest()) - - -class TestHMACPEP247(TestCase): - def runTest(self): - h = hmac.new(b"foo", digestmod=gost341194) - h.update(b"foobar") - h.digest() - - -class TestVectors(TestCase): - def test_empty(self): - self.assertSequenceEqual( - GOST341194(b"", "id-GostR3411-94-TestParamSet").hexdigest(), - "ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d", - ) - - def test_a(self): - self.assertSequenceEqual( - GOST341194(b"a", "id-GostR3411-94-TestParamSet").hexdigest(), - "d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd", - ) - - def test_abc(self): - self.assertSequenceEqual( - GOST341194(b"abc", "id-GostR3411-94-TestParamSet").hexdigest(), - "f3134348c44fb1b2a277729e2285ebb5cb5e0f29c975bc753b70497c06a4d51d", - ) - - def test_message_digest(self): - self.assertSequenceEqual( - GOST341194(b"message digest", "id-GostR3411-94-TestParamSet").hexdigest(), - "ad4434ecb18f2c99b60cbe59ec3d2469582b65273f48de72db2fde16a4889a4d", - ) - - def test_Us(self): - self.assertSequenceEqual( - GOST341194(128 * b"U", "id-GostR3411-94-TestParamSet").hexdigest(), - "53a3a3ed25180cef0c1d85a074273e551c25660a87062a52d926a9e8fe5733a4", - ) - - def test_dog(self): - self.assertSequenceEqual( - GOST341194(b"The quick brown fox jumps over the lazy dog", "id-GostR3411-94-TestParamSet",).hexdigest(), - "77b7fa410c9ac58a25f49bca7d0468c9296529315eaca76bd1a10f376d1f4294", - ) - - def test_cog(self): - self.assertSequenceEqual( - GOST341194(b"The quick brown fox jumps over the lazy cog", "id-GostR3411-94-TestParamSet",).hexdigest(), - "a3ebc4daaab78b0be131dab5737a7f67e602670d543521319150d2e14eeec445", - ) - - def test_rfc32(self): - self.assertSequenceEqual( - GOST341194(b"This is message, length=32 bytes", "id-GostR3411-94-TestParamSet",).hexdigest(), - "b1c466d37519b82e8319819ff32595e047a28cb6f83eff1c6916a815a637fffa", - ) - - def test_rfc50(self): - self.assertSequenceEqual( - GOST341194(b"Suppose the original message has length = 50 bytes", "id-GostR3411-94-TestParamSet",).hexdigest(), - "471aba57a60a770d3a76130635c1fbea4ef14de51f78b4ae57dd893b62f55208", - ) - - -class TestVectorsCryptoPro(TestCase): - """CryptoPro S-box test vectors - """ - def test_empty(self): - self.assertSequenceEqual( - GOST341194(b"", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0", - ) - - def test_a(self): - self.assertSequenceEqual( - GOST341194(b"a", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", - ) - - def test_abc(self): - self.assertSequenceEqual( - GOST341194(b"abc", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c", - ) - - def test_message_digest(self): - self.assertSequenceEqual( - GOST341194(b"message digest", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0", - ) - - def test_dog(self): - self.assertSequenceEqual( - GOST341194(b"The quick brown fox jumps over the lazy dog", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76", - ) - - def test_32(self): - self.assertSequenceEqual( - GOST341194(b"This is message, length=32 bytes", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb", - ) - - def test_50(self): - self.assertSequenceEqual( - GOST341194(b"Suppose the original message has length = 50 bytes", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011", - ) - - def test_Us(self): - self.assertSequenceEqual( - GOST341194(128 * b"U", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "1c4ac7614691bbf427fa2316216be8f10d92edfd37cd1027514c1008f649c4e8", - ) - - -class TestPBKDF2(TestCase): - """http://tc26.ru/methods/containers_v1/Addition_to_PKCS5_v1_0.pdf test vectors - """ - def test_1(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 1, 32)), - "7314e7c04fb2e662c543674253f68bd0b73445d07f241bed872882da21662d58", - ) - - def test_2(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 2, 32)), - "990dfa2bd965639ba48b07b792775df79f2db34fef25f274378872fed7ed1bb3", - ) - - def test_3(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 4096, 32)), - "1f1829a94bdff5be10d0aeb36af498e7a97467f3b31116a5a7c1afff9deadafe", - ) - - @skip("it takes too long") - def test_4(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 16777216, 32)), - "a57ae5a6088396d120850c5c09de0a525100938a59b1b5c3f7810910d05fcd97", - ) - - def test_5(self): - self.assertSequenceEqual( - hexenc(pbkdf2( - b"passwordPASSWORDpassword", - b"saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - 40, - )), - "788358c69cb2dbe251a7bb17d5f4241f265a792a35becde8d56f326b49c85047b7638acb4764b1fd", - ) - - def test_6(self): - self.assertSequenceEqual( - hexenc(pbkdf2( - b"pass\x00word", - b"sa\x00lt", - 4096, - 20, - )), - "43e06c5590b08c0225242373127edf9c8e9c3291", - ) diff --git a/pygost-5.13/build/lib/pygost/test_gost3412.py b/pygost-5.13/build/lib/pygost/test_gost3412.py deleted file mode 100644 index 5dbb200..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost3412.py +++ /dev/null @@ -1,137 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import TestCase - -from pygost.gost3412 import C -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3412 import L -from pygost.gost3412 import PI -from pygost.utils import hexdec - - -def S(blk): - return bytearray(PI[v] for v in blk) - - -def R(blk): - return L(blk, rounds=1) - - -class STest(TestCase): - def test_vec1(self): - blk = bytearray(hexdec("ffeeddccbbaa99881122334455667700")) - self.assertSequenceEqual(S(blk), hexdec("b66cd8887d38e8d77765aeea0c9a7efc")) - - def test_vec2(self): - blk = bytearray(hexdec("b66cd8887d38e8d77765aeea0c9a7efc")) - self.assertSequenceEqual(S(blk), hexdec("559d8dd7bd06cbfe7e7b262523280d39")) - - def test_vec3(self): - blk = bytearray(hexdec("559d8dd7bd06cbfe7e7b262523280d39")) - self.assertSequenceEqual(S(blk), hexdec("0c3322fed531e4630d80ef5c5a81c50b")) - - def test_vec4(self): - blk = bytearray(hexdec("0c3322fed531e4630d80ef5c5a81c50b")) - self.assertSequenceEqual(S(blk), hexdec("23ae65633f842d29c5df529c13f5acda")) - - -class RTest(TestCase): - def test_vec1(self): - blk = bytearray(hexdec("00000000000000000000000000000100")) - self.assertSequenceEqual(R(blk), hexdec("94000000000000000000000000000001")) - - def test_vec2(self): - blk = bytearray(hexdec("94000000000000000000000000000001")) - self.assertSequenceEqual(R(blk), hexdec("a5940000000000000000000000000000")) - - def test_vec3(self): - blk = bytearray(hexdec("a5940000000000000000000000000000")) - self.assertSequenceEqual(R(blk), hexdec("64a59400000000000000000000000000")) - - def test_vec4(self): - blk = bytearray(hexdec("64a59400000000000000000000000000")) - self.assertSequenceEqual(R(blk), hexdec("0d64a594000000000000000000000000")) - - -class LTest(TestCase): - def test_vec1(self): - blk = bytearray(hexdec("64a59400000000000000000000000000")) - self.assertSequenceEqual(L(blk), hexdec("d456584dd0e3e84cc3166e4b7fa2890d")) - - def test_vec2(self): - blk = bytearray(hexdec("d456584dd0e3e84cc3166e4b7fa2890d")) - self.assertSequenceEqual(L(blk), hexdec("79d26221b87b584cd42fbc4ffea5de9a")) - - def test_vec3(self): - blk = bytearray(hexdec("79d26221b87b584cd42fbc4ffea5de9a")) - self.assertSequenceEqual(L(blk), hexdec("0e93691a0cfc60408b7b68f66b513c13")) - - def test_vec4(self): - blk = bytearray(hexdec("0e93691a0cfc60408b7b68f66b513c13")) - self.assertSequenceEqual(L(blk), hexdec("e6a8094fee0aa204fd97bcb0b44b8580")) - - -class KuznechikTest(TestCase): - key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef") - plaintext = hexdec("1122334455667700ffeeddccbbaa9988") - ciphertext = hexdec("7f679d90bebc24305a468d42b9d4edcd") - - def test_c(self): - self.assertSequenceEqual(C[0], hexdec("6ea276726c487ab85d27bd10dd849401")) - self.assertSequenceEqual(C[1], hexdec("dc87ece4d890f4b3ba4eb92079cbeb02")) - self.assertSequenceEqual(C[2], hexdec("b2259a96b4d88e0be7690430a44f7f03")) - self.assertSequenceEqual(C[3], hexdec("7bcd1b0b73e32ba5b79cb140f2551504")) - self.assertSequenceEqual(C[4], hexdec("156f6d791fab511deabb0c502fd18105")) - self.assertSequenceEqual(C[5], hexdec("a74af7efab73df160dd208608b9efe06")) - self.assertSequenceEqual(C[6], hexdec("c9e8819dc73ba5ae50f5b570561a6a07")) - self.assertSequenceEqual(C[7], hexdec("f6593616e6055689adfba18027aa2a08")) - - def test_roundkeys(self): - ciph = GOST3412Kuznechik(self.key) - self.assertSequenceEqual(ciph.ks[0], hexdec("8899aabbccddeeff0011223344556677")) - self.assertSequenceEqual(ciph.ks[1], hexdec("fedcba98765432100123456789abcdef")) - self.assertSequenceEqual(ciph.ks[2], hexdec("db31485315694343228d6aef8cc78c44")) - self.assertSequenceEqual(ciph.ks[3], hexdec("3d4553d8e9cfec6815ebadc40a9ffd04")) - self.assertSequenceEqual(ciph.ks[4], hexdec("57646468c44a5e28d3e59246f429f1ac")) - self.assertSequenceEqual(ciph.ks[5], hexdec("bd079435165c6432b532e82834da581b")) - self.assertSequenceEqual(ciph.ks[6], hexdec("51e640757e8745de705727265a0098b1")) - self.assertSequenceEqual(ciph.ks[7], hexdec("5a7925017b9fdd3ed72a91a22286f984")) - self.assertSequenceEqual(ciph.ks[8], hexdec("bb44e25378c73123a5f32f73cdb6e517")) - self.assertSequenceEqual(ciph.ks[9], hexdec("72e9dd7416bcf45b755dbaa88e4a4043")) - - def test_encrypt(self): - ciph = GOST3412Kuznechik(self.key) - self.assertSequenceEqual(ciph.encrypt(self.plaintext), self.ciphertext) - - def test_decrypt(self): - ciph = GOST3412Kuznechik(self.key) - self.assertSequenceEqual(ciph.decrypt(self.ciphertext), self.plaintext) - - -class MagmaTest(TestCase): - key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") - plaintext = hexdec("fedcba9876543210") - ciphertext = hexdec("4ee901e5c2d8ca3d") - - def test_encrypt(self): - ciph = GOST3412Magma(self.key) - self.assertSequenceEqual(ciph.encrypt(self.plaintext), self.ciphertext) - - def test_decrypt(self): - ciph = GOST3412Magma(self.key) - self.assertSequenceEqual(ciph.decrypt(self.ciphertext), self.plaintext) diff --git a/pygost-5.13/build/lib/pygost/test_gost3413.py b/pygost-5.13/build/lib/pygost/test_gost3413.py deleted file mode 100644 index 0098513..0000000 --- a/pygost-5.13/build/lib/pygost/test_gost3413.py +++ /dev/null @@ -1,766 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from random import randint -from unittest import TestCase - -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3413 import _mac_ks -from pygost.gost3413 import acpkm -from pygost.gost3413 import acpkm_master -from pygost.gost3413 import cbc_decrypt -from pygost.gost3413 import cbc_encrypt -from pygost.gost3413 import cfb_decrypt -from pygost.gost3413 import cfb_encrypt -from pygost.gost3413 import ctr -from pygost.gost3413 import ctr_acpkm -from pygost.gost3413 import ecb_decrypt -from pygost.gost3413 import ecb_encrypt -from pygost.gost3413 import KEYSIZE -from pygost.gost3413 import mac -from pygost.gost3413 import mac_acpkm_master -from pygost.gost3413 import ofb -from pygost.gost3413 import pad2 -from pygost.gost3413 import pad_iso10126 -from pygost.gost3413 import unpad2 -from pygost.gost3413 import unpad_iso10126 -from pygost.utils import hexdec -from pygost.utils import hexenc -from pygost.utils import strxor - - -class Pad2Test(TestCase): - def test_symmetric(self): - for _ in range(100): - for blocksize in (GOST3412Magma.blocksize, GOST3412Kuznechik.blocksize): - data = urandom(randint(0, blocksize * 3)) - self.assertSequenceEqual( - unpad2(pad2(data, blocksize), blocksize), - data, - ) - - -class GOST3412KuznechikModesTest(TestCase): - key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef") - ciph = GOST3412Kuznechik(key) - plaintext = "" - plaintext += "1122334455667700ffeeddccbbaa9988" - plaintext += "00112233445566778899aabbcceeff0a" - plaintext += "112233445566778899aabbcceeff0a00" - plaintext += "2233445566778899aabbcceeff0a0011" - iv = hexdec("1234567890abcef0a1b2c3d4e5f0011223344556677889901213141516171819") - - def test_ecb_vectors(self): - ciphtext = "" - ciphtext += "7f679d90bebc24305a468d42b9d4edcd" - ciphtext += "b429912c6e0032f9285452d76718d08b" - ciphtext += "f0ca33549d247ceef3f5a5313bd4b157" - ciphtext += "d0b09ccde830b9eb3a02c4c5aa8ada98" - self.assertSequenceEqual( - hexenc(ecb_encrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ecb_decrypt( - self.ciph.decrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - )), - self.plaintext, - ) - - def test_ecb_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = ecb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt) - self.assertSequenceEqual(ecb_decrypt( - ciph.decrypt, - GOST3412Kuznechik.blocksize, - ct, - ), pt) - - def test_ctr_vectors(self): - ciphtext = "" - ciphtext += "f195d8bec10ed1dbd57b5fa240bda1b8" - ciphtext += "85eee733f6a13e5df33ce4b33c45dee4" - ciphtext += "a5eae88be6356ed3d5e877f13564a3a5" - ciphtext += "cb91fab1f20cbab6d1c6d15820bdba73" - iv = self.iv[:GOST3412Kuznechik.blocksize // 2] - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_ctr_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Kuznechik.blocksize // 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = ctr(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(ctr( - ciph.encrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_ofb_vectors(self): - ciphtext = "" - ciphtext += "81800a59b1842b24ff1f795e897abd95" - ciphtext += "ed5b47a7048cfab48fb521369d9326bf" - ciphtext += "66a257ac3ca0b8b1c80fe7fc10288a13" - ciphtext += "203ebbc066138660a0292243f6903150" - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_ofb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Kuznechik.blocksize * 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(ofb( - ciph.encrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_ofb_manual(self): - iv = [urandom(GOST3412Kuznechik.blocksize) for _ in range(randint(2, 10))] - pt = [ - urandom(GOST3412Kuznechik.blocksize) - for _ in range(len(iv), len(iv) + randint(1, 10)) - ] - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - r = [ciph.encrypt(i) for i in iv] - for i in range(len(pt) - len(iv)): - r.append(ciph.encrypt(r[i])) - ct = [strxor(g, r) for g, r in zip(pt, r)] - self.assertSequenceEqual( - ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, b"".join(pt), b"".join(iv)), - b"".join(ct), - ) - - def test_cbc_vectors(self): - ciphtext = "" - ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27" - ciphtext += "2826e661b478eca6af1e8e448d5ea5ac" - ciphtext += "fe7babf1e91999e85640e8b0f49d90d0" - ciphtext += "167688065a895c631a2d9a1560b63970" - self.assertSequenceEqual( - hexenc(cbc_encrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cbc_decrypt( - self.ciph.decrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_cbc_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize) - iv = urandom(GOST3412Kuznechik.blocksize * 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = cbc_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(cbc_decrypt( - ciph.decrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_cfb_vectors(self): - ciphtext = "" - ciphtext += "81800a59b1842b24ff1f795e897abd95" - ciphtext += "ed5b47a7048cfab48fb521369d9326bf" - ciphtext += "79f2a8eb5cc68d38842d264e97a238b5" - ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1" - self.assertSequenceEqual( - hexenc(cfb_encrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cfb_decrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_cfb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Kuznechik.blocksize * 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = cfb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(cfb_decrypt( - ciph.encrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_mac_vectors(self): - k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(hexenc(k1), "297d82bc4d39e3ca0de0573298151dc7") - self.assertSequenceEqual(hexenc(k2), "52fb05789a73c7941bc0ae65302a3b8e") - self.assertSequenceEqual( - hexenc(mac( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - )[:8]), - "336f4d296059fbe3", - ) - - def test_mac_applies(self): - for _ in range(100): - data = urandom(randint(0, 16 * 2)) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - mac(ciph.encrypt, GOST3412Kuznechik.blocksize, data) - - -class GOST3412MagmaModesTest(TestCase): - key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") - ciph = GOST3412Magma(key) - plaintext = "" - plaintext += "92def06b3c130a59" - plaintext += "db54c704f8189d20" - plaintext += "4a98fb2e67a8024c" - plaintext += "8912409b17b57e41" - iv = hexdec("1234567890abcdef234567890abcdef134567890abcdef12") - - def test_ecb_vectors(self): - ciphtext = "" - ciphtext += "2b073f0494f372a0" - ciphtext += "de70e715d3556e48" - ciphtext += "11d8d9e9eacfbc1e" - ciphtext += "7c68260996c67efb" - self.assertSequenceEqual( - hexenc(ecb_encrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ecb_decrypt( - self.ciph.decrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - )), - self.plaintext, - ) - - def test_ecb_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), 16) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = ecb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt) - self.assertSequenceEqual(ecb_decrypt( - ciph.decrypt, - GOST3412Magma.blocksize, - ct, - ), pt) - - def test_ctr_vectors(self): - ciphtext = "" - ciphtext += "4e98110c97b7b93c" - ciphtext += "3e250d93d6e85d69" - ciphtext += "136d868807b2dbef" - ciphtext += "568eb680ab52a12d" - iv = self.iv[:4] - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_ctr_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Magma.blocksize // 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = ctr(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(ctr( - ciph.encrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_ofb_vectors(self): - iv = self.iv[:16] - ciphtext = "" - ciphtext += "db37e0e266903c83" - ciphtext += "0d46644c1f9a089c" - ciphtext += "a0f83062430e327e" - ciphtext += "c824efb8bd4fdb05" - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_ofb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Magma.blocksize * 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = ofb(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(ofb( - ciph.encrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_cbc_vectors(self): - ciphtext = "" - ciphtext += "96d1b05eea683919" - ciphtext += "aff76129abb937b9" - ciphtext += "5058b4a1c4bc0019" - ciphtext += "20b78b1a7cd7e667" - self.assertSequenceEqual( - hexenc(cbc_encrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cbc_decrypt( - self.ciph.decrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_cbc_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), 16) - iv = urandom(GOST3412Magma.blocksize * 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = cbc_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(cbc_decrypt( - ciph.decrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_cfb_vectors(self): - iv = self.iv[:16] - ciphtext = "" - ciphtext += "db37e0e266903c83" - ciphtext += "0d46644c1f9a089c" - ciphtext += "24bdd2035315d38b" - ciphtext += "bcc0321421075505" - self.assertSequenceEqual( - hexenc(cfb_encrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cfb_decrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_cfb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Magma.blocksize * 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = cfb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(cfb_decrypt( - ciph.encrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_mac_vectors(self): - k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(hexenc(k1), "5f459b3342521424") - self.assertSequenceEqual(hexenc(k2), "be8b366684a42848") - self.assertSequenceEqual( - hexenc(mac( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - )[:4]), - "154e7210", - ) - - def test_mac_applies(self): - for _ in range(100): - data = urandom(randint(0, 16 * 2)) - ciph = GOST3412Magma(urandom(KEYSIZE)) - mac(ciph.encrypt, GOST3412Magma.blocksize, data) - - -class TestVectorACPKM(TestCase): - """Test vectors from Р 1323565.1.017-2018 - """ - key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF") - - def test_magma_ctr_acpkm(self): - key = acpkm(GOST3412Magma(self.key).encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(key, hexdec("863EA017842C3D372B18A85A28E2317D74BEFC107720DE0C9E8AB974ABD00CA0")) - key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(key, hexdec("49A5E2677DE555982B8AD5E826652D17EEC847BF5B3997A81CF7FE7F1187BD27")) - key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(key, hexdec("3256BF3F97B5667426A9FB1C5EAABE41893CCDD5A868F9B63B0AA90720FA43C4")) - - def test_magma_ctr(self): - encrypter = GOST3412Magma(self.key).encrypt - plaintext = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 -22 33 44 55 66 77 88 99 - """.replace("\n", "").replace(" ", "")) - iv = hexdec("12345678") - ciphertext = hexdec(""" -2A B8 1D EE EB 1E 4C AB 68 E1 04 C4 BD 6B 94 EA -C7 2C 67 AF 6C 2E 5B 6B 0E AF B6 17 70 F1 B3 2E -A1 AE 71 14 9E ED 13 82 AB D4 67 18 06 72 EC 6F -84 A2 F1 5B 3F CA 72 C1 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Magma, - encrypter, - bs=GOST3412Magma.blocksize, - section_size=GOST3412Magma.blocksize * 2, - data=plaintext, - iv=iv - ), - ciphertext, - ) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Magma, - encrypter, - bs=GOST3412Magma.blocksize, - section_size=GOST3412Magma.blocksize * 2, - data=ciphertext, - iv=iv - ), - plaintext, - ) - - def test_kuznechik_ctr_acpkm(self): - key = acpkm(GOST3412Kuznechik(self.key).encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(key, hexdec("2666ED40AE687811745CA0B448F57A7B390ADB5780307E8E9659AC403AE60C60")) - key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(key, hexdec("BB3DD5402E999B7A3DEBB0DB45448EC530F07365DFEE3ABA8415F77AC8F34CE8")) - key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(key, hexdec("23362FD553CAD2178299A5B5A2D4722E3BB83C730A8BF57CE2DD004017F8C565")) - - def test_kuznechik_ctr(self): - encrypter = GOST3412Kuznechik(self.key).encrypt - iv = hexdec("1234567890ABCEF0") - plaintext = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 -22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 -33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 -44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 -55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44 - """.replace("\n", "").replace(" ", "")) - ciphertext = hexdec(""" -F1 95 D8 BE C1 0E D1 DB D5 7B 5F A2 40 BD A1 B8 -85 EE E7 33 F6 A1 3E 5D F3 3C E4 B3 3C 45 DE E4 -4B CE EB 8F 64 6F 4C 55 00 17 06 27 5E 85 E8 00 -58 7C 4D F5 68 D0 94 39 3E 48 34 AF D0 80 50 46 -CF 30 F5 76 86 AE EC E1 1C FC 6C 31 6B 8A 89 6E -DF FD 07 EC 81 36 36 46 0C 4F 3B 74 34 23 16 3E -64 09 A9 C2 82 FA C8 D4 69 D2 21 E7 FB D6 DE 5D - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Kuznechik, - encrypter, - bs=GOST3412Kuznechik.blocksize, - section_size=GOST3412Kuznechik.blocksize * 2, - data=plaintext, - iv=iv, - ), - ciphertext, - ) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Kuznechik, - encrypter, - bs=GOST3412Kuznechik.blocksize, - section_size=GOST3412Kuznechik.blocksize * 2, - data=ciphertext, - iv=iv, - ), - plaintext, - ) - - def test_magma_omac_1_5_blocks(self): - encrypter = GOST3412Magma(self.key).encrypt - key_section_size = 640 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Magma, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Magma.blocksize, - keymat_len=KEYSIZE + GOST3412Magma.blocksize, - ), - hexdec("0DF2F5273DA328932AC49D81D36B2558A50DBF9BBCAC74A614B2CCB2F1CBCD8A70638E3DE8B3571E"), - ) - text = hexdec("1122334455667700FFEEDDCC") - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Magma, - encrypter, - key_section_size, - section_size=GOST3412Magma.blocksize * 2, - bs=GOST3412Magma.blocksize, - data=text, - ), - hexdec("A0540E3730ACBCF3"), - ) - - def test_magma_omac_5_blocks(self): - encrypter = GOST3412Magma(self.key).encrypt - key_section_size = 640 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Magma, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Magma.blocksize, - keymat_len=3 * (KEYSIZE + GOST3412Magma.blocksize), - ), - hexdec(""" -0D F2 F5 27 3D A3 28 93 2A C4 9D 81 D3 6B 25 58 -A5 0D BF 9B BC AC 74 A6 14 B2 CC B2 F1 CB CD 8A -70 63 8E 3D E8 B3 57 1E 8D 38 26 D5 5E 63 A1 67 -E2 40 66 40 54 7B 9F 1F 5F 2B 43 61 2A AE AF DA -18 0B AC 86 04 DF A6 FE 53 C2 CE 27 0E 9C 9F 52 -68 D0 FD BF E1 A3 BD D9 BE 5B 96 D0 A1 20 23 48 -6E F1 71 0F 92 4A E0 31 30 52 CB 5F CA 0B 79 1E -1B AB E8 57 6D 0F E3 A8 - """.replace("\n", "").replace(" ", "")), - ) - text = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Magma, - encrypter, - key_section_size, - section_size=GOST3412Magma.blocksize * 2, - bs=GOST3412Magma.blocksize, - data=text, - ), - hexdec("34008DAD5496BB8E"), - ) - - def test_kuznechik_omac_1_5_blocks(self): - encrypter = GOST3412Kuznechik(self.key).encrypt - key_section_size = 768 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Kuznechik.blocksize, - keymat_len=KEYSIZE + GOST3412Kuznechik.blocksize, - ), - hexdec(""" -0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2 -C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE -0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37 - """.replace("\n", "").replace(" ", "")) - ) - text = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size, - section_size=GOST3412Kuznechik.blocksize * 2, - bs=GOST3412Kuznechik.blocksize, - data=text, - ), - hexdec("B5367F47B62B995EEB2A648C5843145E"), - ) - - def test_kuznechik_omac_5_blocks(self): - encrypter = GOST3412Kuznechik(self.key).encrypt - key_section_size = 768 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Kuznechik.blocksize, - keymat_len=3 * (KEYSIZE + GOST3412Kuznechik.blocksize), - ), - hexdec(""" -0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2 -C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE -0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37 -C9 DD A8 9C FF A4 91 FE AD D9 B3 EA B7 03 BB 31 -BC 7E 92 7F 04 94 72 9F 51 B4 9D 3D F9 C9 46 08 -00 FB BC F5 ED EE 61 0E A0 2F 01 09 3C 7B C7 42 -D7 D6 27 15 01 B1 77 77 52 63 C2 A3 49 5A 83 18 -A8 1C 79 A0 4F 29 66 0E A3 FD A8 74 C6 30 79 9E -14 2C 57 79 14 FE A9 0D 3B C2 50 2E 83 36 85 D9 - """.replace("\n", "").replace(" ", "")), - ) - text = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 -22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 -33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size, - section_size=GOST3412Kuznechik.blocksize * 2, - bs=GOST3412Kuznechik.blocksize, - data=text, - ), - hexdec("FBB8DCEE45BEA67C35F58C5700898E5D"), - ) - - -class ISO10126Test(TestCase): - def test_symmetric(self): - for _ in range(100): - for blocksize in (GOST3412Magma.blocksize, GOST3412Kuznechik.blocksize): - data = urandom(randint(0, blocksize * 3)) - padded = pad_iso10126(data, blocksize) - self.assertSequenceEqual(unpad_iso10126(padded, blocksize), data) - with self.assertRaises(ValueError): - unpad_iso10126(padded[1:], blocksize) - - def test_small(self): - with self.assertRaises(ValueError): - unpad_iso10126(b"foobar\x00\x09", 8) diff --git a/pygost-5.13/build/lib/pygost/test_kdf.py b/pygost-5.13/build/lib/pygost/test_kdf.py deleted file mode 100644 index 6921cfc..0000000 --- a/pygost-5.13/build/lib/pygost/test_kdf.py +++ /dev/null @@ -1,58 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import TestCase - -from pygost.kdf import kdf_gostr3411_2012_256 -from pygost.kdf import kdf_tree_gostr3411_2012_256 -from pygost.utils import hexdec - - -class TestKDFGOSTR34112012256(TestCase): - def runTest(self): - self.assertEqual( - kdf_gostr3411_2012_256( - hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - hexdec("26bdb878"), - hexdec("af21434145656378"), - ), - hexdec("a1aa5f7de402d7b3d323f2991c8d4534013137010a83754fd0af6d7cd4922ed9"), - ) - - -class TestKDFTREEGOSTR34112012256(TestCase): - def runTest(self): - self.assertSequenceEqual( - kdf_tree_gostr3411_2012_256( - hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - hexdec("26bdb878"), - hexdec("af21434145656378"), - 1, - ), - (hexdec("a1aa5f7de402d7b3d323f2991c8d4534013137010a83754fd0af6d7cd4922ed9"),), - ) - self.assertSequenceEqual( - kdf_tree_gostr3411_2012_256( - hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - hexdec("26bdb878"), - hexdec("af21434145656378"), - 2, - ), - ( - hexdec("22b6837845c6bef65ea71672b265831086d3c76aebe6dae91cad51d83f79d16b"), - hexdec("074c9330599d7f8d712fca54392f4ddde93751206b3584c8f43f9e6dc51531f9"), - ), - ) diff --git a/pygost-5.13/build/lib/pygost/test_mgm.py b/pygost-5.13/build/lib/pygost/test_mgm.py deleted file mode 100644 index e70a7f5..0000000 --- a/pygost-5.13/build/lib/pygost/test_mgm.py +++ /dev/null @@ -1,75 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from random import randint -from unittest import TestCase - -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3412 import KEYSIZE -from pygost.mgm import MGM -from pygost.mgm import nonce_prepare -from pygost.utils import hexdec - - -class TestVector(TestCase): - def runTest(self): - key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF") - ad = hexdec("0202020202020202010101010101010104040404040404040303030303030303EA0505050505050505") - plaintext = hexdec("1122334455667700FFEEDDCCBBAA998800112233445566778899AABBCCEEFF0A112233445566778899AABBCCEEFF0A002233445566778899AABBCCEEFF0A0011AABBCC") - mgm = MGM(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize) - ciphertext = mgm.seal(plaintext[:16], plaintext, ad) - self.assertSequenceEqual(ciphertext[:len(plaintext)], hexdec("A9757B8147956E9055B8A33DE89F42FC8075D2212BF9FD5BD3F7069AADC16B39497AB15915A6BA85936B5D0EA9F6851CC60C14D4D3F883D0AB94420695C76DEB2C7552")) - self.assertSequenceEqual(ciphertext[len(plaintext):], hexdec("CF5D656F40C34F5C46E8BB0E29FCDB4C")) - self.assertSequenceEqual(mgm.open(plaintext[:16], ciphertext, ad), plaintext) - - -class TestSymmetric(TestCase): - def _itself(self, mgm, bs, tag_size): - for _ in range(1000): - nonce = nonce_prepare(urandom(bs)) - ad = urandom(randint(0, 20)) - pt = urandom(randint(0, 20)) - if len(ad) + len(pt) == 0: - continue - ct = mgm.seal(nonce, pt, ad) - self.assertEqual(len(ct) - tag_size, len(pt)) - self.assertSequenceEqual(mgm.open(nonce, ct, ad), pt) - - def test_magma(self): - for tag_size in ( - GOST3412Magma.blocksize, - GOST3412Magma.blocksize - 2, - ): - mgm = MGM( - GOST3412Magma(urandom(KEYSIZE)).encrypt, - GOST3412Magma.blocksize, - tag_size, - ) - self._itself(mgm, GOST3412Magma.blocksize, tag_size) - - def test_kuznechik(self): - for tag_size in ( - GOST3412Kuznechik.blocksize, - GOST3412Kuznechik.blocksize - 2, - ): - mgm = MGM( - GOST3412Kuznechik(urandom(KEYSIZE)).encrypt, - GOST3412Kuznechik.blocksize, - tag_size, - ) - self._itself(mgm, GOST3412Kuznechik.blocksize, tag_size) diff --git a/pygost-5.13/build/lib/pygost/test_pfx.py b/pygost-5.13/build/lib/pygost/test_pfx.py deleted file mode 100644 index a2760bf..0000000 --- a/pygost-5.13/build/lib/pygost/test_pfx.py +++ /dev/null @@ -1,680 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from base64 import b64decode -from hmac import new as hmac_new -from unittest import skipIf -from unittest import TestCase - -from pygost import gost3410 -from pygost.gost28147 import cfb_decrypt -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost34112012512 import pbkdf2 as gost34112012_pbkdf2 -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3412 import KEYSIZE -from pygost.gost3413 import ctr_acpkm -from pygost.gost3413 import mac as omac -from pygost.kdf import kdf_tree_gostr3411_2012_256 -from pygost.kdf import keg -from pygost.utils import hexdec -from pygost.wrap import kimp15 - - -try: - from pyderasn import OctetString - - from pygost.asn1schemas.cms import EncryptedData - from pygost.asn1schemas.cms import EnvelopedData - from pygost.asn1schemas.cms import SignedAttributes - from pygost.asn1schemas.cms import SignedData - from pygost.asn1schemas.oids import id_data - from pygost.asn1schemas.oids import id_envelopedData - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_wrap_kexp15 - from pygost.asn1schemas.oids import id_messageDigest - from pygost.asn1schemas.oids import id_pbes2 - from pygost.asn1schemas.oids import id_pkcs12_bagtypes_certBag - from pygost.asn1schemas.oids import id_pkcs12_bagtypes_keyBag - from pygost.asn1schemas.oids import id_pkcs12_bagtypes_pkcs8ShroudedKeyBag - from pygost.asn1schemas.oids import id_pkcs9_certTypes_x509Certificate - from pygost.asn1schemas.oids import id_signedData - from pygost.asn1schemas.oids import id_tc26_agreement_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_256 - from pygost.asn1schemas.pfx import CertBag - from pygost.asn1schemas.pfx import KeyBag - from pygost.asn1schemas.pfx import OctetStringSafeContents - from pygost.asn1schemas.pfx import PBES2Params - from pygost.asn1schemas.pfx import PFX - from pygost.asn1schemas.pfx import PKCS8ShroudedKeyBag - from pygost.asn1schemas.pfx import SafeContents - from pygost.asn1schemas.x509 import Certificate -except ImportError: - pyderasn_exists = False -else: - pyderasn_exists = True - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestPFX(TestCase): - """PFX test vectors from "Транспортный ключевой контейнер" (R50.1.112-2016.pdf) - """ - pfx_raw = b64decode(""" -MIIFqgIBAzCCBSsGCSqGSIb3DQEHAaCCBRwEggUYMIIFFDCCASIGCSqGSIb3DQEH -AaCCARMEggEPMIIBCzCCAQcGCyqGSIb3DQEMCgECoIHgMIHdMHEGCSqGSIb3DQEF -DTBkMEEGCSqGSIb3DQEFDDA0BCD5qZr0TTIsBvdgUoq/zFwOzdyJohj6/4Wiyccg -j9AK/QICB9AwDAYIKoUDBwEBBAIFADAfBgYqhQMCAhUwFQQI3Ip/Vp0IsyIGCSqF -AwcBAgUBAQRoSfLhgx9s/zn+BjnhT0ror07vS55Ys5hgvVpWDx4mXGWWyez/2sMc -aFgSr4H4UTGGwoMynGLpF1IOVo+bGJ0ePqHB+gS5OL9oV+PUmZ/ELrRENKlCDqfY -WvpSystX29CvCFrnTnDsbBYxFTATBgkqhkiG9w0BCRUxBgQEAQAAADCCA+oGCSqG -SIb3DQEHBqCCA9swggPXAgEAMIID0AYJKoZIhvcNAQcBMHEGCSqGSIb3DQEFDTBk -MEEGCSqGSIb3DQEFDDA0BCCJTJLZQRi1WIpQHzyjXbq7+Vw2+1280C45x8ff6kMS -VAICB9AwDAYIKoUDBwEBBAIFADAfBgYqhQMCAhUwFQQIxepowwvS11MGCSqFAwcB -AgUBAYCCA06n09P/o+eDEKoSWpvlpOLKs7dKmVquKzJ81nCngvLQ5fEWL1WkxwiI -rEhm53JKLD0wy4hekalEk011Bvc51XP9gkDkmaoBpnV/TyKIY35wl6ATfeGXno1M -KoA+Ktdhv4gLnz0k2SXdkUj11JwYskXue+REA0p4m2ZsoaTmvoODamh9JeY/5Qjy -Xe58CGnyXFzX3eU86qs4WfdWdS3NzYYOk9zzVl46le9u79O/LnW2j4n2of/Jpk/L -YjrRmz5oYeQOqKOKhEyhpO6e+ejr6laduEv7TwJQKRNiygogbVvkNn3VjHTSOUG4 -W+3NRPhjb0jD9obdyx6MWa6O3B9bUzFMNav8/gYn0vTDxqXMLy/92oTngNrVx6Gc -cNl128ISrDS6+RxtAMiEBRK6xNkemqX5yNXG5GrLQQFGP6mbs2nNpjKlgj3pljmX -Eky2/G78XiJrv02OgGs6CKnI9nMpa6N7PBHV34MJ6EZzWOWDRQ420xk63mnicrs0 -WDVJ0xjdu4FW3iEk02EaiRTvGBpa6GL7LBp6QlaXSSwONx725cyRsL9cTlukqXER -WHDlMpjYLbkGZRrCc1myWgEfsputfSIPNF/oLv9kJNWacP3uuDOfecg3us7eg2OA -xo5zrYfn39GcBMF1WHAYRO/+PnJb9jrDuLAE8+ONNqjNulWNK9CStEhb6Te+yE6q -oeP6hJjFLi+nFLE9ymIo0A7gLQD5vzFvl+7v1ZNVnQkwRUsWoRiEVVGnv3Z1iZU6 -xStxgoHMl62V/P5cz4dr9vJM2adEWNZcVXl6mk1H8DRc1sRGnvs2l237oKWRVntJ -hoWnZ8qtD+3ZUqsX79QhVzUQBzKuBt6jwNhaHLGl5B+Or/zA9FezsOh6+Uc+fZaV -W7fFfeUyWwGy90XD3ybTrjzep9f3nt55Z2c+fu2iEwhoyImWLuC3+CVhf9Af59j9 -8/BophMJuATDJEtgi8rt4vLnfxKu250Mv2ZpbfF69EGTgFYbwc55zRfaUG9zlyCu -1YwMJ6HC9FUVtJp9gObSrirbzTH7mVaMjQkBLotazWbegzI+be8V3yT06C+ehD+2 -GdLWAVs9hp8gPHEUShb/XrgPpDSJmFlOiyeOFBO/j4edDACKqVcwdjBOMAoGCCqF -AwcBAQIDBEAIFX0fyZe20QKKhWm6WYX+S92Gt6zaXroXOvAmayzLfZ5Sd9C2t9zZ -JSg6M8RBUYpw/8ym5ou1o2nDa09M5zF3BCCpzyCQBI+rzfISeKvPV1ROfcXiYU93 -mwcl1xQV2G5/fgICB9A= - """) - password = u"Пароль для PFX" - - def test_shrouded_key_bag(self): - private_key_info_expected = b64decode(b""" -MGYCAQAwHwYIKoUDBwEBAQEwEwYHKoUDAgIjAQYIKoUDBwEBAgIEQEYbRu86z+1JFKDcPDN9UbTG -G2ki9enTqos4KpUU0j9IDpl1UXiaA1YDIwUjlAp+81GkLmyt8Fw6Gt/X5JZySAY= - """) - - pfx, tail = PFX().decode(self.pfx_raw) - self.assertSequenceEqual(tail, b"") - _, outer_safe_contents = pfx["authSafe"]["content"].defined - safe_contents, tail = OctetStringSafeContents().decode( - bytes(outer_safe_contents[0]["bagValue"]), - ) - self.assertSequenceEqual(tail, b"") - safe_bag = safe_contents[0] - shrouded_key_bag, tail = PKCS8ShroudedKeyBag().decode( - bytes(safe_bag["bagValue"]), - ) - self.assertSequenceEqual(tail, b"") - _, pbes2_params = shrouded_key_bag["encryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - - key = gost34112012_pbkdf2( - password=self.password.encode("utf-8"), - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("309dd0354c5603739403f2335e9e2055138f8b5c98b63009de0635eea1fd7ba8") - self.assertSequenceEqual( - cfb_decrypt( - key, - bytes(shrouded_key_bag["encryptedData"]), - iv=bytes(enc_scheme_params["iv"]), - sbox="id-tc26-gost-28147-param-Z", - ), - private_key_info_expected, - ) - - def test_encrypted_data(self): - cert_bag_expected = b64decode(b""" -MIIDSjCCA0YGCyqGSIb3DQEMCgEDoIIDHjCCAxoGCiqGSIb3DQEJFgGgggMKBIIDBjCCAwIwggKt -oAMCAQICEAHQaF8xH5bAAAAACycJAAEwDAYIKoUDBwEBAwIFADBgMQswCQYDVQQGEwJSVTEVMBMG -A1UEBwwM0JzQvtGB0LrQstCwMQ8wDQYDVQQKDAbQotCaMjYxKTAnBgNVBAMMIENBIGNlcnRpZmlj -YXRlIChQS0NTIzEyIGV4YW1wbGUpMB4XDTE1MDMyNzA3MjUwMFoXDTIwMDMyNzA3MjMwMFowZDEL -MAkGA1UEBhMCUlUxFTATBgNVBAcMDNCc0L7RgdC60LLQsDEPMA0GA1UECgwG0KLQmjI2MS0wKwYD -VQQDDCRUZXN0IGNlcnRpZmljYXRlIDEgKFBLQ1MjMTIgZXhhbXBsZSkwZjAfBggqhQMHAQEBATAT -BgcqhQMCAiMBBggqhQMHAQECAgNDAARA1xzymkpvr2dYJT8WTOX3Dt96/+hGsXNytUQpkWB5ImJM -4tg9AsC4RIUwV5H41MhG0uBRFweTzN6AsAdBvhTClYEJADI3MDkwMDAxo4IBKTCCASUwKwYDVR0Q -BCQwIoAPMjAxNTAzMjcwNzI1MDBagQ8yMDE2MDMyNzA3MjUwMFowDgYDVR0PAQH/BAQDAgTwMB0G -A1UdDgQWBBQhWOsRQ68yYN2Utg/owHoWcqsVbTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH -AwQwDAYDVR0TAQH/BAIwADCBmQYDVR0jBIGRMIGOgBQmnc7Xh5ykb5t/BMwOkxA4drfEmqFkpGIw -YDELMAkGA1UEBhMCUlUxFTATBgNVBAcMDNCc0L7RgdC60LLQsDEPMA0GA1UECgwG0KLQmjI2MSkw -JwYDVQQDDCBDQSBjZXJ0aWZpY2F0ZSAoUEtDUyMxMiBleGFtcGxlKYIQAdBoXvL8TSAAAAALJwkA -ATAMBggqhQMHAQEDAgUAA0EA9oq0Vvk8kkgIwkp0x0J5eKtia4MNTiwKAm7jgnCZIx3O98BThaTX -3ZQhEo2RL9pTCPr6wFMheeJ+YdGMReXvsjEVMBMGCSqGSIb3DQEJFTEGBAQBAAAA - """) - - pfx, tail = PFX().decode(self.pfx_raw) - self.assertSequenceEqual(tail, b"") - _, outer_safe_contents = pfx["authSafe"]["content"].defined - _, encrypted_data = outer_safe_contents[1]["bagValue"].defined - _, pbes2_params = encrypted_data["encryptedContentInfo"]["contentEncryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - key = gost34112012_pbkdf2( - password=self.password.encode("utf-8"), - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("0e93d71339e7f53b79a0bc41f9109dd4fb60b30ae10736c1bb77b84c07681cfc") - self.assertSequenceEqual( - cfb_decrypt( - key, - bytes(encrypted_data["encryptedContentInfo"]["encryptedContent"]), - iv=bytes(enc_scheme_params["iv"]), - sbox="id-tc26-gost-28147-param-Z", - ), - cert_bag_expected, - ) - - def test_mac(self): - pfx, tail = PFX().decode(self.pfx_raw) - self.assertSequenceEqual(tail, b"") - _, outer_safe_contents = pfx["authSafe"]["content"].defined - mac_data = pfx["macData"] - mac_key = gost34112012_pbkdf2( - password=self.password.encode("utf-8"), - salt=bytes(mac_data["macSalt"]), - iterations=int(mac_data["iterations"]), - dklen=96, - )[-32:] - # mac_key = hexdec("cadbfbf3bceaa9b79f651508fac5abbeb4a13d0bd0e1876bd3c3efb2112128a5") - self.assertSequenceEqual( - hmac_new( - key=mac_key, - msg=SafeContents(outer_safe_contents).encode(), - digestmod=GOST34112012512, - ).digest(), - bytes(mac_data["mac"]["digest"]), - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestPFX2020(TestCase): - """PFX test vectors from newer PKCS#12 update - """ - ca_prv_raw = hexdec("092F8D059E97E22B90B1AE99F0087FC4D26620B91550CBB437C191005A290810") - ca_curve = gost3410.CURVES["id-tc26-gost-3410-12-256-paramSetA"] - ca_cert = Certificate().decod(b64decode(b""" - MIIB+TCCAaagAwIBAgIEAYy6gTAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2MS - cwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEwMTAx - MDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA4MQ0wCwYDVQQKEwRUSzI2MScwJQYDVQQDEx - 5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwXjAXBggqhQMHAQEBATALBgkq - hQMHAQIBAQEDQwAEQBpKgpyPDnhQAJyLqy8Qs0XQhgxEhby6tSypqYimgbjpcKqtU6 - 4jpDXc3h3BxGxtl2oHJ/4YLZ/ll87dto3ltMqjgZgwgZUwYwYDVR0jBFwwWoAUrGwO - TERmokKW4p8JOyVm88ukUyqhPKQ6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMTHk - NBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQUrGwO - TERmokKW4p8JOyVm88ukUyowDwYDVR0TAQH/BAUwAwEB/zAKBggqhQMHAQEDAgNBAB - Gg3nhgQ5oCKbqlEdVaRxH+1WX4wVkawGXuTYkr1AC2OWw3ZC14Vvg3nazm8UMWUZtk - vu1kJcHQ4jFKkjUeg2E= - """)) - ca_pub = gost3410.pub_unmarshal(bytes(OctetString().decod(bytes( - ca_cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - )))) - password = u"Пароль для PFX".encode("utf-8") - cert_test = Certificate().decod(b64decode(b""" - MIICLjCCAdugAwIBAgIEAYy6hDAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2MS - cwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEwMTAx - MDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYDVQQDEy - FPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDUxMi1iaXQwgaAwFwYIKoUDBwEBAQIw - CwYJKoUDBwECAQIBA4GEAASBgLSLt1q8KQ4YZVxioU+1LV9QhE7MHR9gBEh7S1yVNG - lqt7+rNG5VFqmrPM74rbUsOlhV8M+zZKprXdk35Oz8lSW/n2oIUHZxikXIH/SSHj4r - v3K/Puvz7hYTQSZl/xPdp78nUmjrEa6d5wfX8biEy2z0dgufFvAkMw1Ua4gdXqDOo4 - GHMIGEMGMGA1UdIwRcMFqAFKxsDkxEZqJCluKfCTslZvPLpFMqoTykOjA4MQ0wCwYD - VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaX - SCBAGMuoEwHQYDVR0OBBYEFH4GVwmYDK1rCKhX7nkAWDrJ16CkMAoGCCqFAwcBAQMC - A0EACl6p8dAbpi9Hk+3mgMyI0WIh17IrlrSp/mB0F7ZzMt8XUD1Dwz3JrrnxeXnfMv - OA5BdUJ9hCyDgMVAGs/IcEEA== - """)) - prv_test_raw = b64decode(""" - MIHiAgEBMBcGCCqFAwcBAQECMAsGCSqFAwcBAgECAQRAEWkl+eblsHWs86SNgRKq - SxMOgGhbvR/uZ5/WWfdNG1axvUwVhpcXIxDZUmzQuNzqJBkseI7f5/JjXyTFRF1a - +YGBgQG0i7davCkOGGVcYqFPtS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO - +K21LDpYVfDPs2Sqa13ZN+Ts/JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0Em - Zf8T3ae/J1Jo6xGunecH1/G4hMts9HYLnxbwJDMNVGuIHV6gzg== - """) - - def test_cert_and_encrypted_key(self): - pfx_raw = b64decode(b""" - MIIFKwIBAzCCBMQGCSqGSIb3DQEHAaCCBLUEggSxMIIErTCCAswGCSqGSIb3DQEH - AaCCAr0EggK5MIICtTCCArEGCyqGSIb3DQEMCgEDoIICSjCCAkYGCiqGSIb3DQEJ - FgGgggI2BIICMjCCAi4wggHboAMCAQICBAGMuoQwCgYIKoUDBwEBAwIwODENMAsG - A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0MB4XDTAxMDEwMTAwMDAwMFoXDTQ5MTIzMTAwMDAwMFowOzENMAsGA1UEChME - VEsyNjEqMCgGA1UEAxMhT1JJR0lOQVRPUjogR09TVCAzNC4xMC0xMiA1MTItYml0 - MIGgMBcGCCqFAwcBAQECMAsGCSqFAwcBAgECAQOBhAAEgYC0i7davCkOGGVcYqFP - tS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO+K21LDpYVfDPs2Sqa13ZN+Ts - /JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0EmZf8T3ae/J1Jo6xGunecH1/G4 - hMts9HYLnxbwJDMNVGuIHV6gzqOBhzCBhDBjBgNVHSMEXDBagBSsbA5MRGaiQpbi - nwk7JWbzy6RTKqE8pDowODENMAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsy - NjogR09TVCAzNC4xMC0xMiAyNTYtYml0ggQBjLqBMB0GA1UdDgQWBBR+BlcJmAyt - awioV+55AFg6ydegpDAKBggqhQMHAQEDAgNBAApeqfHQG6YvR5Pt5oDMiNFiIdey - K5a0qf5gdBe2czLfF1A9Q8M9ya658Xl53zLzgOQXVCfYQsg4DFQBrPyHBBAxVDAj - BgkqhkiG9w0BCRUxFgQUeVV0+dS25MICJChpmGc/8AoUwE0wLQYJKoZIhvcNAQkU - MSAeHgBwADEAMgBGAHIAaQBlAG4AZABsAHkATgBhAG0AZTCCAdkGCSqGSIb3DQEH - AaCCAcoEggHGMIIBwjCCAb4GCyqGSIb3DQEMCgECoIIBVzCCAVMwWQYJKoZIhvcN - AQUNMEwwKQYJKoZIhvcNAQUMMBwECKf4N7NMwugqAgIIADAMBggqhQMHAQEEAgUA - MB8GCSqFAwcBAQUCAjASBBAlmt2WDfaPJlsAs0mLKglzBIH1DMvEacbbWRNDVSnX - JLWygYrKoipdOjDA/2HEnBZ34uFOLNheUqiKpCPoFpbR2GBiVYVTVK9ibiczgaca - EQYzDXtcS0QCZOxpKWfteAlbdJLC/SqPurPYyKi0MVRUPROhbisFASDT38HDH1Dh - 0dL5f6ga4aPWLrWbbgWERFOoOPyh4DotlPF37AQOwiEjsbyyRHq3HgbWiaxQRuAh - eqHOn4QVGY92/HFvJ7u3TcnQdLWhTe/lh1RHLNF3RnXtN9if9zC23laDZOiWZplU - yLrUiTCbHrtn1RppPDmLFNMt9dJ7KKgCkOi7Zm5nhqPChbywX13wcfYxVDAjBgkq - hkiG9w0BCRUxFgQUeVV0+dS25MICJChpmGc/8AoUwE0wLQYJKoZIhvcNAQkUMSAe - HgBwADEAMgBGAHIAaQBlAG4AZABsAHkATgBhAG0AZTBeME4wCgYIKoUDBwEBAgME - QAkBKw4ihn7pSIYTEhu0bcvTPZjI3WgVxCkUVlOsc80G69EKFEOTnObGJGSKJ51U - KkOsXF0a7+VBZf3BcVVQh9UECIVEtO+VpuskAgIIAA== - """) - pfx = PFX().decod(pfx_raw) - _, outer_safe_contents = pfx["authSafe"]["content"].defined - - safe_contents = OctetStringSafeContents().decod(bytes( - outer_safe_contents[0]["bagValue"] - )) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_certBag) - cert_bag = CertBag().decod(bytes(safe_bag["bagValue"])) - self.assertEqual(cert_bag["certId"], id_pkcs9_certTypes_x509Certificate) - _, cert = cert_bag["certValue"].defined - self.assertEqual(Certificate(cert), self.cert_test) - - safe_contents = OctetStringSafeContents().decod(bytes( - outer_safe_contents[1]["bagValue"] - )) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_pkcs8ShroudedKeyBag) - shrouded_key_bag = PKCS8ShroudedKeyBag().decod(bytes(safe_bag["bagValue"])) - _, pbes2_params = shrouded_key_bag["encryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - ukm = bytes(enc_scheme_params["ukm"]) - key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("4b7ae649ca31dd5fe3243a91a5188c03f1d7049bec8e0d241c0e1e8c39ea4c1f") - key_enc, key_mac = kdf_tree_gostr3411_2012_256( - key, b"kdf tree", ukm[GOST3412Kuznechik.blocksize // 2:], 2, - ) - ciphertext = bytes(shrouded_key_bag["encryptedData"]) - plaintext = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(key_enc).encrypt, - section_size=256 * 1024, - bs=GOST3412Kuznechik.blocksize, - data=ciphertext, - iv=ukm[:GOST3412Kuznechik.blocksize // 2], - ) - mac_expected = plaintext[-GOST3412Kuznechik.blocksize:] - plaintext = plaintext[:-GOST3412Kuznechik.blocksize] - mac = omac( - GOST3412Kuznechik(key_mac).encrypt, - GOST3412Kuznechik.blocksize, - plaintext, - ) - self.assertSequenceEqual(mac, mac_expected) - self.assertSequenceEqual(plaintext, self.prv_test_raw) - - mac_data = pfx["macData"] - mac_key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(mac_data["macSalt"]), - iterations=int(mac_data["iterations"]), - dklen=96, - )[-32:] - # mac_key = hexdec("a81d1bc91a4a5cf1fd7320f92dda7e5b285816c3b20826a382d7ed0cbf3a9bf4") - self.assertSequenceEqual( - hmac_new( - key=mac_key, - msg=SafeContents(outer_safe_contents).encode(), - digestmod=GOST34112012512, - ).digest(), - bytes(mac_data["mac"]["digest"]), - ) - self.assertTrue(gost3410.verify( - self.ca_curve, - self.ca_pub, - GOST34112012256(cert["tbsCertificate"].encode()).digest()[::-1], - bytes(cert["signatureValue"]), - )) - - def test_encrypted_cert_and_key(self): - pfx_raw = b64decode(b""" - MIIFjAIBAzCCBSUGCSqGSIb3DQEHAaCCBRYEggUSMIIFDjCCA0EGCSqGSIb3DQEH - BqCCAzIwggMuAgEAMIIDJwYJKoZIhvcNAQcBMFUGCSqGSIb3DQEFDTBIMCkGCSqG - SIb3DQEFDDAcBAgUuSVGsSwGjQICCAAwDAYIKoUDBwEBBAIFADAbBgkqhQMHAQEF - AQIwDgQM9Hk3dagtS48+G/x+gIICwWGPqxxN+sTrKbruRf9R5Ya9cf5AtO1frqMn - f1eULfmZmTg/BdE51QQ+Vbnh3v1kmspr6h2+e4Wli+ndEeCWG6A6X/G22h/RAHW2 - YrVmf6cCWxW+YrqzT4h/8RQL/9haunD5LmHPLVsYrEai0OwbgXayDSwARVJQLQYq - sLNmZK5ViN+fRiS5wszVJ3AtVq8EuPt41aQEKwPy2gmH4S6WmnQRC6W7aoqmIifF - PJENJNn5K2M1J6zNESs6bFtYNKMArNqtvv3rioY6eAaaLy6AV6ljsekmqodHmQjv - Y4eEioJs0xhpXhZY69PXT+ZBeHv6MSheBhwXqxAd1DqtPTafMjNK8rqKCap9TtPG - vONvo5W9dgwegxRRQzlum8dzV4m1W9Aq4W7t8/UcxDWRz3k6ijFPlGaA9+8ZMTEO - RHhBRvM6OY2/VNNxbgxWfGYuPxpSi3YnCZIPmBEe5lU/Xv7KjzFusGM38F8YR61k - 4/QNpKI1QUv714YKfaUQznshGGzILv1NGID62pl1+JI3vuawi2mDMrmkuM9QFU9v - /kRP+c2uBHDuOGEUUSNhF08p7+w3vxplatGWXH9fmIsPBdk2f3wkn+rwoqrEuijM - I/bCAylU/M0DMKhAo9j31UYSZdi4fsfRWYDJMq/8FPn96tuo+oCpbqv3NUwpZM/8 - Li4xqgTHtYw/+fRG0/P6XadNEiII/TYjenLfVHXjAHOVJsVeCu/t3EsMYHQddNCh - rFk/Ic2PdIQOyB4/enpW0qrKegSbyZNuF1WI4zl4mI89L8dTQBUkhy45yQXZlDD8 - k1ErYdtdEsPtz/4zuSpbnmwCEIRoOuSXtGuJP+tbcWEXRKM2UBgi3qBjpn7DU18M - tsrRM9pDdadl8mT/Vfh9+B8dZBZVxgQu70lMPEGexbUkYHuFCCnyi9J0V92StbIz - Elxla1VebjCCAcUGCSqGSIb3DQEHAaCCAbYEggGyMIIBrjCCAaoGCyqGSIb3DQEM - CgECoIIBQzCCAT8wVQYJKoZIhvcNAQUNMEgwKQYJKoZIhvcNAQUMMBwECP0EQk0O - 1twvAgIIADAMBggqhQMHAQEEAgUAMBsGCSqFAwcBAQUBATAOBAzwxSqgAAAAAAAA - AAAEgeUqj9mI3RDfK5hMd0EeYws7foZK/5ANr2wUhP5qnDjAZgn76lExJ+wuvlnS - 9PChfWVugvdl/9XJgQvvr9Cu4pOh4ICXplchcy0dGk/MzItHRVC5wK2nTxwQ4kKT - kG9xhLFzoD16dhtqX0+/dQg9G8pE5EzCBIYRXLm1Arcz9k7KVsTJuNMjFrr7EQuu - Tr80ATSQOtsq50zpFyrpznVPGCrOdIjpymZxNdvw48bZxqTtRVDxCYATOGqz0pwH - ClWULHD9LIajLMB2GhBKyQw6ujIlltJs0T+WNdX/AT2FLi1LFSS3+Cj9MVQwIwYJ - KoZIhvcNAQkVMRYEFHlVdPnUtuTCAiQoaZhnP/AKFMBNMC0GCSqGSIb3DQEJFDEg - Hh4AcAAxADIARgByAGkAZQBuAGQAbAB5AE4AYQBtAGUwXjBOMAoGCCqFAwcBAQID - BEDp4e22JmXdnvR0xA99yQuzQuJ8pxBeOpsLm2dZQqt3Fje5zqW1uk/7VOcfV5r2 - bKm8nsLOs2rPT8hBOoeAZvOIBAjGIUHw6IjG2QICCAA= - """) - pfx = PFX().decod(pfx_raw) - _, outer_safe_contents = pfx["authSafe"]["content"].defined - - encrypted_data = EncryptedData().decod(bytes( - outer_safe_contents[0]["bagValue"] - )) - eci = encrypted_data["encryptedContentInfo"] - self.assertEqual(eci["contentEncryptionAlgorithm"]["algorithm"], id_pbes2) - pbes2_params = PBES2Params().decod(bytes( - eci["contentEncryptionAlgorithm"]["parameters"] - )) - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - ukm = bytes(enc_scheme_params["ukm"]) - key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("d066a96fb326ba896a2352d3f40240a4ded6e7e7bd5b4db6b5241d631c8c381c") - key_enc, key_mac = kdf_tree_gostr3411_2012_256( - key, b"kdf tree", ukm[GOST3412Magma.blocksize // 2:], 2, - ) - ciphertext = bytes(eci["encryptedContent"]) - plaintext = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(key_enc).encrypt, - section_size=8 * 1024, - bs=GOST3412Magma.blocksize, - data=ciphertext, - iv=ukm[:GOST3412Magma.blocksize // 2], - ) - mac_expected = plaintext[-GOST3412Magma.blocksize:] - plaintext = plaintext[:-GOST3412Magma.blocksize] - mac = omac( - GOST3412Magma(key_mac).encrypt, - GOST3412Magma.blocksize, - plaintext, - ) - self.assertSequenceEqual(mac, mac_expected) - - safe_contents = SafeContents().decod(plaintext) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_certBag) - cert_bag = CertBag().decod(bytes(safe_bag["bagValue"])) - self.assertEqual(cert_bag["certId"], id_pkcs9_certTypes_x509Certificate) - _, cert = cert_bag["certValue"].defined - self.assertEqual(Certificate(cert), self.cert_test) - - safe_contents = OctetStringSafeContents().decod(bytes( - outer_safe_contents[1]["bagValue"] - )) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_pkcs8ShroudedKeyBag) - shrouded_key_bag = PKCS8ShroudedKeyBag().decod(bytes(safe_bag["bagValue"])) - _, pbes2_params = shrouded_key_bag["encryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - ukm = bytes(enc_scheme_params["ukm"]) - key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("f840d001fd11441e0fb7ccf48f471915e5bf35275309dbe7ade9da4fe460ba7e") - ciphertext = bytes(shrouded_key_bag["encryptedData"]) - plaintext = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(key).encrypt, - section_size=8 * 1024, - bs=GOST3412Magma.blocksize, - data=ciphertext, - iv=ukm[:GOST3412Magma.blocksize // 2], - ) - self.assertSequenceEqual(plaintext, self.prv_test_raw) - - mac_data = pfx["macData"] - mac_key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(mac_data["macSalt"]), - iterations=int(mac_data["iterations"]), - dklen=96, - )[-32:] - # mac_key = hexdec("084f81782af1534ffd67e3c579c14cb45d7a6f659f46fdbb51a552e874e66fb2") - self.assertSequenceEqual( - hmac_new( - key=mac_key, - msg=SafeContents(outer_safe_contents).encode(), - digestmod=GOST34112012512, - ).digest(), - bytes(mac_data["mac"]["digest"]), - ) - - def test_dh(self): - curve = gost3410.CURVES["id-tc26-gost-3410-12-256-paramSetA"] - # sender_prv_raw = hexdec("0B20810E449978C7C3B76C6FF77A16C532421139344A058EF56310B6B6F377E8") - sender_cert = Certificate().decod(b64decode(""" - MIIB6zCCAZigAwIBAgIEAYy6gjAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 - MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw - MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYD - VQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwXjAXBggqhQMH - AQEBATALBgkqhQMHAQIBAQEDQwAEQJYpDRNiWWqDgaZje0EmLLOldQ35o5X1ZuZN - SKequYQc/soI3OgDMWD7ThJJCk01IelCeb6MsBmG4lol+pnpVtOjgYcwgYQwYwYD - VR0jBFwwWoAUrGwOTERmokKW4p8JOyVm88ukUyqhPKQ6MDgxDTALBgNVBAoTBFRL - MjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6 - gTAdBgNVHQ4EFgQUPx5RgcjkifhlJm4/jQdkbm30rVQwCgYIKoUDBwEBAwIDQQA6 - 8x7Vk6PvP/8xOGHhf8PuqaXAYskSyJPuBu+3Bo/PEj10devwc1J9uYWIDCGdKKPy - bSlnQHqUPBBPM30YX1YN - """)) - recipient_prv_raw = hexdec("0DC8DC1FF2BC114BABC3F1CA8C51E4F58610427E197B1C2FBDBA4AE58CBFB7CE")[::-1] - recipient_prv = gost3410.prv_unmarshal(recipient_prv_raw) - recipient_cert = Certificate().decod(b64decode(""" - MIIB6jCCAZegAwIBAgIEAYy6gzAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 - MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw - MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA6MQ0wCwYDVQQKEwRUSzI2MSkwJwYD - VQQDEyBSRUNJUElFTlQ6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdDBeMBcGCCqFAwcB - AQEBMAsGCSqFAwcBAgEBAQNDAARAvyeCGXMsYwpYe5aE0w8w3m4vpKQapGInqpnF - lv7h08psFP0s1W80q3BR534F4TmR+o5+iU+AW6ycvWuc73JEQ6OBhzCBhDBjBgNV - HSMEXDBagBSsbA5MRGaiQpbinwk7JWbzy6RTKqE8pDowODENMAsGA1UEChMEVEsy - NjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0ggQBjLqB - MB0GA1UdDgQWBBQ35gHPN1bx8l2eEMTbrtIg+5MU0TAKBggqhQMHAQEDAgNBABF2 - RHDaRqQuBS2yu7yGIGFgA6c/LG4GKjSOwYsRVmXJNNkQ4TB7PB8j3q7gx2koPsVB - m90WfMWSL6SNSh3muuM= - """)) - self.assertTrue(gost3410.verify( - self.ca_curve, - self.ca_pub, - GOST34112012256(sender_cert["tbsCertificate"].encode()).digest()[::-1], - bytes(sender_cert["signatureValue"]), - )) - self.assertTrue(gost3410.verify( - self.ca_curve, - self.ca_pub, - GOST34112012256(recipient_cert["tbsCertificate"].encode()).digest()[::-1], - bytes(recipient_cert["signatureValue"]), - )) - - pfx_raw = b64decode(""" - MIIKVwIBAzCCClAGCSqGSIb3DQEHAqCCCkEwggo9AgEBMQwwCgYIKoUDBwEBAgIw - ggcjBgkqhkiG9w0BBwGgggcUBIIHEDCCBwwwggKdBgkqhkiG9w0BBwGgggKOBIIC - ijCCAoYwggKCBgsqhkiG9w0BDAoBA6CCAkowggJGBgoqhkiG9w0BCRYBoIICNgSC - AjIwggIuMIIB26ADAgECAgQBjLqEMAoGCCqFAwcBAQMCMDgxDTALBgNVBAoTBFRL - MjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdDAeFw0w - MTAxMDEwMDAwMDBaFw00OTEyMzEwMDAwMDBaMDsxDTALBgNVBAoTBFRLMjYxKjAo - BgNVBAMTIU9SSUdJTkFUT1I6IEdPU1QgMzQuMTAtMTIgNTEyLWJpdDCBoDAXBggq - hQMHAQEBAjALBgkqhQMHAQIBAgEDgYQABIGAtIu3WrwpDhhlXGKhT7UtX1CETswd - H2AESHtLXJU0aWq3v6s0blUWqas8zvittSw6WFXwz7Nkqmtd2Tfk7PyVJb+faghQ - dnGKRcgf9JIePiu/cr8+6/PuFhNBJmX/E92nvydSaOsRrp3nB9fxuITLbPR2C58W - 8CQzDVRriB1eoM6jgYcwgYQwYwYDVR0jBFwwWoAUrGwOTERmokKW4p8JOyVm88uk - UyqhPKQ6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1Qg - MzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQUfgZXCZgMrWsIqFfueQBY - OsnXoKQwCgYIKoUDBwEBAwIDQQAKXqnx0BumL0eT7eaAzIjRYiHXsiuWtKn+YHQX - tnMy3xdQPUPDPcmuufF5ed8y84DkF1Qn2ELIOAxUAaz8hwQQMSUwIwYJKoZIhvcN - AQkVMRYEFHlVdPnUtuTCAiQoaZhnP/AKFMBNMIIEZwYJKoZIhvcNAQcDoIIEWDCC - BFQCAQKgggHzoIIB7zCCAeswggGYoAMCAQICBAGMuoIwCgYIKoUDBwEBAwIwODEN - MAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAy - NTYtYml0MB4XDTAxMDEwMTAwMDAwMFoXDTQ5MTIzMTAwMDAwMFowOzENMAsGA1UE - ChMEVEsyNjEqMCgGA1UEAxMhT1JJR0lOQVRPUjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0MF4wFwYIKoUDBwEBAQEwCwYJKoUDBwECAQEBA0MABECWKQ0TYllqg4GmY3tB - JiyzpXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZhuJaJfqZ - 6VbTo4GHMIGEMGMGA1UdIwRcMFqAFKxsDkxEZqJCluKfCTslZvPLpFMqoTykOjA4 - MQ0wCwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEy - IDI1Ni1iaXSCBAGMuoEwHQYDVR0OBBYEFD8eUYHI5In4ZSZuP40HZG5t9K1UMAoG - CCqFAwcBAQMCA0EAOvMe1ZOj7z//MThh4X/D7qmlwGLJEsiT7gbvtwaPzxI9dHXr - 8HNSfbmFiAwhnSij8m0pZ0B6lDwQTzN9GF9WDTGB/6GB/AIBA6BCMEAwODENMAsG - A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0AgQBjLqCoSIEIBt4fjey+k8C1D3OaMca8wl6h3j3C6OAbrx8rmxXktsQMBcG - CSqFAwcBAQcCATAKBggqhQMHAQEGATB2MHQwQDA4MQ0wCwYDVQQKEwRUSzI2MScw - JQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQCBAGMuoMEMJkp - Wae6IVfaY3mP0izRY7ifc41fATXdJ2tmTl+1vitkSE2vLCKXDLl90KfHA6gNmDCC - AVQGCSqGSIb3DQEHATAfBgkqhQMHAQEFAgEwEgQQFhEshEBO2LkAAAAAAAAAAICC - ASQYvLpT/8azEXJfekyGuyvE9UkVX+Ao8sfu9My/c4WAVRNMhZkCqD+BbPwBsIzN - sXZIi9rXGAfsPz7xaO9EUFZPjNOWtF/E01oJgG+gYLFn7qAiEFcmRLptSHuanNHn - 7Yol6IHushX4UaW9hEa/L6eFQx/hoDhrNZnWTXNZtNuHuMGC9dzhHhTxfkdjZYXD - v+M7psVj58JutE3U2d4pgxKcBPdMO4vl4+27cIKxQZFZU2zuCVJLYLqmPT5pCBkM - mJqy7bZwHOJ9kBq/TGUf8iJGYSCNre3RTNLbcTTk7rZrbiMkFsG3borzenpouS5E - BcCkBt8Mj0nvsMCu9ipHTuWww7LltlkXCjlNXFUi6ZI3VyHW5CDpghujQWiZxiAc - JuGl6GwZoIIB7zCCAeswggGYoAMCAQICBAGMuoIwCgYIKoUDBwEBAwIwODENMAsG - A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0MB4XDTAxMDEwMTAwMDAwMFoXDTQ5MTIzMTAwMDAwMFowOzENMAsGA1UEChME - VEsyNjEqMCgGA1UEAxMhT1JJR0lOQVRPUjogR09TVCAzNC4xMC0xMiAyNTYtYml0 - MF4wFwYIKoUDBwEBAQEwCwYJKoUDBwECAQEBA0MABECWKQ0TYllqg4GmY3tBJiyz - pXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZhuJaJfqZ6VbT - o4GHMIGEMGMGA1UdIwRcMFqAFKxsDkxEZqJCluKfCTslZvPLpFMqoTykOjA4MQ0w - CwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1 - Ni1iaXSCBAGMuoEwHQYDVR0OBBYEFD8eUYHI5In4ZSZuP40HZG5t9K1UMAoGCCqF - AwcBAQMCA0EAOvMe1ZOj7z//MThh4X/D7qmlwGLJEsiT7gbvtwaPzxI9dHXr8HNS - fbmFiAwhnSij8m0pZ0B6lDwQTzN9GF9WDTGCAQ4wggEKAgEBMEAwODENMAsGA1UE - ChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0 - AgQBjLqCMAoGCCqFAwcBAQICoGkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc - BgkqhkiG9w0BCQUxDxcNMjEwNDE0MTkyMTEyWjAvBgkqhkiG9w0BCQQxIgQg1XOA - zNa710QuXsn5+yIf3cNTiFOQMgTiBRJBz8Tr4I0wCgYIKoUDBwEBAQEEQALINal9 - 7wHXYiG+w0yzSkKOs0jRZew0S73r/cfk/sUoM3HKKIEbKruvlAdiOqX/HLFSEx/s - kxFG6QUFH8uuoX8= - """) - pfx = PFX().decod(pfx_raw) - self.assertEqual(pfx["authSafe"]["contentType"], id_signedData) - - sd = SignedData().decod(bytes(pfx["authSafe"]["content"])) - self.assertEqual(sd["certificates"][0]["certificate"], sender_cert) - si = sd["signerInfos"][0] - self.assertEqual( - si["digestAlgorithm"]["algorithm"], - id_tc26_gost3411_2012_256, - ) - digest = [ - bytes(attr["attrValues"][0].defined[1]) for attr in si["signedAttrs"] - if attr["attrType"] == id_messageDigest - ][0] - sender_pub = gost3410.pub_unmarshal(bytes(OctetString().decod(bytes( - sender_cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - )))) - content = bytes(sd["encapContentInfo"]["eContent"]) - self.assertSequenceEqual(digest, GOST34112012256(content).digest()) - self.assertTrue(gost3410.verify( - curve, - sender_pub, - GOST34112012256( - SignedAttributes(si["signedAttrs"]).encode() - ).digest()[::-1], - bytes(si["signature"]), - )) - - outer_safe_contents = SafeContents().decod(content) - - safe_bag = outer_safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_data) - safe_contents = OctetStringSafeContents().decod(bytes(safe_bag["bagValue"])) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_certBag) - cert_bag = CertBag().decod(bytes(safe_bag["bagValue"])) - self.assertEqual(cert_bag["certId"], id_pkcs9_certTypes_x509Certificate) - _, cert = cert_bag["certValue"].defined - self.assertEqual(Certificate(cert), self.cert_test) - - safe_bag = outer_safe_contents[1] - self.assertEqual(safe_bag["bagId"], id_envelopedData) - ed = EnvelopedData().decod(bytes(safe_bag["bagValue"])) - kari = ed["recipientInfos"][0]["kari"] - ukm = bytes(kari["ukm"]) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_wrap_kexp15, - ) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_256, - ) - kexp = bytes(kari["recipientEncryptedKeys"][0]["encryptedKey"]) - keymat = keg(curve, recipient_prv, sender_pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Kuznechik(kek).encrypt, - GOST3412Kuznechik(kim).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - ukm[24:24 + GOST3412Kuznechik.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(cek).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - bytes(eci["encryptedContent"]), - eci_ukm[:GOST3412Kuznechik.blocksize // 2], - ) - - safe_contents = SafeContents().decod(content) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_keyBag) - KeyBag().decod(bytes(safe_bag["bagValue"])) - self.assertSequenceEqual(bytes(safe_bag["bagValue"]), self.prv_test_raw) diff --git a/pygost-5.13/build/lib/pygost/test_wrap.py b/pygost-5.13/build/lib/pygost/test_wrap.py deleted file mode 100644 index 7ecf8ee..0000000 --- a/pygost-5.13/build/lib/pygost/test_wrap.py +++ /dev/null @@ -1,111 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.utils import hexdec -from pygost.wrap import kexp15 -from pygost.wrap import kimp15 -from pygost.wrap import unwrap_cryptopro -from pygost.wrap import unwrap_gost -from pygost.wrap import wrap_cryptopro -from pygost.wrap import wrap_gost - - -class WrapGostTest(TestCase): - def test_symmetric(self): - for sbox in (DEFAULT_SBOX, "id-tc26-gost-28147-param-Z"): - for _ in range(1 << 8): - kek = urandom(32) - cek = urandom(32) - ukm = urandom(8) - wrapped = wrap_gost(ukm, kek, cek, sbox=sbox) - unwrapped = unwrap_gost(kek, wrapped, sbox=sbox) - self.assertSequenceEqual(unwrapped, cek) - - def test_invalid_length(self): - with self.assertRaises(ValueError): - unwrap_gost(urandom(32), urandom(41)) - with self.assertRaises(ValueError): - unwrap_gost(urandom(32), urandom(45)) - - -class WrapCryptoproTest(TestCase): - def test_symmetric(self): - for sbox in (DEFAULT_SBOX, "id-tc26-gost-28147-param-Z"): - for _ in range(1 << 8): - kek = urandom(32) - cek = urandom(32) - ukm = urandom(8) - wrapped = wrap_cryptopro(ukm, kek, cek, sbox=sbox) - unwrapped = unwrap_cryptopro(kek, wrapped, sbox=sbox) - self.assertSequenceEqual(unwrapped, cek) - - -class TestVectorKExp15(TestCase): - """Test vectors from Р 1323565.1.017-2018 - """ - key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF") - key_enc = hexdec("202122232425262728292A2B2C2D2E2F38393A3B3C3D3E3F3031323334353637") - key_mac = hexdec("08090A0B0C0D0E0F0001020304050607101112131415161718191A1B1C1D1E1F") - - def test_magma(self): - iv = hexdec("67BED654") - kexp = kexp15( - GOST3412Magma(self.key_enc).encrypt, - GOST3412Magma(self.key_mac).encrypt, - GOST3412Magma.blocksize, - self.key, - iv, - ) - self.assertSequenceEqual(kexp, hexdec(""" -CF D5 A1 2D 5B 81 B6 E1 E9 9C 91 6D 07 90 0C 6A -C1 27 03 FB 3A BD ED 55 56 7B F3 74 2C 89 9C 75 -5D AF E7 B4 2E 3A 8B D9 - """.replace("\n", "").replace(" ", ""))) - self.assertSequenceEqual(kimp15( - GOST3412Magma(self.key_enc).encrypt, - GOST3412Magma(self.key_mac).encrypt, - GOST3412Magma.blocksize, - kexp, - iv, - ), self.key) - - def test_kuznechik(self): - iv = hexdec("0909472DD9F26BE8") - kexp = kexp15( - GOST3412Kuznechik(self.key_enc).encrypt, - GOST3412Kuznechik(self.key_mac).encrypt, - GOST3412Kuznechik.blocksize, - self.key, - iv, - ) - self.assertSequenceEqual(kexp, hexdec(""" -E3 61 84 E8 4E 8D 73 6F F3 6C C2 E5 AE 06 5D C6 -56 B2 3C 20 F5 49 B0 2F DF F8 8E 1F 3F 30 D8 C2 -9A 53 F3 CA 55 4D BA D8 0D E1 52 B9 A4 62 5B 32 - """.replace("\n", "").replace(" ", ""))) - self.assertSequenceEqual(kimp15( - GOST3412Kuznechik(self.key_enc).encrypt, - GOST3412Kuznechik(self.key_mac).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - iv, - ), self.key) diff --git a/pygost-5.13/build/lib/pygost/test_x509.py b/pygost-5.13/build/lib/pygost/test_x509.py deleted file mode 100644 index e9fccb7..0000000 --- a/pygost-5.13/build/lib/pygost/test_x509.py +++ /dev/null @@ -1,433 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from base64 import b64decode -from unittest import skipIf -from unittest import TestCase - -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_marshal -from pygost.gost3410 import pub_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410 import verify -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.utils import hexdec - -try: - - from pyderasn import Any - from pyderasn import BitString - from pyderasn import Boolean - from pyderasn import GeneralizedTime - from pyderasn import Integer - from pyderasn import OctetString - from pyderasn import PrintableString - from pyderasn import UTCTime - - from pygost.asn1schemas.oids import id_at_commonName - from pygost.asn1schemas.oids import id_ce_basicConstraints - from pygost.asn1schemas.oids import id_GostR3410_2001_TestParamSet - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetA - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetTest - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_256 - from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_512 - from pygost.asn1schemas.pkcs10 import Attributes - from pygost.asn1schemas.pkcs10 import CertificationRequest - from pygost.asn1schemas.pkcs10 import CertificationRequestInfo - from pygost.asn1schemas.x509 import AlgorithmIdentifier - from pygost.asn1schemas.x509 import AttributeType - from pygost.asn1schemas.x509 import AttributeTypeAndValue - from pygost.asn1schemas.x509 import AttributeValue - from pygost.asn1schemas.x509 import BasicConstraints - from pygost.asn1schemas.x509 import Certificate - from pygost.asn1schemas.x509 import CertificateList - from pygost.asn1schemas.x509 import CertificateSerialNumber - from pygost.asn1schemas.x509 import Extension - from pygost.asn1schemas.x509 import Extensions - from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters - from pygost.asn1schemas.x509 import Name - from pygost.asn1schemas.x509 import RDNSequence - from pygost.asn1schemas.x509 import RelativeDistinguishedName - from pygost.asn1schemas.x509 import SubjectPublicKeyInfo - from pygost.asn1schemas.x509 import TBSCertificate - from pygost.asn1schemas.x509 import TBSCertList - from pygost.asn1schemas.x509 import Time - from pygost.asn1schemas.x509 import Validity - from pygost.asn1schemas.x509 import Version - -except ImportError: - pyderasn_exists = False -else: - pyderasn_exists = True - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestCertificate(TestCase): - """Certificate test vectors from "Использования алгоритмов ГОСТ Р - 34.10, ГОСТ Р 34.11 в профиле сертификата и списке отзыва - сертификатов (CRL) инфраструктуры открытых ключей X.509" - (TK26IOK.pdf) - """ - - def process_cert(self, curve_name, hasher, prv_key_raw, cert_raw): - cert, tail = Certificate().decode(cert_raw, ctx={ - "defines_by_path": ( - ( - ( - "tbsCertificate", - "subjectPublicKeyInfo", - "algorithm", - "algorithm", - ), - ( - ( - ("..", "subjectPublicKey"), - { - id_tc26_gost3410_2012_256: OctetString(), - id_tc26_gost3410_2012_512: OctetString(), - }, - ), - ), - ), - ), - }) - self.assertSequenceEqual(tail, b"") - curve = CURVES[curve_name] - prv_key = prv_unmarshal(prv_key_raw) - spk = cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - self.assertIsNotNone(spk.defined) - _, pub_key_raw = spk.defined - pub_key = pub_unmarshal(bytes(pub_key_raw)) - self.assertSequenceEqual(pub_key, public_key(curve, prv_key)) - self.assertTrue(verify( - curve, - pub_key, - hasher(cert["tbsCertificate"].encode()).digest()[::-1], - bytes(cert["signatureValue"]), - )) - - def test_256(self): - cert_raw = b64decode(""" -MIICYjCCAg+gAwIBAgIBATAKBggqhQMHAQEDAjBWMSkwJwYJKoZIhvcNAQkBFhpH -b3N0UjM0MTAtMjAxMkBleGFtcGxlLmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIw -MTIgKDI1NiBiaXQpIGV4YW1wbGUwHhcNMTMxMTA1MTQwMjM3WhcNMzAxMTAxMTQw -MjM3WjBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxlLmNv -bTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgKDI1NiBiaXQpIGV4YW1wbGUwZjAf -BggqhQMHAQEBATATBgcqhQMCAiQABggqhQMHAQECAgNDAARAut/Qw1MUq9KPqkdH -C2xAF3K7TugHfo9n525D2s5mFZdD5pwf90/i4vF0mFmr9nfRwMYP4o0Pg1mOn5Rl -aXNYraOBwDCBvTAdBgNVHQ4EFgQU1fIeN1HaPbw+XWUzbkJ+kHJUT0AwCwYDVR0P -BAQDAgHGMA8GA1UdEwQIMAYBAf8CAQEwfgYDVR0BBHcwdYAU1fIeN1HaPbw+XWUz -bkJ+kHJUT0ChWqRYMFYxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDEyQGV4 -YW1wbGUuY29tMSkwJwYDVQQDEyBHb3N0UjM0MTAtMjAxMiAoMjU2IGJpdCkgZXhh -bXBsZYIBATAKBggqhQMHAQEDAgNBAF5bm4BbARR6hJLEoWJkOsYV3Hd7kXQQjz3C -dqQfmHrz6TI6Xojdh/t8ckODv/587NS5/6KsM77vc6Wh90NAT2s= - """) - prv_key_raw = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - self.process_cert( - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - GOST34112012256, - prv_key_raw, - cert_raw, - ) - - def test_512(self): - cert_raw = b64decode(""" -MIIC6DCCAlSgAwIBAgIBATAKBggqhQMHAQEDAzBWMSkwJwYJKoZIhvcNAQkBFhpH -b3N0UjM0MTAtMjAxMkBleGFtcGxlLmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIw -MTIgKDUxMiBiaXQpIGV4YW1wbGUwHhcNMTMxMDA0MDczNjA0WhcNMzAxMDAxMDcz -NjA0WjBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxlLmNv -bTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgKDUxMiBiaXQpIGV4YW1wbGUwgaow -IQYIKoUDBwEBAQIwFQYJKoUDBwECAQICBggqhQMHAQECAwOBhAAEgYATGQ9VCiM5 -FRGCQ8MEz2F1dANqhaEuywa8CbxOnTvaGJpFQVXQwkwvLFAKh7hk542vOEtxpKtT -CXfGf84nRhMH/Q9bZeAc2eO/yhxrsQhTBufa1Fuou2oe/jUOaG6RAtUUvRzhNTpp -RGGl1+EIY2vzzUua9j9Ol/gAoy/LNKQIfqOBwDCBvTAdBgNVHQ4EFgQUPcbTRXJZ -nHtjj+eBP7b5lcTMekIwCwYDVR0PBAQDAgHGMA8GA1UdEwQIMAYBAf8CAQEwfgYD -VR0BBHcwdYAUPcbTRXJZnHtjj+eBP7b5lcTMekKhWqRYMFYxKTAnBgkqhkiG9w0B -CQEWGkdvc3RSMzQxMC0yMDEyQGV4YW1wbGUuY29tMSkwJwYDVQQDEyBHb3N0UjM0 -MTAtMjAxMiAoNTEyIGJpdCkgZXhhbXBsZYIBATAKBggqhQMHAQEDAwOBgQBObS7o -ppPTXzHyVR1DtPa8b57nudJzI4czhsfeX5HDntOq45t9B/qSs8dC6eGxbhHZ9zCO -SFtxWYdmg0au8XI9Xb8vTC1qdwWID7FFjMWDNQZb6lYh/J+8F2xKylvB5nIlRZqO -o3eUNFkNyHJwQCk2WoOlO16zwGk2tdKH4KmD5w== - """) - prv_key_raw = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - self.process_cert( - "id-tc26-gost-3410-12-512-paramSetB", - GOST34112012512, - prv_key_raw, - cert_raw, - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestRFC4491bis(TestCase): - """Test vectors from https://tools.ietf.org/html/draft-deremin-rfc4491-bis-02 - """ - - def _test_vector( - self, - curve_name, - hsh, - ai_spki, - ai_sign, - cert_serial, - prv_hex, - cr_sign_hex, - cr_b64, - c_sign_hex, - c_b64, - crl_sign_hex, - crl_b64, - ): - prv_raw = hexdec(prv_hex)[::-1] - prv = prv_unmarshal(prv_raw) - curve = CURVES[curve_name] - pub = public_key(curve, prv) - pub_raw = pub_marshal(pub) - subj = Name(("rdnSequence", RDNSequence([ - RelativeDistinguishedName(( - AttributeTypeAndValue(( - ("type", AttributeType(id_at_commonName)), - ("value", AttributeValue(PrintableString("Example"))), - )), - )) - ]))) - spki = SubjectPublicKeyInfo(( - ("algorithm", ai_spki), - ("subjectPublicKey", BitString(OctetString(pub_raw).encode())), - )) - - # Certification request - cri = CertificationRequestInfo(( - ("version", Integer(0)), - ("subject", subj), - ("subjectPKInfo", spki), - ("attributes", Attributes()), - )) - sign = hexdec(cr_sign_hex) - self.assertTrue(verify( - curve, - pub, - hsh(cri.encode()).digest()[::-1], - sign, - )) - cr = CertificationRequest(( - ("certificationRequestInfo", cri), - ("signatureAlgorithm", ai_sign), - ("signature", BitString(sign)), - )) - self.assertSequenceEqual(cr.encode(), b64decode(cr_b64)) - - # Certificate - tbs = TBSCertificate(( - ("version", Version("v3")), - ("serialNumber", CertificateSerialNumber(cert_serial)), - ("signature", ai_sign), - ("issuer", subj), - ("validity", Validity(( - ("notBefore", Time(("utcTime", UTCTime(b"010101000000Z")))), - ("notAfter", Time(("generalTime", GeneralizedTime(b"20501231000000Z")))), - ))), - ("subject", subj), - ("subjectPublicKeyInfo", spki), - ("extensions", Extensions(( - Extension(( - ("extnID", id_ce_basicConstraints), - ("critical", Boolean(True)), - ("extnValue", OctetString( - BasicConstraints((("cA", Boolean(True)),)).encode() - )), - )), - ))), - )) - sign = hexdec(c_sign_hex) - self.assertTrue(verify( - curve, - pub, - hsh(tbs.encode()).digest()[::-1], - sign, - )) - cert = Certificate(( - ("tbsCertificate", tbs), - ("signatureAlgorithm", ai_sign), - ("signatureValue", BitString(sign)), - )) - self.assertSequenceEqual(cert.encode(), b64decode(c_b64)) - - # CRL - tbs = TBSCertList(( - ("version", Version("v2")), - ("signature", ai_sign), - ("issuer", subj), - ("thisUpdate", Time(("utcTime", UTCTime(b"140101000000Z")))), - ("nextUpdate", Time(("utcTime", UTCTime(b"140102000000Z")))), - )) - sign = hexdec(crl_sign_hex) - self.assertTrue(verify( - curve, - pub, - hsh(tbs.encode()).digest()[::-1], - sign, - )) - crl = CertificateList(( - ("tbsCertList", tbs), - ("signatureAlgorithm", ai_sign), - ("signatureValue", BitString(sign)), - )) - self.assertSequenceEqual(crl.encode(), b64decode(crl_b64)) - - def test_256_test_paramset(self): - self._test_vector( - "id-GostR3410-2001-TestParamSet", - GOST34112012256, - AlgorithmIdentifier(( - ("algorithm", id_tc26_gost3410_2012_256), - ("parameters", Any( - GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", id_GostR3410_2001_TestParamSet), - ("digestParamSet", id_tc26_gost3411_2012_256), - )) - )), - )), - AlgorithmIdentifier(( - ("algorithm", id_tc26_signwithdigest_gost3410_2012_256), - )), - 10, - "7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28", - "6AAAB38E35D4AAA517940301799122D855484F579F4CBB96D63CDFDF3ACC432A41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493", - """ -MIHTMIGBAgEAMBIxEDAOBgNVBAMTB0V4YW1wbGUwZjAfBggqhQMHAQEBATATBgcq -hQMCAiMABggqhQMHAQECAgNDAARAC9hv5djbiWaPeJtOHbqFhcVQi0XsW1nYkG3b -cOJJK3/ad/+HGhD73ydm0pPF0WSvuzx7lzpByIXRHXDWibTxJqAAMAoGCCqFAwcB -AQMCA0EAaqqzjjXUqqUXlAMBeZEi2FVIT1efTLuW1jzf3zrMQypBqijS8asUgoDN -ntVv7aQZdAU1VKQnZ7g60EP9OdwEkw== - """, - "4D53F012FE081776507D4D9BB81F00EFDB4EEFD4AB83BAC4BACF735173CFA81C41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493", - """ -MIIBLTCB26ADAgECAgEKMAoGCCqFAwcBAQMCMBIxEDAOBgNVBAMTB0V4YW1wbGUw -IBcNMDEwMTAxMDAwMDAwWhgPMjA1MDEyMzEwMDAwMDBaMBIxEDAOBgNVBAMTB0V4 -YW1wbGUwZjAfBggqhQMHAQEBATATBgcqhQMCAiMABggqhQMHAQECAgNDAARAC9hv -5djbiWaPeJtOHbqFhcVQi0XsW1nYkG3bcOJJK3/ad/+HGhD73ydm0pPF0WSvuzx7 -lzpByIXRHXDWibTxJqMTMBEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhQMHAQEDAgNB -AE1T8BL+CBd2UH1Nm7gfAO/bTu/Uq4O6xLrPc1Fzz6gcQaoo0vGrFIKAzZ7Vb+2k -GXQFNVSkJ2e4OtBD/TncBJM= - """, - "42BF392A14D3EBE957AF3E46CB50BF5F4221A003AD3D172753C94A9C37A31D2041AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493", - """ -MIGSMEECAQEwCgYIKoUDBwEBAwIwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx -MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAgNBAEK/OSoU0+vpV68+ -RstQv19CIaADrT0XJ1PJSpw3ox0gQaoo0vGrFIKAzZ7Vb+2kGXQFNVSkJ2e4OtBD -/TncBJM= - """, - ) - - def test_256a_paramset(self): - self._test_vector( - "id-tc26-gost-3410-2012-256-paramSetA", - GOST34112012256, - AlgorithmIdentifier(( - ("algorithm", id_tc26_gost3410_2012_256), - ("parameters", Any( - GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", id_tc26_gost3410_2012_256_paramSetA), - )) - )), - )), - AlgorithmIdentifier(( - ("algorithm", id_tc26_signwithdigest_gost3410_2012_256), - )), - 10, - "7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28", - "1BDC2A1317679B66232F63EA16FF7C64CCAAB9AD855FC6E18091661DB79D48121D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769", - """ -MIHKMHkCAQAwEjEQMA4GA1UEAxMHRXhhbXBsZTBeMBcGCCqFAwcBAQEBMAsGCSqF -AwcBAgEBAQNDAARAdCeV1L7ohN3yhQ/sA+o/rxhE4B2dpgtkUJOlXibfw5l49ZbP -TU0MbPHRiUPZRJPRa57AoW1RLS4SfMRpGmMY4qAAMAoGCCqFAwcBAQMCA0EAG9wq -Exdnm2YjL2PqFv98ZMyqua2FX8bhgJFmHbedSBIdDh2lvjR8bxtSVseurCAK1krH -em9bOg4Jcxjnrm7naQ== - """, - "140B4DA9124B09CB0D5CE928EE874273A310129492EC0E29369E3B791248578C1D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769", - """ -MIIBJTCB06ADAgECAgEKMAoGCCqFAwcBAQMCMBIxEDAOBgNVBAMTB0V4YW1wbGUw -IBcNMDEwMTAxMDAwMDAwWhgPMjA1MDEyMzEwMDAwMDBaMBIxEDAOBgNVBAMTB0V4 -YW1wbGUwXjAXBggqhQMHAQEBATALBgkqhQMHAQIBAQEDQwAEQHQnldS+6ITd8oUP -7APqP68YROAdnaYLZFCTpV4m38OZePWWz01NDGzx0YlD2UST0WuewKFtUS0uEnzE -aRpjGOKjEzARMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoUDBwEBAwIDQQAUC02pEksJ -yw1c6Sjuh0JzoxASlJLsDik2njt5EkhXjB0OHaW+NHxvG1JWx66sIArWSsd6b1s6 -DglzGOeubudp - """, - "14BD68087C3B903C7AA28B07FEB2E7BD6FE0963F563267359F5CD8EAB45059AD1D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769", - """ -MIGSMEECAQEwCgYIKoUDBwEBAwIwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx -MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAgNBABS9aAh8O5A8eqKL -B/6y571v4JY/VjJnNZ9c2Oq0UFmtHQ4dpb40fG8bUlbHrqwgCtZKx3pvWzoOCXMY -565u52k= - """, - ) - - def test_512_test_paramset(self): - self._test_vector( - "id-tc26-gost-3410-2012-512-paramSetTest", - GOST34112012512, - AlgorithmIdentifier(( - ("algorithm", id_tc26_gost3410_2012_512), - ("parameters", Any( - GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", id_tc26_gost3410_2012_512_paramSetTest), - )) - )), - )), - AlgorithmIdentifier(( - ("algorithm", id_tc26_signwithdigest_gost3410_2012_512), - )), - 11, - "0BA6048AADAE241BA40936D47756D7C93091A0E8514669700EE7508E508B102072E8123B2200A0563322DAD2827E2714A2636B7BFD18AADFC62967821FA18DD4", - "433B1D6CE40A51F1E5737EB16AA2C683829A405B9D9127E21260FC9D6AC05D87BF24E26C45278A5C2192A75BA94993ABD6074E7FF1BF03FD2F5397AFA1D945582F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36", - """ -MIIBTzCBvAIBADASMRAwDgYDVQQDEwdFeGFtcGxlMIGgMBcGCCqFAwcBAQECMAsG -CSqFAwcBAgECAAOBhAAEgYDh7zDVLGEz3dmdHVxBRVz3302LTJJbvGmvFDPRVlhR -Wt0hRoUMMlxbgcEzvmVaqMTUQOe5io1ZSHsMdpa8xV0R7L53NqnsNX/y/TmTH04R -TLjNo1knCsfw5/9D2UGUGeph/Sq3f12fY1I9O1CgT2PioM9Rt8E63CFWDwvUDMnH -N6AAMAoGCCqFAwcBAQMDA4GBAEM7HWzkClHx5XN+sWqixoOCmkBbnZEn4hJg/J1q -wF2HvyTibEUnilwhkqdbqUmTq9YHTn/xvwP9L1OXr6HZRVgvhvpgoIEJGiPdeV4e -PGie5RKjyC7g3MJkPHjuqPys01SSVYSGsg8cnsGXyQaZhQJgyTvLzZxcMxfhk0Th -c642 - """, - "415703D892F1A5F3F68C4353189A7EE207B80B5631EF9D49529A4D6B542C2CFA15AA2EACF11F470FDE7D954856903C35FD8F955EF300D95C77534A724A0EEE702F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36", - """ -MIIBqjCCARagAwIBAgIBCzAKBggqhQMHAQEDAzASMRAwDgYDVQQDEwdFeGFtcGxl -MCAXDTAxMDEwMTAwMDAwMFoYDzIwNTAxMjMxMDAwMDAwWjASMRAwDgYDVQQDEwdF -eGFtcGxlMIGgMBcGCCqFAwcBAQECMAsGCSqFAwcBAgECAAOBhAAEgYDh7zDVLGEz -3dmdHVxBRVz3302LTJJbvGmvFDPRVlhRWt0hRoUMMlxbgcEzvmVaqMTUQOe5io1Z -SHsMdpa8xV0R7L53NqnsNX/y/TmTH04RTLjNo1knCsfw5/9D2UGUGeph/Sq3f12f -Y1I9O1CgT2PioM9Rt8E63CFWDwvUDMnHN6MTMBEwDwYDVR0TAQH/BAUwAwEB/zAK -BggqhQMHAQEDAwOBgQBBVwPYkvGl8/aMQ1MYmn7iB7gLVjHvnUlSmk1rVCws+hWq -LqzxH0cP3n2VSFaQPDX9j5Ve8wDZXHdTSnJKDu5wL4b6YKCBCRoj3XleHjxonuUS -o8gu4NzCZDx47qj8rNNUklWEhrIPHJ7Bl8kGmYUCYMk7y82cXDMX4ZNE4XOuNg== - """, - "3A13FB7AECDB5560EEF6137CFC5DD64691732EBFB3690A1FC0C7E8A4EEEA08307D648D4DC0986C46A87B3FBE4C7AF42EA34359C795954CA39FF3ABBED9051F4D2F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36", - """ -MIHTMEECAQEwCgYIKoUDBwEBAwMwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx -MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAwOBgQA6E/t67NtVYO72 -E3z8XdZGkXMuv7NpCh/Ax+ik7uoIMH1kjU3AmGxGqHs/vkx69C6jQ1nHlZVMo5/z -q77ZBR9NL4b6YKCBCRoj3XleHjxonuUSo8gu4NzCZDx47qj8rNNUklWEhrIPHJ7B -l8kGmYUCYMk7y82cXDMX4ZNE4XOuNg== - """, - ) diff --git a/pygost-5.13/build/lib/pygost/utils.py b/pygost-5.13/build/lib/pygost/utils.py deleted file mode 100644 index 21c31b0..0000000 --- a/pygost-5.13/build/lib/pygost/utils.py +++ /dev/null @@ -1,101 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from codecs import getdecoder -from codecs import getencoder -from sys import version_info - - -xrange = range if version_info[0] == 3 else xrange - - -def strxor(a, b): - """XOR of two strings - - This function will process only shortest length of both strings, - ignoring remaining one. - """ - mlen = min(len(a), len(b)) - a, b, xor = bytearray(a), bytearray(b), bytearray(mlen) - for i in xrange(mlen): - xor[i] = a[i] ^ b[i] - return bytes(xor) - - -_hexdecoder = getdecoder("hex") -_hexencoder = getencoder("hex") - - -def hexdec(data): - """Decode hexadecimal - """ - return _hexdecoder(data)[0] - - -def hexenc(data): - """Encode hexadecimal - """ - return _hexencoder(data)[0].decode("ascii") - - -def bytes2long(raw): - """Deserialize big-endian bytes into long number - - :param bytes raw: binary string - :returns: deserialized long number - :rtype: int - """ - return int(hexenc(raw), 16) - - -def long2bytes(n, size=32): - """Serialize long number into big-endian bytestring - - :param long n: long number - :returns: serialized bytestring - :rtype: bytes - """ - res = hex(int(n))[2:].rstrip("L") - if len(res) % 2 != 0: - res = "0" + res - s = hexdec(res) - if len(s) != size: - s = (size - len(s)) * b"\x00" + s - return s - - -def modinvert(a, n): - """Modular multiplicative inverse - - :returns: inverse number. -1 if it does not exist - - Realization is taken from: - https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm - """ - if a < 0: - # k^-1 = p - (-k)^-1 mod p - return n - modinvert(-a, n) - t, newt = 0, 1 - r, newr = n, a - while newr != 0: - quotinent = r // newr - t, newt = newt, t - quotinent * newt - r, newr = newr, r - quotinent * newr - if r > 1: - return -1 - if t < 0: - t = t + n - return t diff --git a/pygost-5.13/build/lib/pygost/wrap.py b/pygost-5.13/build/lib/pygost/wrap.py deleted file mode 100644 index 3fa49e7..0000000 --- a/pygost-5.13/build/lib/pygost/wrap.py +++ /dev/null @@ -1,152 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Key wrap. - -:rfc:`4357` key wrapping (28147-89 and CryptoPro). -""" - -from hmac import compare_digest -from struct import pack -from struct import unpack - -from pygost.gost28147 import cfb_encrypt -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost28147 import ecb_decrypt -from pygost.gost28147 import ecb_encrypt -from pygost.gost28147_mac import MAC -from pygost.gost3413 import ctr -from pygost.gost3413 import mac - - -def wrap_gost(ukm, kek, cek, sbox=DEFAULT_SBOX): - """28147-89 key wrapping - - :param ukm: UKM - :type ukm: bytes, 8 bytes - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param cek: content encryption key - :type cek: bytes, 32 bytes - :returns: wrapped key - :rtype: bytes, 44 bytes - """ - cek_mac = MAC(kek, data=cek, iv=ukm, sbox=sbox).digest()[:4] - cek_enc = ecb_encrypt(kek, cek, sbox=sbox) - return ukm + cek_enc + cek_mac - - -def unwrap_gost(kek, data, sbox=DEFAULT_SBOX): - """28147-89 key unwrapping - - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param data: wrapped key - :type data: bytes, 44 bytes - :returns: unwrapped CEK - :rtype: 32 bytes - """ - if len(data) != 44: - raise ValueError("Invalid data length") - ukm, cek_enc, cek_mac = data[:8], data[8:8 + 32], data[-4:] - cek = ecb_decrypt(kek, cek_enc, sbox=sbox) - if MAC(kek, data=cek, iv=ukm, sbox=sbox).digest()[:4] != cek_mac: - raise ValueError("Invalid MAC") - return cek - - -def wrap_cryptopro(ukm, kek, cek, sbox=DEFAULT_SBOX): - """CryptoPro key wrapping - - :param ukm: UKM - :type ukm: bytes, 8 bytes - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param cek: content encryption key - :type cek: bytes, 32 bytes - :returns: wrapped key - :rtype: bytes, 44 bytes - """ - return wrap_gost( - ukm, - diversify(kek, bytearray(ukm), sbox=sbox), - cek, - sbox=sbox, - ) - - -def unwrap_cryptopro(kek, data, sbox=DEFAULT_SBOX): - """CryptoPro key unwrapping - - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param data: wrapped key - :type data: bytes, 44 bytes - :returns: unwrapped CEK - :rtype: 32 bytes - """ - if len(data) < 8: - raise ValueError("Invalid data length") - return unwrap_gost( - diversify(kek, bytearray(data[:8]), sbox=sbox), - data, - sbox=sbox, - ) - - -def diversify(kek, ukm, sbox=DEFAULT_SBOX): - out = kek - for i in range(8): - s1, s2 = 0, 0 - for j in range(8): - k, = unpack("> j) & 1: - s1 += k - else: - s2 += k - iv = pack(">> from pygost.gost3410 import CURVES - >>> curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - >>> from os import urandom - >>> prv_raw = urandom(64) - >>> from pygost.gost3410 import prv_unmarshal - >>> from pygost.gost3410 import prv_marshal - >>> prv = prv_unmarshal(prv_raw) - >>> prv_raw = prv_marshal(curve, prv) - >>> from pygost.gost3410 import public_key - >>> pub = public_key(curve, prv) - >>> from pygost.gost3410 import pub_marshal - >>> from pygost.utils import hexenc - >>> print "Public key is:", hexenc(pub_marshal(pub)) - >>> from pygost import gost34112012512 - >>> data_for_signing = b"some data" - >>> dgst = gost34112012512.new(data_for_signing).digest() - >>> from pygost.gost3410 import sign - >>> signature = sign(curve, prv, dgst) - >>> from pygost.gost3410 import verify - >>> verify(curve, pub, dgst, signature) - True - -Other examples can be found in docstrings and unittests. -Example self-signed X.509 certificate creation can be found in -pygost/asn1schemas/cert-selfsigned-example.py. - -PyGOST is free software: see the file COPYING for copying conditions. - -PyGOST'es home page is: http://www.pygost.cypherpunks.ru/ -You can read about GOST algorithms more: http://www.gost.cypherpunks.ru/ - -Please send questions, bug reports and patches to -http://lists.cypherpunks.ru/gost.html mailing list. -Announcements also go to this mailing list. - -Development Git source code repository currently is located here: -http://www.git.cypherpunks.ru/?p=pygost.git;a=summary diff --git a/pygost-5.13/pygost.egg-info/SOURCES.txt b/pygost-5.13/pygost.egg-info/SOURCES.txt deleted file mode 100644 index 781d116..0000000 --- a/pygost-5.13/pygost.egg-info/SOURCES.txt +++ /dev/null @@ -1,71 +0,0 @@ -AUTHORS -COPYING -FAQ -INSTALL -MANIFEST.in -NEWS -README -THANKS -VERSION -setup.cfg -setup.py -pygost/__init__.py -pygost/gost28147.py -pygost/gost28147_mac.py -pygost/gost3410.py -pygost/gost3410_vko.py -pygost/gost34112012.py -pygost/gost34112012256.py -pygost/gost34112012512.py -pygost/gost341194.py -pygost/gost3412.py -pygost/gost3413.py -pygost/iface.py -pygost/kdf.py -pygost/mgm.py -pygost/pbkdf2.py -pygost/test_cms.py -pygost/test_gost28147.py -pygost/test_gost28147_mac.py -pygost/test_gost3410.py -pygost/test_gost3410_vko.py -pygost/test_gost34112012.py -pygost/test_gost341194.py -pygost/test_gost3412.py -pygost/test_gost3413.py -pygost/test_kdf.py -pygost/test_mgm.py -pygost/test_pfx.py -pygost/test_wrap.py -pygost/test_x509.py -pygost/utils.py -pygost/wrap.py -pygost.egg-info/PKG-INFO -pygost.egg-info/SOURCES.txt -pygost.egg-info/dependency_links.txt -pygost.egg-info/top_level.txt -pygost/asn1schemas/__init__.py -pygost/asn1schemas/cert-dane-hash.py -pygost/asn1schemas/cert-selfsigned-example.py -pygost/asn1schemas/cms.py -pygost/asn1schemas/oids.py -pygost/asn1schemas/pfx.py -pygost/asn1schemas/pkcs10.py -pygost/asn1schemas/prvkey.py -pygost/asn1schemas/x509.py -pygost/stubs/pygost/__init__.pyi -pygost/stubs/pygost/gost28147.pyi -pygost/stubs/pygost/gost28147_mac.pyi -pygost/stubs/pygost/gost3410.pyi -pygost/stubs/pygost/gost3410_vko.pyi -pygost/stubs/pygost/gost34112012.pyi -pygost/stubs/pygost/gost34112012256.pyi -pygost/stubs/pygost/gost34112012512.pyi -pygost/stubs/pygost/gost341194.pyi -pygost/stubs/pygost/gost3412.pyi -pygost/stubs/pygost/gost3413.pyi -pygost/stubs/pygost/iface.pyi -pygost/stubs/pygost/kdf.pyi -pygost/stubs/pygost/mgm.pyi -pygost/stubs/pygost/utils.pyi -pygost/stubs/pygost/wrap.pyi \ No newline at end of file diff --git a/pygost-5.13/pygost.egg-info/dependency_links.txt b/pygost-5.13/pygost.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/pygost-5.13/pygost.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pygost-5.13/pygost.egg-info/top_level.txt b/pygost-5.13/pygost.egg-info/top_level.txt deleted file mode 100644 index d05bec6..0000000 --- a/pygost-5.13/pygost.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pygost diff --git a/pygost-5.13/pygost/__init__.py b/pygost-5.13/pygost/__init__.py deleted file mode 100644 index fba7932..0000000 --- a/pygost-5.13/pygost/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Pure Python GOST cryptographic functions library. - -PyGOST is free software: see the file COPYING for copying conditions. -""" - -__version__ = "5.13" diff --git a/pygost-5.13/pygost/asn1schemas/__init__.py b/pygost-5.13/pygost/asn1schemas/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygost-5.13/pygost/asn1schemas/cert-dane-hash.py b/pygost-5.13/pygost/asn1schemas/cert-dane-hash.py deleted file mode 100755 index 0292b9e..0000000 --- a/pygost-5.13/pygost/asn1schemas/cert-dane-hash.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python3 -"""DANE's SPKI hash calculator -""" - -from base64 import standard_b64decode -from hashlib import sha256 -import sys - -from pygost.asn1schemas.x509 import Certificate - - -lines = sys.stdin.read().split("-----") -idx = lines.index("BEGIN CERTIFICATE") -if idx == -1: - raise ValueError("PEM has no CERTIFICATE") -cert_raw = standard_b64decode(lines[idx + 1]) -cert = Certificate().decod(cert_raw) -print(sha256(cert["tbsCertificate"]["subjectPublicKeyInfo"].encode()).hexdigest()) diff --git a/pygost-5.13/pygost/asn1schemas/cert-selfsigned-example.py b/pygost-5.13/pygost/asn1schemas/cert-selfsigned-example.py deleted file mode 100755 index bd562b1..0000000 --- a/pygost-5.13/pygost/asn1schemas/cert-selfsigned-example.py +++ /dev/null @@ -1,348 +0,0 @@ -#!/usr/bin/env python3 -"""Create example self-signed X.509 certificate -""" - -from argparse import ArgumentParser -from base64 import standard_b64decode -from base64 import standard_b64encode -from datetime import datetime -from datetime import timedelta -from os import urandom -from sys import exit as sys_exit -from sys import stdout -from textwrap import fill - -from pyderasn import Any -from pyderasn import BitString -from pyderasn import Boolean -from pyderasn import IA5String -from pyderasn import Integer -from pyderasn import OctetString -from pyderasn import PrintableString -from pyderasn import UTCTime - -from pygost.asn1schemas.oids import id_at_commonName -from pygost.asn1schemas.oids import id_at_countryName -from pygost.asn1schemas.oids import id_ce_authorityKeyIdentifier -from pygost.asn1schemas.oids import id_ce_basicConstraints -from pygost.asn1schemas.oids import id_ce_keyUsage -from pygost.asn1schemas.oids import id_ce_subjectAltName -from pygost.asn1schemas.oids import id_ce_subjectKeyIdentifier -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetA -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetB -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetC -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetD -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetA -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetB -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetC -from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_512 -from pygost.asn1schemas.prvkey import PrivateKey -from pygost.asn1schemas.prvkey import PrivateKeyAlgorithmIdentifier -from pygost.asn1schemas.prvkey import PrivateKeyInfo -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import AttributeType -from pygost.asn1schemas.x509 import AttributeTypeAndValue -from pygost.asn1schemas.x509 import AttributeValue -from pygost.asn1schemas.x509 import AuthorityKeyIdentifier -from pygost.asn1schemas.x509 import BasicConstraints -from pygost.asn1schemas.x509 import Certificate -from pygost.asn1schemas.x509 import CertificateSerialNumber -from pygost.asn1schemas.x509 import Extension -from pygost.asn1schemas.x509 import Extensions -from pygost.asn1schemas.x509 import GeneralName -from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters -from pygost.asn1schemas.x509 import KeyIdentifier -from pygost.asn1schemas.x509 import KeyUsage -from pygost.asn1schemas.x509 import Name -from pygost.asn1schemas.x509 import RDNSequence -from pygost.asn1schemas.x509 import RelativeDistinguishedName -from pygost.asn1schemas.x509 import SubjectAltName -from pygost.asn1schemas.x509 import SubjectKeyIdentifier -from pygost.asn1schemas.x509 import SubjectPublicKeyInfo -from pygost.asn1schemas.x509 import TBSCertificate -from pygost.asn1schemas.x509 import Time -from pygost.asn1schemas.x509 import Validity -from pygost.asn1schemas.x509 import Version -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_marshal -from pygost.gost3410 import public_key -from pygost.gost3410 import sign -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.utils import bytes2long - -parser = ArgumentParser(description="Self-signed X.509 certificate creator") -parser.add_argument( - "--ca", - action="store_true", - help="Enable BasicConstraints.cA", -) -parser.add_argument( - "--cn", - required=True, - help="Subject's CommonName", -) -parser.add_argument( - "--country", - help="Subject's Country", -) -parser.add_argument( - "--serial", - help="Serial number", -) -parser.add_argument( - "--ai", - required=True, - help="Signing algorithm: {256[ABCD],512[ABC]}", -) -parser.add_argument( - "--issue-with", - help="Path to PEM with CA to issue the child", -) -parser.add_argument( - "--reuse-key", - help="Path to PEM with the key to reuse", -) -parser.add_argument( - "--out-key", - help="Path to PEM with the resulting key", -) -parser.add_argument( - "--only-key", - action="store_true", - help="Only generate the key", -) -parser.add_argument( - "--out-cert", - help="Path to PEM with the resulting certificate", -) -args = parser.parse_args() -AIs = { - "256A": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetA, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetA"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "256B": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetB, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetB"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "256C": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetC, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetC"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "256D": { - "publicKeyParamSet": id_tc26_gost3410_2012_256_paramSetD, - "key_algorithm": id_tc26_gost3410_2012_256, - "prv_len": 32, - "curve": CURVES["id-tc26-gost-3410-2012-256-paramSetD"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_256, - "hasher": GOST34112012256, - }, - "512A": { - "publicKeyParamSet": id_tc26_gost3410_2012_512_paramSetA, - "key_algorithm": id_tc26_gost3410_2012_512, - "prv_len": 64, - "curve": CURVES["id-tc26-gost-3410-12-512-paramSetA"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_512, - "hasher": GOST34112012512, - }, - "512B": { - "publicKeyParamSet": id_tc26_gost3410_2012_512_paramSetB, - "key_algorithm": id_tc26_gost3410_2012_512, - "prv_len": 64, - "curve": CURVES["id-tc26-gost-3410-12-512-paramSetB"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_512, - "hasher": GOST34112012512, - }, - "512C": { - "publicKeyParamSet": id_tc26_gost3410_2012_512_paramSetC, - "key_algorithm": id_tc26_gost3410_2012_512, - "prv_len": 64, - "curve": CURVES["id-tc26-gost-3410-2012-512-paramSetC"], - "sign_algorithm": id_tc26_signwithdigest_gost3410_2012_512, - "hasher": GOST34112012512, - }, -} -ai = AIs[args.ai] - -ca_prv = None -ca_cert = None -ca_subj = None -ca_ai = None -if args.issue_with is not None: - with open(args.issue_with, "rb") as fd: - lines = fd.read().decode("ascii").split("-----") - idx = lines.index("BEGIN PRIVATE KEY") - if idx == -1: - raise ValueError("PEM has no PRIVATE KEY") - prv_raw = standard_b64decode(lines[idx + 1]) - idx = lines.index("BEGIN CERTIFICATE") - if idx == -1: - raise ValueError("PEM has no CERTIFICATE") - cert_raw = standard_b64decode(lines[idx + 1]) - pki = PrivateKeyInfo().decod(prv_raw) - ca_prv = prv_unmarshal(bytes(OctetString().decod(bytes(pki["privateKey"])))) - ca_cert = Certificate().decod(cert_raw) - tbs = ca_cert["tbsCertificate"] - ca_subj = tbs["subject"] - curve_oid = GostR34102012PublicKeyParameters().decod(bytes( - tbs["subjectPublicKeyInfo"]["algorithm"]["parameters"] - ))["publicKeyParamSet"] - ca_ai = next(iter([ - params for params in AIs.values() - if params["publicKeyParamSet"] == curve_oid - ])) - -key_params = GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", ai["publicKeyParamSet"]), -)) - - -def pem(obj): - return fill(standard_b64encode(obj.encode()).decode("ascii"), 64) - - -if args.reuse_key is not None: - with open(args.reuse_key, "rb") as fd: - lines = fd.read().decode("ascii").split("-----") - idx = lines.index("BEGIN PRIVATE KEY") - if idx == -1: - raise ValueError("PEM has no PRIVATE KEY") - prv_raw = standard_b64decode(lines[idx + 1]) - pki = PrivateKeyInfo().decod(prv_raw) - prv = prv_unmarshal(bytes(OctetString().decod(bytes(pki["privateKey"])))) -else: - prv_raw = urandom(ai["prv_len"]) - out = stdout if args.out_key is None else open(args.out_key, "w") - print("-----BEGIN PRIVATE KEY-----", file=out) - print(pem(PrivateKeyInfo(( - ("version", Integer(0)), - ("privateKeyAlgorithm", PrivateKeyAlgorithmIdentifier(( - ("algorithm", ai["key_algorithm"]), - ("parameters", Any(key_params)), - ))), - ("privateKey", PrivateKey(OctetString(prv_raw).encode())), - ))), file=out) - print("-----END PRIVATE KEY-----", file=out) - if args.only_key: - sys_exit() - prv = prv_unmarshal(prv_raw) - -curve = ai["curve"] -pub_raw = pub_marshal(public_key(curve, prv)) -rdn = [RelativeDistinguishedName(( - AttributeTypeAndValue(( - ("type", AttributeType(id_at_commonName)), - ("value", AttributeValue(PrintableString(args.cn))), - )), -))] -if args.country: - rdn.append(RelativeDistinguishedName(( - AttributeTypeAndValue(( - ("type", AttributeType(id_at_countryName)), - ("value", AttributeValue(PrintableString(args.country))), - )), - ))) -subj = Name(("rdnSequence", RDNSequence(rdn))) -not_before = datetime.utcnow() -not_after = not_before + timedelta(days=365 * (10 if args.ca else 1)) -ai_sign = AlgorithmIdentifier(( - ("algorithm", (ai if ca_ai is None else ca_ai)["sign_algorithm"]), -)) -exts = [ - Extension(( - ("extnID", id_ce_subjectKeyIdentifier), - ("extnValue", OctetString( - SubjectKeyIdentifier(GOST34112012256(pub_raw).digest()[:20]).encode() - )), - )), - Extension(( - ("extnID", id_ce_keyUsage), - ("critical", Boolean(True)), - ("extnValue", OctetString(KeyUsage( - ("keyCertSign" if args.ca else "digitalSignature",), - ).encode())), - )), -] -if args.ca: - exts.append(Extension(( - ("extnID", id_ce_basicConstraints), - ("critical", Boolean(True)), - ("extnValue", OctetString(BasicConstraints(( - ("cA", Boolean(True)), - )).encode())), - ))) -else: - exts.append(Extension(( - ("extnID", id_ce_subjectAltName), - ("extnValue", OctetString( - SubjectAltName(( - GeneralName(("dNSName", IA5String(args.cn))), - )).encode() - )), - ))) -if ca_ai is not None: - caKeyId = [ - bytes(SubjectKeyIdentifier().decod(bytes(ext["extnValue"]))) - for ext in ca_cert["tbsCertificate"]["extensions"] - if ext["extnID"] == id_ce_subjectKeyIdentifier - ][0] - exts.append(Extension(( - ("extnID", id_ce_authorityKeyIdentifier), - ("extnValue", OctetString(AuthorityKeyIdentifier(( - ("keyIdentifier", KeyIdentifier(caKeyId)), - )).encode())), - ))) - -serial = ( - bytes2long(GOST34112012256(urandom(16)).digest()[:20]) - if args.serial is None else int(args.serial) -) -tbs = TBSCertificate(( - ("version", Version("v3")), - ("serialNumber", CertificateSerialNumber(serial)), - ("signature", ai_sign), - ("issuer", subj if ca_ai is None else ca_subj), - ("validity", Validity(( - ("notBefore", Time(("utcTime", UTCTime(not_before)))), - ("notAfter", Time(("utcTime", UTCTime(not_after)))), - ))), - ("subject", subj), - ("subjectPublicKeyInfo", SubjectPublicKeyInfo(( - ("algorithm", AlgorithmIdentifier(( - ("algorithm", ai["key_algorithm"]), - ("parameters", Any(key_params)), - ))), - ("subjectPublicKey", BitString(OctetString(pub_raw).encode())), - ))), - ("extensions", Extensions(exts)), -)) -cert = Certificate(( - ("tbsCertificate", tbs), - ("signatureAlgorithm", ai_sign), - ("signatureValue", BitString( - sign(curve, prv, ai["hasher"](tbs.encode()).digest()[::-1]) - if ca_ai is None else - sign(ca_ai["curve"], ca_prv, ca_ai["hasher"](tbs.encode()).digest()[::-1]) - )), -)) -out = stdout if args.out_cert is None else open(args.out_cert, "w") -print("-----BEGIN CERTIFICATE-----", file=out) -print(pem(cert), file=out) -print("-----END CERTIFICATE-----", file=out) diff --git a/pygost-5.13/pygost/asn1schemas/cms.py b/pygost-5.13/pygost/asn1schemas/cms.py deleted file mode 100644 index 8028d2b..0000000 --- a/pygost-5.13/pygost/asn1schemas/cms.py +++ /dev/null @@ -1,431 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""CMS related structures (**NOT COMPLETE**) -""" - -from pyderasn import Any -from pyderasn import BitString -from pyderasn import Choice -from pyderasn import Integer -from pyderasn import ObjectIdentifier -from pyderasn import OctetString -from pyderasn import Sequence -from pyderasn import SequenceOf -from pyderasn import SetOf -from pyderasn import tag_ctxc -from pyderasn import tag_ctxp - -from pygost.asn1schemas.oids import id_cms_mac_attr -from pygost.asn1schemas.oids import id_contentType -from pygost.asn1schemas.oids import id_digestedData -from pygost.asn1schemas.oids import id_encryptedData -from pygost.asn1schemas.oids import id_envelopedData -from pygost.asn1schemas.oids import id_Gost28147_89 -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm_omac -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_wrap_kexp15 -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm_omac -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_wrap_kexp15 -from pygost.asn1schemas.oids import id_messageDigest -from pygost.asn1schemas.oids import id_signedData -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import Certificate -from pygost.asn1schemas.x509 import CertificateSerialNumber -from pygost.asn1schemas.x509 import Name -from pygost.asn1schemas.x509 import SubjectPublicKeyInfo - - -class CMSVersion(Integer): - pass - - -class ContentType(ObjectIdentifier): - pass - - -class IssuerAndSerialNumber(Sequence): - schema = ( - ("issuer", Name()), - ("serialNumber", CertificateSerialNumber()), - ) - - -class KeyIdentifier(OctetString): - pass - - -class SubjectKeyIdentifier(KeyIdentifier): - pass - - -class RecipientIdentifier(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - ("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))), - ) - - -class Gost2814789Key(OctetString): - bounds = (32, 32) - - -class Gost2814789MAC(OctetString): - bounds = (4, 4) - - -class Gost2814789EncryptedKey(Sequence): - schema = ( - ("encryptedKey", Gost2814789Key()), - ("maskKey", Gost2814789Key(impl=tag_ctxp(0), optional=True)), - ("macKey", Gost2814789MAC()), - ) - - -class GostR34102001TransportParameters(Sequence): - schema = ( - ("encryptionParamSet", ObjectIdentifier()), - ("ephemeralPublicKey", SubjectPublicKeyInfo( - impl=tag_ctxc(0), - optional=True, - )), - ("ukm", OctetString()), - ) - - -class GostR3410KeyTransport(Sequence): - schema = ( - ("sessionEncryptedKey", Gost2814789EncryptedKey()), - ("transportParameters", GostR34102001TransportParameters( - impl=tag_ctxc(0), - optional=True, - )), - ) - - -class GostR3410KeyTransport2019(Sequence): - schema = ( - ("encryptedKey", OctetString()), - ("ephemeralPublicKey", SubjectPublicKeyInfo()), - ("ukm", OctetString()), - ) - - -class GostR341012KEGParameters(Sequence): - schema = ( - ("algorithm", ObjectIdentifier()), - ) - - -class KeyEncryptionAlgorithmIdentifier(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_gostr3412_2015_magma_wrap_kexp15: GostR341012KEGParameters(), - id_gostr3412_2015_kuznyechik_wrap_kexp15: GostR341012KEGParameters(), - }), - (("..", "encryptedKey"), { - id_tc26_gost3410_2012_256: GostR3410KeyTransport(), - id_tc26_gost3410_2012_512: GostR3410KeyTransport(), - id_gostr3412_2015_magma_wrap_kexp15: GostR3410KeyTransport2019(), - id_gostr3412_2015_kuznyechik_wrap_kexp15: GostR3410KeyTransport2019(), - }), - (("..", "recipientEncryptedKeys", any, "encryptedKey"), { - id_tc26_gost3410_2012_256: Gost2814789EncryptedKey(), - id_tc26_gost3410_2012_512: Gost2814789EncryptedKey(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class EncryptedKey(OctetString): - pass - - -class KeyTransRecipientInfo(Sequence): - schema = ( - ("version", CMSVersion()), - ("rid", RecipientIdentifier()), - ("keyEncryptionAlgorithm", KeyEncryptionAlgorithmIdentifier()), - ("encryptedKey", EncryptedKey()), - ) - - -class OriginatorPublicKey(Sequence): - schema = ( - ("algorithm", AlgorithmIdentifier()), - ("publicKey", BitString()), - ) - - -class OriginatorIdentifierOrKey(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - ("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))), - ("originatorKey", OriginatorPublicKey(impl=tag_ctxc(1))), - ) - - -class UserKeyingMaterial(OctetString): - pass - - -class KeyAgreeRecipientIdentifier(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - # ("rKeyId", RecipientKeyIdentifier(impl=tag_ctxc(0))), - ) - - -class RecipientEncryptedKey(Sequence): - schema = ( - ("rid", KeyAgreeRecipientIdentifier()), - ("encryptedKey", EncryptedKey()), - ) - - -class RecipientEncryptedKeys(SequenceOf): - schema = RecipientEncryptedKey() - - -class KeyAgreeRecipientInfo(Sequence): - schema = ( - ("version", CMSVersion(3)), - ("originator", OriginatorIdentifierOrKey(expl=tag_ctxc(0))), - ("ukm", UserKeyingMaterial(expl=tag_ctxc(1), optional=True)), - ("keyEncryptionAlgorithm", KeyEncryptionAlgorithmIdentifier()), - ("recipientEncryptedKeys", RecipientEncryptedKeys()), - ) - - -class RecipientInfo(Choice): - schema = ( - ("ktri", KeyTransRecipientInfo()), - ("kari", KeyAgreeRecipientInfo(impl=tag_ctxc(1))), - # ("kekri", KEKRecipientInfo(impl=tag_ctxc(2))), - # ("pwri", PasswordRecipientInfo(impl=tag_ctxc(3))), - # ("ori", OtherRecipientInfo(impl=tag_ctxc(4))), - ) - - -class RecipientInfos(SetOf): - schema = RecipientInfo() - bounds = (1, float("+inf")) - - -class Gost2814789IV(OctetString): - bounds = (8, 8) - - -class Gost2814789Parameters(Sequence): - schema = ( - ("iv", Gost2814789IV()), - ("encryptionParamSet", ObjectIdentifier()), - ) - - -class Gost341215EncryptionParameters(Sequence): - schema = ( - ("ukm", OctetString()), - ) - - -class ContentEncryptionAlgorithmIdentifier(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_Gost28147_89: Gost2814789Parameters(), - id_gostr3412_2015_magma_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_magma_ctracpkm_omac: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm_omac: Gost341215EncryptionParameters(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class EncryptedContent(OctetString): - pass - - -class EncryptedContentInfo(Sequence): - schema = ( - ("contentType", ContentType()), - ("contentEncryptionAlgorithm", ContentEncryptionAlgorithmIdentifier()), - ("encryptedContent", EncryptedContent(impl=tag_ctxp(0), optional=True)), - ) - - -class Digest(OctetString): - pass - - -class AttributeValue(Any): - pass - - -class AttributeValues(SetOf): - schema = AttributeValue() - - -class EncryptedMac(OctetString): - pass - - -class Attribute(Sequence): - schema = ( - ("attrType", ObjectIdentifier(defines=( - (("attrValues",), { - id_contentType: ObjectIdentifier(), - id_messageDigest: Digest(), - id_cms_mac_attr: EncryptedMac(), - },), - ))), - ("attrValues", AttributeValues()), - ) - - -class UnprotectedAttributes(SetOf): - schema = Attribute() - bounds = (1, float("+inf")) - - -class CertificateChoices(Choice): - schema = ( - ("certificate", Certificate()), - # ("extendedCertificate", OctetString(impl=tag_ctxp(0))), - # ("v1AttrCert", AttributeCertificateV1(impl=tag_ctxc(1))), # V1 is osbolete - # ("v2AttrCert", AttributeCertificateV2(impl=tag_ctxc(2))), - # ("other", OtherCertificateFormat(impl=tag_ctxc(3))), - ) - - -class CertificateSet(SetOf): - schema = CertificateChoices() - - -class OriginatorInfo(Sequence): - schema = ( - ("certs", CertificateSet(impl=tag_ctxc(0), optional=True)), - # ("crls", RevocationInfoChoices(impl=tag_ctxc(1), optional=True)), - ) - - -class EnvelopedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("originatorInfo", OriginatorInfo(impl=tag_ctxc(0), optional=True)), - ("recipientInfos", RecipientInfos()), - ("encryptedContentInfo", EncryptedContentInfo()), - ("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class EncapsulatedContentInfo(Sequence): - schema = ( - ("eContentType", ContentType()), - ("eContent", OctetString(expl=tag_ctxc(0), optional=True)), - ) - - -class SignerIdentifier(Choice): - schema = ( - ("issuerAndSerialNumber", IssuerAndSerialNumber()), - ("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))), - ) - - -class DigestAlgorithmIdentifiers(SetOf): - schema = AlgorithmIdentifier() - - -class DigestAlgorithmIdentifier(AlgorithmIdentifier): - pass - - -class SignatureAlgorithmIdentifier(AlgorithmIdentifier): - pass - - -class SignatureValue(OctetString): - pass - - -class SignedAttributes(SetOf): - schema = Attribute() - bounds = (1, float("+inf")) - - -class SignerInfo(Sequence): - schema = ( - ("version", CMSVersion()), - ("sid", SignerIdentifier()), - ("digestAlgorithm", DigestAlgorithmIdentifier()), - ("signedAttrs", SignedAttributes(impl=tag_ctxc(0), optional=True)), - ("signatureAlgorithm", SignatureAlgorithmIdentifier()), - ("signature", SignatureValue()), - # ("unsignedAttrs", UnsignedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class SignerInfos(SetOf): - schema = SignerInfo() - - -class SignedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("digestAlgorithms", DigestAlgorithmIdentifiers()), - ("encapContentInfo", EncapsulatedContentInfo()), - ("certificates", CertificateSet(impl=tag_ctxc(0), optional=True)), - # ("crls", RevocationInfoChoices(impl=tag_ctxc(1), optional=True)), - ("signerInfos", SignerInfos()), - ) - - -class DigestedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("digestAlgorithm", DigestAlgorithmIdentifier()), - ("encapContentInfo", EncapsulatedContentInfo()), - ("digest", Digest()), - ) - - -class EncryptedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("encryptedContentInfo", EncryptedContentInfo()), - ("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class ContentInfo(Sequence): - schema = ( - ("contentType", ContentType(defines=( - (("content",), { - id_digestedData: DigestedData(), - id_encryptedData: EncryptedData(), - id_envelopedData: EnvelopedData(), - id_signedData: SignedData(), - }), - ))), - ("content", Any(expl=tag_ctxc(0))), - ) diff --git a/pygost-5.13/pygost/asn1schemas/oids.py b/pygost-5.13/pygost/asn1schemas/oids.py deleted file mode 100644 index 4638900..0000000 --- a/pygost-5.13/pygost/asn1schemas/oids.py +++ /dev/null @@ -1,60 +0,0 @@ -from pyderasn import ObjectIdentifier - - -id_at_commonName = ObjectIdentifier("2.5.4.3") -id_at_countryName = ObjectIdentifier("2.5.4.6") -id_at_localityName = ObjectIdentifier("2.5.4.7") -id_at_stateOrProvinceName = ObjectIdentifier("2.5.4.8") -id_at_organizationName = ObjectIdentifier("2.5.4.10") - -id_pkcs7 = ObjectIdentifier("1.2.840.113549.1.7") -id_data = id_pkcs7 + (1,) -id_signedData = id_pkcs7 + (2,) -id_envelopedData = id_pkcs7 + (3,) -id_digestedData = id_pkcs7 + (5,) -id_encryptedData = id_pkcs7 + (6,) - -id_pkcs9 = ObjectIdentifier("1.2.840.113549.1.9") -id_contentType = id_pkcs9 + (3,) -id_messageDigest = id_pkcs9 + (4,) -id_pkcs9_certTypes_x509Certificate = ObjectIdentifier("1.2.840.113549.1.9.22.1") -id_pkcs12_bagtypes_keyBag = ObjectIdentifier("1.2.840.113549.1.12.10.1.1") -id_pkcs12_bagtypes_pkcs8ShroudedKeyBag = ObjectIdentifier("1.2.840.113549.1.12.10.1.2") -id_pkcs12_bagtypes_certBag = ObjectIdentifier("1.2.840.113549.1.12.10.1.3") - -id_Gost28147_89 = ObjectIdentifier("1.2.643.2.2.21") -id_GostR3410_2001_TestParamSet = ObjectIdentifier("1.2.643.2.2.35.0") -id_cms_mac_attr = ObjectIdentifier("1.2.643.7.1.0.6.1.1") -id_tc26_gost3410_2012_256 = ObjectIdentifier("1.2.643.7.1.1.1.1") -id_tc26_gost3410_2012_512 = ObjectIdentifier("1.2.643.7.1.1.1.2") -id_tc26_gost3411_2012_256 = ObjectIdentifier("1.2.643.7.1.1.2.2") -id_tc26_gost3411_2012_512 = ObjectIdentifier("1.2.643.7.1.1.2.3") -id_tc26_signwithdigest_gost3410_2012_256 = ObjectIdentifier("1.2.643.7.1.1.3.2") -id_tc26_signwithdigest_gost3410_2012_512 = ObjectIdentifier("1.2.643.7.1.1.3.3") -id_gostr3412_2015_magma_ctracpkm = ObjectIdentifier("1.2.643.7.1.1.5.1.1") -id_gostr3412_2015_magma_ctracpkm_omac = ObjectIdentifier("1.2.643.7.1.1.5.1.2") -id_gostr3412_2015_kuznyechik_ctracpkm = ObjectIdentifier("1.2.643.7.1.1.5.2.1") -id_gostr3412_2015_kuznyechik_ctracpkm_omac = ObjectIdentifier("1.2.643.7.1.1.5.2.2") -id_tc26_agreement_gost3410_2012_256 = ObjectIdentifier("1.2.643.7.1.1.6.1") -id_tc26_agreement_gost3410_2012_512 = ObjectIdentifier("1.2.643.7.1.1.6.2") -id_gostr3412_2015_magma_wrap_kexp15 = ObjectIdentifier("1.2.643.7.1.1.7.1.1") -id_gostr3412_2015_kuznyechik_wrap_kexp15 = ObjectIdentifier("1.2.643.7.1.1.7.2.1") -id_tc26_gost3410_2012_256_paramSetA = ObjectIdentifier("1.2.643.7.1.2.1.1.1") -id_tc26_gost3410_2012_256_paramSetB = ObjectIdentifier("1.2.643.7.1.2.1.1.2") -id_tc26_gost3410_2012_256_paramSetC = ObjectIdentifier("1.2.643.7.1.2.1.1.3") -id_tc26_gost3410_2012_256_paramSetD = ObjectIdentifier("1.2.643.7.1.2.1.1.4") -id_tc26_gost3410_2012_512_paramSetTest = ObjectIdentifier("1.2.643.7.1.2.1.2.0") -id_tc26_gost3410_2012_512_paramSetA = ObjectIdentifier("1.2.643.7.1.2.1.2.1") -id_tc26_gost3410_2012_512_paramSetB = ObjectIdentifier("1.2.643.7.1.2.1.2.2") -id_tc26_gost3410_2012_512_paramSetC = ObjectIdentifier("1.2.643.7.1.2.1.2.3") -id_tc26_gost_28147_param_Z = ObjectIdentifier("1.2.643.7.1.2.5.1.1") - -id_pbes2 = ObjectIdentifier("1.2.840.113549.1.5.13") -id_pbkdf2 = ObjectIdentifier("1.2.840.113549.1.5.12") - -id_at_commonName = ObjectIdentifier("2.5.4.3") -id_ce_basicConstraints = ObjectIdentifier("2.5.29.19") -id_ce_subjectKeyIdentifier = ObjectIdentifier("2.5.29.14") -id_ce_keyUsage = ObjectIdentifier("2.5.29.15") -id_ce_subjectAltName = ObjectIdentifier("2.5.29.17") -id_ce_authorityKeyIdentifier = ObjectIdentifier("2.5.29.35") diff --git a/pygost-5.13/pygost/asn1schemas/pfx.py b/pygost-5.13/pygost/asn1schemas/pfx.py deleted file mode 100644 index 27a87d0..0000000 --- a/pygost-5.13/pygost/asn1schemas/pfx.py +++ /dev/null @@ -1,250 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""PKCS #12 related structures (**NOT COMPLETE**) -""" - -from pyderasn import Any -from pyderasn import Choice -from pyderasn import Integer -from pyderasn import ObjectIdentifier -from pyderasn import OctetString -from pyderasn import Sequence -from pyderasn import SequenceOf -from pyderasn import SetOf -from pyderasn import tag_ctxc -from pyderasn import tag_ctxp - -from pygost.asn1schemas.cms import CMSVersion -from pygost.asn1schemas.cms import ContentType -from pygost.asn1schemas.cms import Gost2814789Parameters -from pygost.asn1schemas.cms import Gost341215EncryptionParameters -from pygost.asn1schemas.oids import id_data -from pygost.asn1schemas.oids import id_encryptedData -from pygost.asn1schemas.oids import id_Gost28147_89 -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm_omac -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm -from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm_omac -from pygost.asn1schemas.oids import id_pbes2 -from pygost.asn1schemas.oids import id_pbkdf2 -from pygost.asn1schemas.oids import id_pkcs9_certTypes_x509Certificate -from pygost.asn1schemas.prvkey import PrivateKeyInfo -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import Certificate - - -class PBKDF2Salt(Choice): - schema = ( - ("specified", OctetString()), - # ("otherSource", PBKDF2SaltSources()), - ) - - -id_hmacWithSHA1 = ObjectIdentifier("1.2.840.113549.2.7") - - -class PBKDF2PRFs(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(default=id_hmacWithSHA1)), - ("parameters", Any(optional=True)), - ) - - -class IterationCount(Integer): - bounds = (1, float("+inf")) - - -class KeyLength(Integer): - bounds = (1, float("+inf")) - - -class PBKDF2Params(Sequence): - schema = ( - ("salt", PBKDF2Salt()), - ("iterationCount", IterationCount(optional=True)), - ("keyLength", KeyLength(optional=True)), - ("prf", PBKDF2PRFs()), - ) - - -class PBES2KDFs(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), {id_pbkdf2: PBKDF2Params()}), - ))), - ("parameters", Any(optional=True)), - ) - - -class PBES2Encs(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_Gost28147_89: Gost2814789Parameters(), - id_gostr3412_2015_magma_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_magma_ctracpkm_omac: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm: Gost341215EncryptionParameters(), - id_gostr3412_2015_kuznyechik_ctracpkm_omac: Gost341215EncryptionParameters(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class PBES2Params(Sequence): - schema = ( - ("keyDerivationFunc", PBES2KDFs()), - ("encryptionScheme", PBES2Encs()), - ) - - -class EncryptionAlgorithmIdentifier(AlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), {id_pbes2: PBES2Params()}), - ))), - ("parameters", Any(optional=True)), - ) - - -class ContentEncryptionAlgorithmIdentifier(EncryptionAlgorithmIdentifier): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), {id_pbes2: PBES2Params()}), - ))), - ("parameters", Any(optional=True)), - ) - - -class EncryptedContent(OctetString): - pass - - -class EncryptedContentInfo(Sequence): - schema = ( - ("contentType", ContentType()), - ("contentEncryptionAlgorithm", ContentEncryptionAlgorithmIdentifier()), - ("encryptedContent", EncryptedContent(impl=tag_ctxp(0), optional=True)), - ) - - -class EncryptedData(Sequence): - schema = ( - ("version", CMSVersion()), - ("encryptedContentInfo", EncryptedContentInfo()), - # ("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)), - ) - - -class PKCS12BagSet(Any): - pass - - -class AttrValue(SetOf): - schema = Any() - - -class PKCS12Attribute(Sequence): - schema = ( - ("attrId", ObjectIdentifier()), - ("attrValue", AttrValue()), - ) - - -class PKCS12Attributes(SetOf): - schema = PKCS12Attribute() - - -class SafeBag(Sequence): - schema = ( - ("bagId", ObjectIdentifier(defines=( - (("bagValue",), {id_encryptedData: EncryptedData()}), - ))), - ("bagValue", PKCS12BagSet(expl=tag_ctxc(0))), - ("bagAttributes", PKCS12Attributes(optional=True)), - ) - - -class SafeContents(SequenceOf): - schema = SafeBag() - - -OctetStringSafeContents = SafeContents(expl=OctetString.tag_default) - - -class AuthSafe(Sequence): - schema = ( - ("contentType", ContentType(defines=( - (("content",), {id_data: OctetStringSafeContents()}), - ))), - ("content", Any(expl=tag_ctxc(0))), - ) - - -class DigestInfo(Sequence): - schema = ( - ("digestAlgorithm", AlgorithmIdentifier()), - ("digest", OctetString()), - ) - - -class MacData(Sequence): - schema = ( - ("mac", DigestInfo()), - ("macSalt", OctetString()), - ("iterations", Integer(default=1)), - ) - - -class PFX(Sequence): - schema = ( - ("version", Integer(default=1)), - ("authSafe", AuthSafe()), - ("macData", MacData(optional=True)), - ) - - -class EncryptedPrivateKeyInfo(Sequence): - schema = ( - ("encryptionAlgorithm", EncryptionAlgorithmIdentifier()), - ("encryptedData", OctetString()), - ) - - -class PKCS8ShroudedKeyBag(EncryptedPrivateKeyInfo): - pass - - -OctetStringX509Certificate = Certificate(expl=OctetString.tag_default) - - -class CertTypes(Any): - pass - - -class CertBag(Sequence): - schema = ( - ("certId", ObjectIdentifier(defines=( - (("certValue",), { - id_pkcs9_certTypes_x509Certificate: OctetStringX509Certificate(), - }), - ))), - ("certValue", CertTypes(expl=tag_ctxc(0))), - ) - - -class KeyBag(PrivateKeyInfo): - pass diff --git a/pygost-5.13/pygost/asn1schemas/pkcs10.py b/pygost-5.13/pygost/asn1schemas/pkcs10.py deleted file mode 100644 index dce45dd..0000000 --- a/pygost-5.13/pygost/asn1schemas/pkcs10.py +++ /dev/null @@ -1,49 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""PKCS #10 related structures (**NOT COMPLETE**) -""" - -from pyderasn import BitString -from pyderasn import Integer -from pyderasn import Sequence -from pyderasn import SetOf -from pyderasn import tag_ctxc - -from pygost.asn1schemas.cms import Attribute -from pygost.asn1schemas.x509 import AlgorithmIdentifier -from pygost.asn1schemas.x509 import Name -from pygost.asn1schemas.x509 import SubjectPublicKeyInfo - - -class Attributes(SetOf): - schema = Attribute() - - -class CertificationRequestInfo(Sequence): - schema = ( - ("version", Integer(0)), - ("subject", Name()), - ("subjectPKInfo", SubjectPublicKeyInfo()), - ("attributes", Attributes(impl=tag_ctxc(0))), - ) - - -class CertificationRequest(Sequence): - schema = ( - ("certificationRequestInfo", CertificationRequestInfo()), - ("signatureAlgorithm", AlgorithmIdentifier()), - ("signature", BitString()), - ) diff --git a/pygost-5.13/pygost/asn1schemas/prvkey.py b/pygost-5.13/pygost/asn1schemas/prvkey.py deleted file mode 100644 index 7da2533..0000000 --- a/pygost-5.13/pygost/asn1schemas/prvkey.py +++ /dev/null @@ -1,100 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from pyderasn import Any -from pyderasn import BitString -from pyderasn import Choice -from pyderasn import Integer -from pyderasn import Null -from pyderasn import ObjectIdentifier -from pyderasn import OctetString -from pyderasn import Sequence -from pyderasn import SetOf -from pyderasn import tag_ctxc -from pyderasn import tag_ctxp - -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 -from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 -from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters - - -class ECParameters(Choice): - schema = ( - ("namedCurve", ObjectIdentifier()), - ("implicitCurve", Null()), - # ("specifiedCurve", SpecifiedECDomain()), - ) - - -ecPrivkeyVer1 = Integer(1) - - -class ECPrivateKey(Sequence): - schema = ( - ("version", Integer(ecPrivkeyVer1)), - ("privateKey", OctetString()), - ("parameters", ECParameters(expl=tag_ctxc(0), optional=True)), - ("publicKey", BitString(expl=tag_ctxc(1), optional=True)), - ) - - -class PrivateKeyAlgorithmIdentifier(Sequence): - schema = ( - ("algorithm", ObjectIdentifier(defines=( - (("parameters",), { - id_tc26_gost3410_2012_256: GostR34102012PublicKeyParameters(), - id_tc26_gost3410_2012_512: GostR34102012PublicKeyParameters(), - }), - ))), - ("parameters", Any(optional=True)), - ) - - -class PrivateKey(OctetString): - pass - - -class AttributeValue(Any): - pass - - -class AttributeValues(SetOf): - schema = AttributeValue() - - -class Attribute(Sequence): - schema = ( - ("attrType", ObjectIdentifier()), - ("attrValues", AttributeValues()), - ) - - -class Attributes(SetOf): - schema = Attribute() - - -class PublicKey(BitString): - pass - - -class PrivateKeyInfo(Sequence): - schema = ( - ("version", Integer(0)), - ("privateKeyAlgorithm", PrivateKeyAlgorithmIdentifier()), - ("privateKey", PrivateKey()), - ("attributes", Attributes(impl=tag_ctxc(0), optional=True)), - ("publicKey", PublicKey(impl=tag_ctxp(1), optional=True)), - ) diff --git a/pygost-5.13/pygost/asn1schemas/x509.py b/pygost-5.13/pygost/asn1schemas/x509.py deleted file mode 100644 index 86ad7da..0000000 --- a/pygost-5.13/pygost/asn1schemas/x509.py +++ /dev/null @@ -1,262 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -""":rfc:`5280` related structures (**NOT COMPLETE**) - -They are taken from `PyDERASN -# -# 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, version 3 of the License. -# -# 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 . -"""GOST 28147-89 block cipher - -This is implementation of :rfc:`5830` ECB, CNT, CFB and :rfc:`4357` -CBC modes of operation. N1, N2, K names are taken according to -specification's terminology. CNT and CFB modes can work with arbitrary -data lengths. -""" - -from functools import partial - -from pygost.gost3413 import pad2 -from pygost.gost3413 import pad_size -from pygost.gost3413 import unpad2 -from pygost.utils import hexdec -from pygost.utils import strxor -from pygost.utils import xrange - - -KEYSIZE = 32 -BLOCKSIZE = 8 -C1 = 0x01010104 -C2 = 0x01010101 - -# Sequence of K_i S-box applying for encryption and decryption -SEQ_ENCRYPT = ( - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 7, 6, 5, 4, 3, 2, 1, 0, -) -SEQ_DECRYPT = ( - 0, 1, 2, 3, 4, 5, 6, 7, - 7, 6, 5, 4, 3, 2, 1, 0, - 7, 6, 5, 4, 3, 2, 1, 0, - 7, 6, 5, 4, 3, 2, 1, 0, -) - -# S-box parameters -DEFAULT_SBOX = "id-Gost28147-89-CryptoPro-A-ParamSet" -SBOXES = { - "id-Gost28147-89-TestParamSet": ( - (4, 2, 15, 5, 9, 1, 0, 8, 14, 3, 11, 12, 13, 7, 10, 6), - (12, 9, 15, 14, 8, 1, 3, 10, 2, 7, 4, 13, 6, 0, 11, 5), - (13, 8, 14, 12, 7, 3, 9, 10, 1, 5, 2, 4, 6, 15, 0, 11), - (14, 9, 11, 2, 5, 15, 7, 1, 0, 13, 12, 6, 10, 4, 3, 8), - (3, 14, 5, 9, 6, 8, 0, 13, 10, 11, 7, 12, 2, 1, 15, 4), - (8, 15, 6, 11, 1, 9, 12, 5, 13, 3, 7, 10, 0, 14, 2, 4), - (9, 11, 12, 0, 3, 6, 7, 5, 4, 8, 14, 15, 1, 10, 2, 13), - (12, 6, 5, 2, 11, 0, 9, 13, 3, 14, 7, 10, 15, 4, 1, 8), - ), - "id-Gost28147-89-CryptoPro-A-ParamSet": ( - (9, 6, 3, 2, 8, 11, 1, 7, 10, 4, 14, 15, 12, 0, 13, 5), - (3, 7, 14, 9, 8, 10, 15, 0, 5, 2, 6, 12, 11, 4, 13, 1), - (14, 4, 6, 2, 11, 3, 13, 8, 12, 15, 5, 10, 0, 7, 1, 9), - (14, 7, 10, 12, 13, 1, 3, 9, 0, 2, 11, 4, 15, 8, 5, 6), - (11, 5, 1, 9, 8, 13, 15, 0, 14, 4, 2, 3, 12, 7, 10, 6), - (3, 10, 13, 12, 1, 2, 0, 11, 7, 5, 9, 4, 8, 15, 14, 6), - (1, 13, 2, 9, 7, 10, 6, 0, 8, 12, 4, 5, 15, 3, 11, 14), - (11, 10, 15, 5, 0, 12, 14, 8, 6, 2, 3, 9, 1, 7, 13, 4), - ), - "id-Gost28147-89-CryptoPro-B-ParamSet": ( - (8, 4, 11, 1, 3, 5, 0, 9, 2, 14, 10, 12, 13, 6, 7, 15), - (0, 1, 2, 10, 4, 13, 5, 12, 9, 7, 3, 15, 11, 8, 6, 14), - (14, 12, 0, 10, 9, 2, 13, 11, 7, 5, 8, 15, 3, 6, 1, 4), - (7, 5, 0, 13, 11, 6, 1, 2, 3, 10, 12, 15, 4, 14, 9, 8), - (2, 7, 12, 15, 9, 5, 10, 11, 1, 4, 0, 13, 6, 8, 14, 3), - (8, 3, 2, 6, 4, 13, 14, 11, 12, 1, 7, 15, 10, 0, 9, 5), - (5, 2, 10, 11, 9, 1, 12, 3, 7, 4, 13, 0, 6, 15, 8, 14), - (0, 4, 11, 14, 8, 3, 7, 1, 10, 2, 9, 6, 15, 13, 5, 12), - ), - "id-Gost28147-89-CryptoPro-C-ParamSet": ( - (1, 11, 12, 2, 9, 13, 0, 15, 4, 5, 8, 14, 10, 7, 6, 3), - (0, 1, 7, 13, 11, 4, 5, 2, 8, 14, 15, 12, 9, 10, 6, 3), - (8, 2, 5, 0, 4, 9, 15, 10, 3, 7, 12, 13, 6, 14, 1, 11), - (3, 6, 0, 1, 5, 13, 10, 8, 11, 2, 9, 7, 14, 15, 12, 4), - (8, 13, 11, 0, 4, 5, 1, 2, 9, 3, 12, 14, 6, 15, 10, 7), - (12, 9, 11, 1, 8, 14, 2, 4, 7, 3, 6, 5, 10, 0, 15, 13), - (10, 9, 6, 8, 13, 14, 2, 0, 15, 3, 5, 11, 4, 1, 12, 7), - (7, 4, 0, 5, 10, 2, 15, 14, 12, 6, 1, 11, 13, 9, 3, 8), - ), - "id-Gost28147-89-CryptoPro-D-ParamSet": ( - (15, 12, 2, 10, 6, 4, 5, 0, 7, 9, 14, 13, 1, 11, 8, 3), - (11, 6, 3, 4, 12, 15, 14, 2, 7, 13, 8, 0, 5, 10, 9, 1), - (1, 12, 11, 0, 15, 14, 6, 5, 10, 13, 4, 8, 9, 3, 7, 2), - (1, 5, 14, 12, 10, 7, 0, 13, 6, 2, 11, 4, 9, 3, 15, 8), - (0, 12, 8, 9, 13, 2, 10, 11, 7, 3, 6, 5, 4, 14, 15, 1), - (8, 0, 15, 3, 2, 5, 14, 11, 1, 10, 4, 7, 12, 9, 13, 6), - (3, 0, 6, 15, 1, 14, 9, 2, 13, 8, 12, 4, 11, 10, 5, 7), - (1, 10, 6, 8, 15, 11, 0, 4, 12, 3, 5, 9, 7, 13, 2, 14), - ), - "id-tc26-gost-28147-param-Z": ( - (12, 4, 6, 2, 10, 5, 11, 9, 14, 8, 13, 7, 0, 3, 15, 1), - (6, 8, 2, 3, 9, 10, 5, 12, 1, 14, 4, 7, 11, 13, 0, 15), - (11, 3, 5, 8, 2, 15, 10, 13, 14, 1, 7, 4, 12, 9, 6, 0), - (12, 8, 2, 1, 13, 4, 15, 6, 7, 0, 10, 5, 3, 14, 9, 11), - (7, 15, 5, 10, 8, 1, 6, 13, 0, 9, 3, 14, 11, 4, 2, 12), - (5, 13, 15, 6, 9, 2, 12, 10, 11, 7, 8, 1, 4, 3, 14, 0), - (8, 14, 2, 5, 6, 9, 1, 12, 15, 4, 11, 0, 13, 10, 3, 7), - (1, 7, 14, 13, 0, 5, 8, 3, 4, 15, 10, 6, 9, 12, 11, 2), - ), - "id-GostR3411-94-TestParamSet": ( - (4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3), - (14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9), - (5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11), - (7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3), - (6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2), - (4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14), - (13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12), - (1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12), - ), - "id-GostR3411-94-CryptoProParamSet": ( - (10, 4, 5, 6, 8, 1, 3, 7, 13, 12, 14, 0, 9, 2, 11, 15), - (5, 15, 4, 0, 2, 13, 11, 9, 1, 7, 6, 3, 12, 14, 10, 8), - (7, 15, 12, 14, 9, 4, 1, 0, 3, 11, 5, 2, 6, 10, 8, 13), - (4, 10, 7, 12, 0, 15, 2, 8, 14, 1, 6, 5, 13, 11, 9, 3), - (7, 6, 4, 11, 9, 12, 2, 10, 1, 8, 0, 14, 15, 13, 3, 5), - (7, 6, 2, 4, 13, 9, 15, 0, 10, 1, 5, 11, 8, 14, 12, 3), - (13, 14, 4, 1, 7, 0, 5, 10, 3, 12, 8, 15, 6, 2, 9, 11), - (1, 3, 10, 9, 5, 11, 4, 15, 8, 6, 7, 14, 13, 0, 2, 12), - ), - "EACParamSet": ( - (11, 4, 8, 10, 9, 7, 0, 3, 1, 6, 2, 15, 14, 5, 12, 13), - (1, 7, 14, 9, 11, 3, 15, 12, 0, 5, 4, 6, 13, 10, 8, 2), - (7, 3, 1, 9, 2, 4, 13, 15, 8, 10, 12, 6, 5, 0, 11, 14), - (10, 5, 15, 7, 14, 11, 3, 9, 2, 8, 1, 12, 0, 4, 6, 13), - (0, 14, 6, 11, 9, 3, 8, 4, 12, 15, 10, 5, 13, 7, 1, 2), - (9, 2, 11, 12, 0, 4, 5, 6, 3, 15, 13, 8, 1, 7, 14, 10), - (4, 0, 14, 1, 5, 11, 8, 3, 12, 2, 9, 7, 6, 10, 13, 15), - (7, 14, 12, 13, 9, 4, 8, 15, 10, 2, 6, 0, 3, 11, 5, 1), - ), -} -SBOXES["AppliedCryptography"] = SBOXES["id-GostR3411-94-TestParamSet"] - - -def _K(s, _in): - """S-box substitution - - :param s: S-box - :param _in: 32-bit word - :returns: substituted 32-bit word - """ - return ( - (s[0][(_in >> 0) & 0x0F] << 0) + - (s[1][(_in >> 4) & 0x0F] << 4) + - (s[2][(_in >> 8) & 0x0F] << 8) + - (s[3][(_in >> 12) & 0x0F] << 12) + - (s[4][(_in >> 16) & 0x0F] << 16) + - (s[5][(_in >> 20) & 0x0F] << 20) + - (s[6][(_in >> 24) & 0x0F] << 24) + - (s[7][(_in >> 28) & 0x0F] << 28) - ) - - -def block2ns(data): - """Convert block to N1 and N2 integers - """ - data = bytearray(data) - return ( - data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24, - data[4] | data[5] << 8 | data[6] << 16 | data[7] << 24, - ) - - -def ns2block(ns): - """Convert N1 and N2 integers to 8-byte block - """ - n1, n2 = ns - return bytes(bytearray(( - (n2 >> 0) & 0xFF, (n2 >> 8) & 0xFF, (n2 >> 16) & 0xFF, (n2 >> 24) & 0xFF, - (n1 >> 0) & 0xFF, (n1 >> 8) & 0xFF, (n1 >> 16) & 0xFF, (n1 >> 24) & 0xFF, - ))) - - -def _shift11(x): - """11-bit cyclic shift - """ - return ((x << 11) & (2 ** 32 - 1)) | ((x >> (32 - 11)) & (2 ** 32 - 1)) - - -def validate_key(key): - if len(key) != KEYSIZE: - raise ValueError("Invalid key size") - - -def validate_iv(iv): - if len(iv) != BLOCKSIZE: - raise ValueError("Invalid IV size") - - -def validate_sbox(sbox): - if sbox not in SBOXES: - raise ValueError("Unknown sbox supplied") - - -def xcrypt(seq, sbox, key, ns): - """Perform full-round single-block operation - - :param seq: sequence of K_i S-box applying (either encrypt or decrypt) - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bytes key: 256-bit encryption key - :param ns: N1 and N2 integers - :type ns: (int, int) - :returns: resulting N1 and N2 - :rtype: (int, int) - """ - s = SBOXES[sbox] - w = bytearray(key) - x = [ - w[0 + i * 4] | - w[1 + i * 4] << 8 | - w[2 + i * 4] << 16 | - w[3 + i * 4] << 24 for i in range(8) - ] - n1, n2 = ns - for i in seq: - n1, n2 = _shift11(_K(s, (n1 + x[i]) % (2 ** 32))) ^ n2, n1 - return n1, n2 - - -def encrypt(sbox, key, ns): - """Encrypt single block - """ - return xcrypt(SEQ_ENCRYPT, sbox, key, ns) - - -def decrypt(sbox, key, ns): - """Decrypt single block - """ - return xcrypt(SEQ_DECRYPT, sbox, key, ns) - - -def ecb(key, data, action, sbox=DEFAULT_SBOX): - """ECB mode of operation - - :param bytes key: encryption key - :param data: plaintext - :type data: bytes, multiple of BLOCKSIZE - :param func action: "encrypt"/"decrypt" - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :returns: ciphertext - :rtype: bytes - """ - validate_key(key) - validate_sbox(sbox) - if not data or len(data) % BLOCKSIZE != 0: - raise ValueError("Data is not blocksize aligned") - result = [] - for i in xrange(0, len(data), BLOCKSIZE): - result.append(ns2block(action( - sbox, key, block2ns(data[i:i + BLOCKSIZE]) - ))) - return b"".join(result) - - -ecb_encrypt = partial(ecb, action=encrypt) -ecb_decrypt = partial(ecb, action=decrypt) - - -def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX, mesh=False): - """CBC encryption mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :type bool pad: perform ISO/IEC 7816-4 padding - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: ciphertext - :rtype: bytes - - 34.13-2015 padding method 2 is used. - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - if pad: - data = pad2(data, BLOCKSIZE) - if len(data) % BLOCKSIZE != 0: - raise ValueError("Data is not blocksize aligned") - ciphertext = [iv] - for i in xrange(0, len(data), BLOCKSIZE): - if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0: - key, _ = meshing(key, iv, sbox=sbox) - ciphertext.append(ns2block(encrypt(sbox, key, block2ns( - strxor(ciphertext[-1], data[i:i + BLOCKSIZE]) - )))) - return b"".join(ciphertext) - - -def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX, mesh=False): - """CBC decryption mode of operation - - :param bytes key: encryption key - :param bytes data: ciphertext - :type bool pad: perform ISO/IEC 7816-4 unpadding after decryption - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: plaintext - :rtype: bytes - """ - validate_key(key) - validate_sbox(sbox) - if not data or len(data) % BLOCKSIZE != 0: - raise ValueError("Data is not blocksize aligned") - if len(data) < 2 * BLOCKSIZE: - raise ValueError("There is no either data, or IV in ciphertext") - iv = data[:BLOCKSIZE] - plaintext = [] - for i in xrange(BLOCKSIZE, len(data), BLOCKSIZE): - if ( - mesh and - (i - BLOCKSIZE) >= MESH_MAX_DATA and - (i - BLOCKSIZE) % MESH_MAX_DATA == 0 - ): - key, _ = meshing(key, iv, sbox=sbox) - plaintext.append(strxor( - ns2block(decrypt(sbox, key, block2ns(data[i:i + BLOCKSIZE]))), - data[i - BLOCKSIZE:i], - )) - if pad: - plaintext[-1] = unpad2(plaintext[-1], BLOCKSIZE) - return b"".join(plaintext) - - -def cnt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX): - """Counter mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :returns: ciphertext - :rtype: bytes - - For decryption you use the same function again. - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - n2, n1 = encrypt(sbox, key, block2ns(iv)) - gamma = [] - for _ in xrange(0, len(data) + pad_size(len(data), BLOCKSIZE), BLOCKSIZE): - n1 = (n1 + C2) % (2 ** 32) - n2 = (n2 + C1) % (2 ** 32 - 1) - gamma.append(ns2block(encrypt(sbox, key, (n1, n2)))) - return strxor(b"".join(gamma), data) - - -MESH_CONST = hexdec("6900722264C904238D3ADB9646E92AC418FEAC9400ED0712C086DCC2EF4CA92B") -MESH_MAX_DATA = 1024 - - -def meshing(key, iv, sbox=DEFAULT_SBOX): - """:rfc:`4357` key meshing - """ - key = ecb_decrypt(key, MESH_CONST, sbox=sbox) - iv = ecb_encrypt(key, iv, sbox=sbox) - return key, iv - - -def cfb_encrypt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX, mesh=False): - """CFB encryption mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: ciphertext - :rtype: bytes - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - ciphertext = [iv] - for i in xrange(0, len(data) + pad_size(len(data), BLOCKSIZE), BLOCKSIZE): - if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0: - key, iv = meshing(key, ciphertext[-1], sbox=sbox) - ciphertext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(iv))), - )) - continue - ciphertext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(ciphertext[-1]))), - )) - return b"".join(ciphertext[1:]) - - -def cfb_decrypt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX, mesh=False): - """CFB decryption mode of operation - - :param bytes key: encryption key - :param bytes data: plaintext - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - :param bool mesh: enable key meshing - :returns: ciphertext - :rtype: bytes - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - if not data: - raise ValueError("No data supplied") - plaintext = [] - data = iv + data - for i in xrange(BLOCKSIZE, len(data) + pad_size(len(data), BLOCKSIZE), BLOCKSIZE): - if ( - mesh and - (i - BLOCKSIZE) >= MESH_MAX_DATA and - (i - BLOCKSIZE) % MESH_MAX_DATA == 0 - ): - key, iv = meshing(key, data[i - BLOCKSIZE:i], sbox=sbox) - plaintext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(iv))), - )) - continue - plaintext.append(strxor( - data[i:i + BLOCKSIZE], - ns2block(encrypt(sbox, key, block2ns(data[i - BLOCKSIZE:i]))), - )) - return b"".join(plaintext) diff --git a/pygost-5.13/pygost/gost28147_mac.py b/pygost-5.13/pygost/gost28147_mac.py deleted file mode 100644 index aab2805..0000000 --- a/pygost-5.13/pygost/gost28147_mac.py +++ /dev/null @@ -1,99 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST 28147-89 MAC -""" - -from copy import copy - -from pygost.gost28147 import block2ns -from pygost.gost28147 import BLOCKSIZE -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost28147 import ns2block -from pygost.gost28147 import validate_iv -from pygost.gost28147 import validate_key -from pygost.gost28147 import validate_sbox -from pygost.gost28147 import xcrypt -from pygost.gost3413 import pad1 -from pygost.iface import PEP247 -from pygost.utils import strxor -from pygost.utils import xrange - -digest_size = 8 -SEQ_MAC = ( - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, -) - - -class MAC(PEP247): - """GOST 28147-89 MAC mode of operation - - >>> m = MAC(key=key) - >>> m.update("some data") - >>> m.update("another data") - >>> m.hexdigest()[:8] - 'a687a08b' - """ - digest_size = digest_size - - def __init__(self, key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX): - """ - :param key: authentication key - :type key: bytes, 32 bytes - :param iv: initialization vector - :type iv: bytes, BLOCKSIZE length - :param sbox: S-box parameters to use - :type sbox: str, SBOXES'es key - """ - validate_key(key) - validate_iv(iv) - validate_sbox(sbox) - self.key = key - self.data = data - self.iv = iv - self.sbox = sbox - - def copy(self): - return MAC(self.key, copy(self.data), self.iv, self.sbox) - - def update(self, data): - """Append data that has to be authenticated - """ - self.data += data - - def digest(self): - """Get MAC tag of supplied data - - You have to provide at least single byte of data. - If you want to produce tag length of 3 bytes, then - ``digest()[:3]``. - """ - if not self.data: - raise ValueError("No data processed") - data = pad1(self.data, BLOCKSIZE) - prev = block2ns(self.iv)[::-1] - for i in xrange(0, len(data), BLOCKSIZE): - prev = xcrypt( - SEQ_MAC, self.sbox, self.key, block2ns(strxor( - data[i:i + BLOCKSIZE], - ns2block(prev), - )), - )[::-1] - return ns2block(prev) - - -def new(key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX): - return MAC(key, data, iv, sbox) diff --git a/pygost-5.13/pygost/gost3410.py b/pygost-5.13/pygost/gost3410.py deleted file mode 100644 index c12b170..0000000 --- a/pygost-5.13/pygost/gost3410.py +++ /dev/null @@ -1,412 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.10 public-key signature function. - -This is implementation of GOST R 34.10-2001 (:rfc:`5832`), GOST R -34.10-2012 (:rfc:`7091`). The difference between 2001 and 2012 is the -key, digest and signature lengths. -""" - -from os import urandom - -from pygost.utils import bytes2long -from pygost.utils import hexdec -from pygost.utils import long2bytes -from pygost.utils import modinvert - - -def point_size(point): - """Determine is it either 256 or 512 bit point - """ - return (512 // 8) if point.bit_length() > 256 else (256 // 8) - - -class GOST3410Curve(object): - """GOST 34.10 validated curve - - >>> curve = CURVES["id-GostR3410-2001-TestParamSet"] - >>> prv = prv_unmarshal(urandom(32)) - >>> signature = sign(curve, prv, GOST341194(data).digest()) - >>> pub = public_key(curve, prv) - >>> verify(curve, pub, GOST341194(data).digest(), signature) - True - - :param long p: characteristic of the underlying prime field - :param long q: elliptic curve subgroup order - :param long a, b: coefficients of the equation of the elliptic curve in - the canonical form - :param long x, y: the coordinate of the point P (generator of the - subgroup of order q) of the elliptic curve in - the canonical form - :param long e, d: coefficients of the equation of the elliptic curve in - the twisted Edwards form - :param str name: human-readable curve name - """ - - def __init__(self, p, q, a, b, x, y, cofactor=1, e=None, d=None, name=None): - self.p = p - self.q = q - self.a = a - self.b = b - self.x = x - self.y = y - self.cofactor = cofactor - self.e = e - self.d = d - if not self.contains((x, y)): - raise ValueError("Invalid parameters") - self._st = None - self.name = name - - @property - def point_size(self): - return point_size(self.p) - - def __repr__(self): - return "<%s: %s>" % (self.__class__.__name__, self.name) - - def pos(self, v): - """Make positive number - """ - if v < 0: - return v + self.p - return v - - def contains(self, point): - """Is point on the curve? - - :type point: (long, long) - """ - x, y = point - r1 = y * y % self.p - r2 = ((x * x + self.a) * x + self.b) % self.p - return r1 == self.pos(r2) - - def _add(self, p1x, p1y, p2x, p2y): - if p1x == p2x and p1y == p2y: - # double - t = ((3 * p1x * p1x + self.a) * modinvert(2 * p1y, self.p)) % self.p - else: - tx = self.pos(p2x - p1x) % self.p - ty = self.pos(p2y - p1y) % self.p - t = (ty * modinvert(tx, self.p)) % self.p - tx = self.pos(t * t - p1x - p2x) % self.p - ty = self.pos(t * (p1x - tx) - p1y) % self.p - return tx, ty - - def exp(self, degree, x=None, y=None): - x = x or self.x - y = y or self.y - tx = x - ty = y - if degree == 0: - raise ValueError("Bad degree value") - degree -= 1 - while degree != 0: - if degree & 1 == 1: - tx, ty = self._add(tx, ty, x, y) - degree = degree >> 1 - x, y = self._add(x, y, x, y) - return tx, ty - - def st(self): - """Compute s/t parameters for twisted Edwards curve points conversion - """ - if self.e is None or self.d is None: - raise ValueError("Non twisted Edwards curve") - if self._st is not None: - return self._st - self._st = ( - self.pos(self.e - self.d) * modinvert(4, self.p) % self.p, - (self.e + self.d) * modinvert(6, self.p) % self.p, - ) - return self._st - - -CURVES = { - "GostR3410_2001_ParamSet_cc": GOST3410Curve( - p=bytes2long(hexdec("C0000000000000000000000000000000000000000000000000000000000003C7")), - q=bytes2long(hexdec("5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85")), - a=bytes2long(hexdec("C0000000000000000000000000000000000000000000000000000000000003c4")), - b=bytes2long(hexdec("2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000002")), - y=bytes2long(hexdec("a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c")), - ), - "id-GostR3410-2001-TestParamSet": GOST3410Curve( - p=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000431")), - q=bytes2long(hexdec("8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3")), - a=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000007")), - b=bytes2long(hexdec("5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000002")), - y=bytes2long(hexdec("08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8")), - ), - "id-tc26-gost-3410-12-256-paramSetA": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97")), - q=bytes2long(hexdec("400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67")), - a=bytes2long(hexdec("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335")), - b=bytes2long(hexdec("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513")), - x=bytes2long(hexdec("91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28")), - y=bytes2long(hexdec("32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C")), - cofactor=4, - e=0x01, - d=bytes2long(hexdec("0605F6B7C183FA81578BC39CFAD518132B9DF62897009AF7E522C32D6DC7BFFB")), - ), - "id-tc26-gost-3410-12-256-paramSetB": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97")), - q=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893")), - a=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94")), - b=bytes2long(hexdec("00000000000000000000000000000000000000000000000000000000000000a6")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000001")), - y=bytes2long(hexdec("8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14")), - ), - "id-tc26-gost-3410-12-256-paramSetC": GOST3410Curve( - p=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000C99")), - q=bytes2long(hexdec("800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F")), - a=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000C96")), - b=bytes2long(hexdec("3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000001")), - y=bytes2long(hexdec("3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC")), - ), - "id-tc26-gost-3410-12-256-paramSetD": GOST3410Curve( - p=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B")), - q=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9")), - a=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598")), - b=bytes2long(hexdec("000000000000000000000000000000000000000000000000000000000000805a")), - x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000000")), - y=bytes2long(hexdec("41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67")), - ), - "id-tc26-gost-3410-12-512-paramSetTest": GOST3410Curve( - p=bytes2long(hexdec("4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DF1D852741AF4704A0458047E80E4546D35B8336FAC224DD81664BBF528BE6373")), - q=bytes2long(hexdec("4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DA82F2D7ECB1DBAC719905C5EECC423F1D86E25EDBE23C595D644AAF187E6E6DF")), - a=7, - b=bytes2long(hexdec("1CFF0806A31116DA29D8CFA54E57EB748BC5F377E49400FDD788B649ECA1AC4361834013B2AD7322480A89CA58E0CF74BC9E540C2ADD6897FAD0A3084F302ADC")), - x=bytes2long(hexdec("24D19CC64572EE30F396BF6EBBFD7A6C5213B3B3D7057CC825F91093A68CD762FD60611262CD838DC6B60AA7EEE804E28BC849977FAC33B4B530F1B120248A9A")), - y=bytes2long(hexdec("2BB312A43BD2CE6E0D020613C857ACDDCFBF061E91E5F2C3F32447C259F39B2C83AB156D77F1496BF7EB3351E1EE4E43DC1A18B91B24640B6DBB92CB1ADD371E")), - ), - "id-tc26-gost-3410-12-512-paramSetA": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7")), - q=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275")), - a=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4")), - b=bytes2long(hexdec("E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760")), - x=bytes2long(hexdec("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003")), - y=bytes2long(hexdec("7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4")), - ), - "id-tc26-gost-3410-12-512-paramSetB": GOST3410Curve( - p=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F")), - q=bytes2long(hexdec("800000000000000000000000000000000000000000000000000000000000000149A1EC142565A545ACFDB77BD9D40CFA8B996712101BEA0EC6346C54374F25BD")), - a=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C")), - b=bytes2long(hexdec("687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116")), - x=bytes2long(hexdec("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002")), - y=bytes2long(hexdec("1A8F7EDA389B094C2C071E3647A8940F3C123B697578C213BE6DD9E6C8EC7335DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD")), - ), - "id-tc26-gost-3410-12-512-paramSetC": GOST3410Curve( - p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7")), - q=bytes2long(hexdec("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC98CDBA46506AB004C33A9FF5147502CC8EDA9E7A769A12694623CEF47F023ED")), - a=bytes2long(hexdec("DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3")), - b=bytes2long(hexdec("B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1")), - x=bytes2long(hexdec("E2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043AA27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148")), - y=bytes2long(hexdec("F5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9BE18E2D33E3021ED2EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F")), - cofactor=4, - e=0x01, - d=bytes2long(hexdec("9E4F5D8C017D8D9F13A5CF3CDF5BFE4DAB402D54198E31EBDE28A0621050439CA6B39E0A515C06B304E2CE43E79E369E91A0CFC2BC2A22B4CA302DBB33EE7550")), - ), -} -CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetB"] -CURVES["id-GostR3410-2001-CryptoPro-B-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetC"] -CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetD"] -CURVES["id-GostR3410-2001-CryptoPro-XchA-ParamSet"] = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] -CURVES["id-GostR3410-2001-CryptoPro-XchB-ParamSet"] = CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"] -CURVES["id-tc26-gost-3410-2012-256-paramSetA"] = CURVES["id-tc26-gost-3410-12-256-paramSetA"] -CURVES["id-tc26-gost-3410-2012-256-paramSetB"] = CURVES["id-tc26-gost-3410-12-256-paramSetB"] -CURVES["id-tc26-gost-3410-2012-256-paramSetC"] = CURVES["id-tc26-gost-3410-12-256-paramSetC"] -CURVES["id-tc26-gost-3410-2012-256-paramSetD"] = CURVES["id-tc26-gost-3410-12-256-paramSetD"] -CURVES["id-tc26-gost-3410-2012-512-paramSetTest"] = CURVES["id-tc26-gost-3410-12-512-paramSetTest"] -CURVES["id-tc26-gost-3410-2012-512-paramSetA"] = CURVES["id-tc26-gost-3410-12-512-paramSetA"] -CURVES["id-tc26-gost-3410-2012-512-paramSetB"] = CURVES["id-tc26-gost-3410-12-512-paramSetB"] -CURVES["id-tc26-gost-3410-2012-512-paramSetC"] = CURVES["id-tc26-gost-3410-12-512-paramSetC"] -for _name, _curve in CURVES.items(): - _curve.name = _name -DEFAULT_CURVE = CURVES["id-tc26-gost-3410-12-256-paramSetB"] - - -def public_key(curve, prv, mask=None): - """Generate public key from the private one - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :returns: public key's parts, X and Y - :rtype: (long, long) - """ - pub = curve.exp(prv) - if mask is not None: - pub = curve.exp(mask, pub[0], pub[1]) - return pub - - -def sign(curve, prv, digest, rand=None, mask=None): - """Calculate signature for provided digest - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param digest: digest for signing - :type digest: bytes, 32 or 64 bytes - :param rand: optional predefined random data used for k/r generation - :type rand: bytes, 32 or 64 bytes - :returns: signature, BE(S) || BE(R) - :rtype: bytes, 64 or 128 bytes - """ - size = curve.point_size - q = curve.q - e = bytes2long(digest) % q - if e == 0: - e = 1 - while True: - if rand is None: - rand = urandom(size) - elif len(rand) != size: - raise ValueError("rand length != %d" % size) - k = bytes2long(rand) % q - if k == 0: - continue - r, y = curve.exp(k) - if mask is not None: - r, y = curve.exp(mask, x=r, y=y) - r %= q - if r == 0: - continue - d = prv * r - k *= e - s = d + k - if mask is not None: - s *= mask - s %= q - if s == 0: - continue - break - return long2bytes(s, size) + long2bytes(r, size) - - -def verify(curve, pub, digest, signature): - """Verify provided digest with the signature - - :param GOST3410Curve curve: curve to use - :type pub: (long, long) - :param digest: digest needed to check - :type digest: bytes, 32 or 64 bytes - :param signature: signature to verify with - :type signature: bytes, 64 or 128 bytes - :rtype: bool - """ - size = curve.point_size - if len(signature) != size * 2: - raise ValueError("Invalid signature length") - q = curve.q - p = curve.p - s = bytes2long(signature[:size]) - r = bytes2long(signature[size:]) - if r <= 0 or r >= q or s <= 0 or s >= q: - return False - e = bytes2long(digest) % curve.q - if e == 0: - e = 1 - v = modinvert(e, q) - z1 = s * v % q - z2 = q - r * v % q - p1x, p1y = curve.exp(z1) - q1x, q1y = curve.exp(z2, pub[0], pub[1]) - lm = q1x - p1x - if lm < 0: - lm += p - lm = modinvert(lm, p) - z1 = q1y - p1y - lm = lm * z1 % p - lm = lm * lm % p - lm = lm - p1x - q1x - lm = lm % p - if lm < 0: - lm += p - lm %= q - # This is not constant time comparison! - return lm == r - - -def prv_unmarshal(prv): - """Unmarshal little-endian private key - - :param bytes prv: serialized private key - :rtype: long - - It is advisable to use :py:func:`pygost.gost3410.prv_marshal` to - assure that key i in curve's Q field for better compatibility with - some implementations. - """ - return bytes2long(prv[::-1]) - - -def prv_marshal(curve, prv): - """Marshal little-endian private key - - :param GOST3410Curve curve: curve to use - :param long prv: serialized private key - :rtype: bytes - - Key is in curve's Q field. - """ - return long2bytes(prv % curve.q, point_size(prv))[::-1] - - -def pub_marshal(pub): - """Marshal public key - - :type pub: (long, long) - :rtype: bytes - :returns: LE(X) || LE(Y) - """ - size = point_size(pub[0]) - return (long2bytes(pub[1], size) + long2bytes(pub[0], size))[::-1] - - -def pub_unmarshal(pub): - """Unmarshal public key - - :param pub: LE(X) || LE(Y) - :type pub: bytes - :rtype: (long, long) - """ - size = len(pub) // 2 - pub = pub[::-1] - return (bytes2long(pub[size:]), bytes2long(pub[:size])) - - -def uv2xy(curve, u, v): - """Convert twisted Edwards curve U,V coordinates to Weierstrass X,Y - """ - s, t = curve.st() - k1 = (s * (1 + v)) % curve.p - k2 = curve.pos(1 - v) - x = t + k1 * modinvert(k2, curve.p) - y = k1 * modinvert(u * k2, curve.p) - return x % curve.p, y % curve.p - - -def xy2uv(curve, x, y): - """Convert Weierstrass X,Y coordinates to twisted Edwards curve U,V - """ - s, t = curve.st() - xmt = curve.pos(x - t) - u = xmt * modinvert(y, curve.p) - v = curve.pos(xmt - s) * modinvert(xmt + s, curve.p) - return u % curve.p, v % curve.p diff --git a/pygost-5.13/pygost/gost3410_vko.py b/pygost-5.13/pygost/gost3410_vko.py deleted file mode 100644 index 3f169dc..0000000 --- a/pygost-5.13/pygost/gost3410_vko.py +++ /dev/null @@ -1,97 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Key agreement functions, VKO GOST R 34.10-2001/2012 -""" - -from pygost.gost3410 import pub_marshal -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost341194 import GOST341194 -from pygost.utils import bytes2long - - -def ukm_unmarshal(ukm): - """Unmarshal UKM value - - :type ukm: little-endian bytes - :rtype: long - """ - return bytes2long(ukm[::-1]) - - -def kek(curve, prv, pub, ukm, mask=None): - if not curve.contains(pub): - raise ValueError("pub is not on the curve") - key = curve.exp(prv, pub[0], pub[1]) - key = curve.exp(curve.cofactor * ukm, key[0], key[1]) - if mask is not None: - key = curve.exp(mask, key[0], key[1]) - return pub_marshal(key) - - -def kek_34102001(curve, prv, pub, ukm): - """Key agreement (34.10-2001, 34.11-94) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param long ukm: user keying material, VKO-factor - :returns: Key Encryption Key (shared key) - :rtype: bytes, 32 bytes - - Shared Key Encryption Key computation is based on - :rfc:`4357` VKO GOST R 34.10-2001 with little-endian - hash output. - """ - return GOST341194( - kek(curve, prv, pub, ukm), - sbox="id-GostR3411-94-CryptoProParamSet", - ).digest() - - -def kek_34102012256(curve, prv, pub, ukm=1): - """Key agreement (34.10-2012, 34.11-2012 256 bit) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param long ukm: user keying material, VKO-factor - :returns: Key Encryption Key (shared key) - :rtype: bytes, 32 bytes - - Shared Key Encryption Key computation is based on - :rfc:`7836` VKO GOST R 34.10-2012. - """ - return GOST34112012256(kek(curve, prv, pub, ukm)).digest() - - -def kek_34102012512(curve, prv, pub, ukm=1): - """Key agreement (34.10-2012, 34.11-2012 512 bit) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param long ukm: user keying material, VKO-factor - :returns: Key Encryption Key (shared key) - :rtype: bytes, 32 bytes - - Shared Key Encryption Key computation is based on - :rfc:`7836` VKO GOST R 34.10-2012. - """ - return GOST34112012512(kek(curve, prv, pub, ukm)).digest() diff --git a/pygost-5.13/pygost/gost34112012.py b/pygost-5.13/pygost/gost34112012.py deleted file mode 100644 index 91782de..0000000 --- a/pygost-5.13/pygost/gost34112012.py +++ /dev/null @@ -1,299 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.11-2012 (Streebog) hash function common files - -This is implementation of :rfc:`6986`. Most function and variable names are -taken according to specification's terminology. -""" - -from copy import copy -from struct import pack -from struct import unpack - -from pygost.iface import PEP247 -from pygost.utils import hexdec -from pygost.utils import strxor -from pygost.utils import xrange - - -BLOCKSIZE = 64 -Pi = bytearray(( - 252, 238, 221, 17, 207, 110, 49, 22, 251, 196, 250, - 218, 35, 197, 4, 77, 233, 119, 240, 219, 147, 46, - 153, 186, 23, 54, 241, 187, 20, 205, 95, 193, 249, - 24, 101, 90, 226, 92, 239, 33, 129, 28, 60, 66, - 139, 1, 142, 79, 5, 132, 2, 174, 227, 106, 143, - 160, 6, 11, 237, 152, 127, 212, 211, 31, 235, 52, - 44, 81, 234, 200, 72, 171, 242, 42, 104, 162, 253, - 58, 206, 204, 181, 112, 14, 86, 8, 12, 118, 18, - 191, 114, 19, 71, 156, 183, 93, 135, 21, 161, 150, - 41, 16, 123, 154, 199, 243, 145, 120, 111, 157, 158, - 178, 177, 50, 117, 25, 61, 255, 53, 138, 126, 109, - 84, 198, 128, 195, 189, 13, 87, 223, 245, 36, 169, - 62, 168, 67, 201, 215, 121, 214, 246, 124, 34, 185, - 3, 224, 15, 236, 222, 122, 148, 176, 188, 220, 232, - 40, 80, 78, 51, 10, 74, 167, 151, 96, 115, 30, - 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65, - 173, 69, 70, 146, 39, 94, 85, 47, 140, 163, 165, - 125, 105, 213, 149, 59, 7, 88, 179, 64, 134, 172, - 29, 247, 48, 55, 107, 228, 136, 217, 231, 137, 225, - 27, 131, 73, 76, 63, 248, 254, 141, 83, 170, 144, - 202, 216, 133, 97, 32, 113, 103, 164, 45, 43, 9, - 91, 203, 155, 37, 208, 190, 229, 108, 82, 89, 166, - 116, 210, 230, 244, 180, 192, 209, 102, 175, 194, 57, - 75, 99, 182, -)) - -A = [unpack(">Q", hexdec(s))[0] for s in ( - "8e20faa72ba0b470", "47107ddd9b505a38", "ad08b0e0c3282d1c", "d8045870ef14980e", - "6c022c38f90a4c07", "3601161cf205268d", "1b8e0b0e798c13c8", "83478b07b2468764", - "a011d380818e8f40", "5086e740ce47c920", "2843fd2067adea10", "14aff010bdd87508", - "0ad97808d06cb404", "05e23c0468365a02", "8c711e02341b2d01", "46b60f011a83988e", - "90dab52a387ae76f", "486dd4151c3dfdb9", "24b86a840e90f0d2", "125c354207487869", - "092e94218d243cba", "8a174a9ec8121e5d", "4585254f64090fa0", "accc9ca9328a8950", - "9d4df05d5f661451", "c0a878a0a1330aa6", "60543c50de970553", "302a1e286fc58ca7", - "18150f14b9ec46dd", "0c84890ad27623e0", "0642ca05693b9f70", "0321658cba93c138", - "86275df09ce8aaa8", "439da0784e745554", "afc0503c273aa42a", "d960281e9d1d5215", - "e230140fc0802984", "71180a8960409a42", "b60c05ca30204d21", "5b068c651810a89e", - "456c34887a3805b9", "ac361a443d1c8cd2", "561b0d22900e4669", "2b838811480723ba", - "9bcf4486248d9f5d", "c3e9224312c8c1a0", "effa11af0964ee50", "f97d86d98a327728", - "e4fa2054a80b329c", "727d102a548b194e", "39b008152acb8227", "9258048415eb419d", - "492c024284fbaec0", "aa16012142f35760", "550b8e9e21f7a530", "a48b474f9ef5dc18", - "70a6a56e2440598e", "3853dc371220a247", "1ca76e95091051ad", "0edd37c48a08a6d8", - "07e095624504536c", "8d70c431ac02a736", "c83862965601dd1b", "641c314b2b8ee083", -)] - -Tau = ( - 0, 8, 16, 24, 32, 40, 48, 56, - 1, 9, 17, 25, 33, 41, 49, 57, - 2, 10, 18, 26, 34, 42, 50, 58, - 3, 11, 19, 27, 35, 43, 51, 59, - 4, 12, 20, 28, 36, 44, 52, 60, - 5, 13, 21, 29, 37, 45, 53, 61, - 6, 14, 22, 30, 38, 46, 54, 62, - 7, 15, 23, 31, 39, 47, 55, 63, -) - -C = [hexdec("".join(s))[::-1] for s in ( - ( - "b1085bda1ecadae9ebcb2f81c0657c1f", - "2f6a76432e45d016714eb88d7585c4fc", - "4b7ce09192676901a2422a08a460d315", - "05767436cc744d23dd806559f2a64507", - ), - ( - "6fa3b58aa99d2f1a4fe39d460f70b5d7", - "f3feea720a232b9861d55e0f16b50131", - "9ab5176b12d699585cb561c2db0aa7ca", - "55dda21bd7cbcd56e679047021b19bb7", - ), - ( - "f574dcac2bce2fc70a39fc286a3d8435", - "06f15e5f529c1f8bf2ea7514b1297b7b", - "d3e20fe490359eb1c1c93a376062db09", - "c2b6f443867adb31991e96f50aba0ab2", - ), - ( - "ef1fdfb3e81566d2f948e1a05d71e4dd", - "488e857e335c3c7d9d721cad685e353f", - "a9d72c82ed03d675d8b71333935203be", - "3453eaa193e837f1220cbebc84e3d12e", - ), - ( - "4bea6bacad4747999a3f410c6ca92363", - "7f151c1f1686104a359e35d7800fffbd", - "bfcd1747253af5a3dfff00b723271a16", - "7a56a27ea9ea63f5601758fd7c6cfe57", - ), - ( - "ae4faeae1d3ad3d96fa4c33b7a3039c0", - "2d66c4f95142a46c187f9ab49af08ec6", - "cffaa6b71c9ab7b40af21f66c2bec6b6", - "bf71c57236904f35fa68407a46647d6e", - ), - ( - "f4c70e16eeaac5ec51ac86febf240954", - "399ec6c7e6bf87c9d3473e33197a93c9", - "0992abc52d822c3706476983284a0504", - "3517454ca23c4af38886564d3a14d493", - ), - ( - "9b1f5b424d93c9a703e7aa020c6e4141", - "4eb7f8719c36de1e89b4443b4ddbc49a", - "f4892bcb929b069069d18d2bd1a5c42f", - "36acc2355951a8d9a47f0dd4bf02e71e", - ), - ( - "378f5a541631229b944c9ad8ec165fde", - "3a7d3a1b258942243cd955b7e00d0984", - "800a440bdbb2ceb17b2b8a9aa6079c54", - "0e38dc92cb1f2a607261445183235adb", - ), - ( - "abbedea680056f52382ae548b2e4f3f3", - "8941e71cff8a78db1fffe18a1b336103", - "9fe76702af69334b7a1e6c303b7652f4", - "3698fad1153bb6c374b4c7fb98459ced", - ), - ( - "7bcd9ed0efc889fb3002c6cd635afe94", - "d8fa6bbbebab07612001802114846679", - "8a1d71efea48b9caefbacd1d7d476e98", - "dea2594ac06fd85d6bcaa4cd81f32d1b", - ), - ( - "378ee767f11631bad21380b00449b17a", - "cda43c32bcdf1d77f82012d430219f9b", - "5d80ef9d1891cc86e71da4aa88e12852", - "faf417d5d9b21b9948bc924af11bd720", - ), -)] - - -def _lcache(): - cache = [] - for byteN in xrange(8): - cache.append([0 for _ in xrange(256)]) - for byteN in xrange(8): - for byteVal in xrange(256): - res64 = 0 - val = byteVal - for bitN in xrange(8): - if val & 0x80 > 0: - res64 ^= A[(7 - byteN) * 8 + bitN] - val <<= 1 - cache[byteN][byteVal] = res64 - return cache - - -# Trade memory for CPU for part of L() calculations -LCache = _lcache() - - -def add512bit(a, b): - a = int.from_bytes(a, "little") - b = int.from_bytes(b, "little") - r = (a + b) % (1 << 512) - return r.to_bytes(512 // 8, "little") - - -def g(n, hsh, msg): - res = E(LPS(strxor(hsh[:8], pack(">> m = GOST34112012(digest_size=32) - >>> m.update("foo") - >>> m.update("bar") - >>> m.hexdigest() - 'e3c9fd89226d93b489a9fe27d686806e24a514e3787bca053c698ec4616ceb78' - """ - block_size = BLOCKSIZE - - def __init__(self, data=b"", digest_size=64): - """ - :param digest_size: hash digest size to compute - :type digest_size: 32 or 64 bytes - """ - self._digest_size = digest_size - self.hsh = BLOCKSIZE * (b"\x01" if digest_size == 32 else b"\x00") - self.chk = bytearray(BLOCKSIZE * b"\x00") - self.n = 0 - self.buf = b"" - self.update(data) - - def copy(self): - obj = GOST34112012() - obj._digest_size = self._digest_size - obj.hsh = self.hsh - obj.chk = copy(self.chk) - obj.n = self.n - obj.buf = self.buf - return obj - - @property - def digest_size(self): - return self._digest_size - - def _update_block(self, block): - self.hsh = g(self.n, self.hsh, block) - self.chk = add512bit(self.chk, block) - self.n += 512 - - def update(self, data): - """Update state with the new data - """ - if len(self.buf) > 0: - chunk_len = BLOCKSIZE - len(self.buf) - self.buf += data[:chunk_len] - data = data[chunk_len:] - if len(self.buf) == BLOCKSIZE: - self._update_block(self.buf) - self.buf = b"" - while len(data) >= BLOCKSIZE: - self._update_block(data[:BLOCKSIZE]) - data = data[BLOCKSIZE:] - self.buf += data - - def digest(self): - """Get hash of the provided data - """ - data = self.buf - - # Padding - padblock_size = len(data) * 8 - data += b"\x01" - padlen = BLOCKSIZE - len(data) - if padlen != BLOCKSIZE: - data += b"\x00" * padlen - - hsh = g(self.n, self.hsh, data) - n = self.n + padblock_size - chk = add512bit(self.chk, data) - hsh = g(0, hsh, pack(" -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.11-94 hash function - -This is implementation of :rfc:`5831`. Most function and variable names are -taken according to specification's terminology. -""" - -from copy import copy -from functools import partial -from struct import pack - -from pygost.gost28147 import block2ns -from pygost.gost28147 import encrypt -from pygost.gost28147 import ns2block -from pygost.gost28147 import validate_sbox -from pygost.iface import PEP247 -from pygost.pbkdf2 import pbkdf2 as pbkdf2_base -from pygost.utils import hexdec -from pygost.utils import hexenc -from pygost.utils import strxor -from pygost.utils import xrange - - -DEFAULT_SBOX = "id-GostR3411-94-CryptoProParamSet" -BLOCKSIZE = 32 -C2 = 32 * b"\x00" -C3 = hexdec(b"ff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00") -C4 = 32 * b"\x00" -digest_size = 32 - - -def A(x): - x4, x3, x2, x1 = x[0:8], x[8:16], x[16:24], x[24:32] - return b"".join((strxor(x1, x2), x4, x3, x2)) - - -def P(x): - return bytearray(( - x[0], x[8], x[16], x[24], x[1], x[9], x[17], x[25], x[2], - x[10], x[18], x[26], x[3], x[11], x[19], x[27], x[4], x[12], - x[20], x[28], x[5], x[13], x[21], x[29], x[6], x[14], x[22], - x[30], x[7], x[15], x[23], x[31], - )) - - -def _chi(Y): - """Chi function - - This is some kind of LFSR. - """ - (y16, y15, y14, y13, y12, y11, y10, y9, y8, y7, y6, y5, y4, y3, y2, y1) = ( - Y[0:2], Y[2:4], Y[4:6], Y[6:8], Y[8:10], Y[10:12], Y[12:14], - Y[14:16], Y[16:18], Y[18:20], Y[20:22], Y[22:24], Y[24:26], - Y[26:28], Y[28:30], Y[30:32], - ) - by1, by2, by3, by4, by13, by16, byx = ( - bytearray(y1), bytearray(y2), bytearray(y3), bytearray(y4), - bytearray(y13), bytearray(y16), bytearray(2), - ) - byx[0] = by1[0] ^ by2[0] ^ by3[0] ^ by4[0] ^ by13[0] ^ by16[0] - byx[1] = by1[1] ^ by2[1] ^ by3[1] ^ by4[1] ^ by13[1] ^ by16[1] - return b"".join(( - bytes(byx), y16, y15, y14, y13, y12, y11, y10, y9, y8, y7, y6, y5, y4, y3, y2 - )) - - -def _step(hin, m, sbox): - """Step function - - H_out = f(H_in, m) - """ - # Generate keys - u = hin - v = m - w = strxor(hin, m) - k1 = P(w) - - u = strxor(A(u), C2) - v = A(A(v)) - w = strxor(u, v) - k2 = P(w) - - u = strxor(A(u), C3) - v = A(A(v)) - w = strxor(u, v) - k3 = P(w) - - u = strxor(A(u), C4) - v = A(A(v)) - w = strxor(u, v) - k4 = P(w) - - # Encipher - h4, h3, h2, h1 = hin[0:8], hin[8:16], hin[16:24], hin[24:32] - s1 = ns2block(encrypt(sbox, k1[::-1], block2ns(h1[::-1])))[::-1] - s2 = ns2block(encrypt(sbox, k2[::-1], block2ns(h2[::-1])))[::-1] - s3 = ns2block(encrypt(sbox, k3[::-1], block2ns(h3[::-1])))[::-1] - s4 = ns2block(encrypt(sbox, k4[::-1], block2ns(h4[::-1])))[::-1] - s = b"".join((s4, s3, s2, s1)) - - # Permute - # H_out = chi^61(H_in XOR chi(m XOR chi^12(S))) - x = s - for _ in xrange(12): - x = _chi(x) - x = strxor(x, m) - x = _chi(x) - x = strxor(hin, x) - for _ in xrange(61): - x = _chi(x) - return x - - -class GOST341194(PEP247): - """GOST 34.11-94 big-endian hash - - >>> m = GOST341194() - >>> m.update("foo") - >>> m.update("bar") - >>> m.hexdigest() - '3bd8a3a35917871dfa0d49f9e73e7c57eea028dc061133eb560849ea20c133af' - >>> GOST341194("foobar").hexdigest() - '3bd8a3a35917871dfa0d49f9e73e7c57eea028dc061133eb560849ea20c133af' - """ - block_size = BLOCKSIZE - digest_size = digest_size - - def __init__(self, data=b"", sbox=DEFAULT_SBOX): - """ - :param bytes data: provide initial data - :param bytes sbox: S-box to use - """ - validate_sbox(sbox) - self.data = data - self.sbox = sbox - - def copy(self): - return GOST341194(copy(self.data), self.sbox) - - def update(self, data): - """Append data that has to be hashed - """ - self.data += data - - def digest(self): - """Get hash of the provided data - """ - _len = 0 - checksum = 0 - h = 32 * b"\x00" - m = self.data - for i in xrange(0, len(m), BLOCKSIZE): - part = m[i:i + BLOCKSIZE][::-1] - _len += len(part) * 8 - checksum = (checksum + int(hexenc(part), 16)) % (2 ** 256) - if len(part) < BLOCKSIZE: - part = b"\x00" * (BLOCKSIZE - len(part)) + part - h = _step(h, part, self.sbox) - h = _step(h, 24 * b"\x00" + pack(">Q", _len), self.sbox) - - checksum = hex(checksum)[2:].rstrip("L") - if len(checksum) % 2 != 0: - checksum = "0" + checksum - checksum = hexdec(checksum) - checksum = b"\x00" * (BLOCKSIZE - len(checksum)) + checksum - h = _step(h, checksum, self.sbox) - return h[::-1] - - -def new(data=b"", sbox=DEFAULT_SBOX): - return GOST341194(data, sbox) - - -PBKDF2_HASHER = partial(GOST341194, sbox="id-GostR3411-94-CryptoProParamSet") - - -def pbkdf2(password, salt, iterations, dklen): - return pbkdf2_base(PBKDF2_HASHER, password, salt, iterations, dklen) diff --git a/pygost-5.13/pygost/gost3412.py b/pygost-5.13/pygost/gost3412.py deleted file mode 100644 index b9472ee..0000000 --- a/pygost-5.13/pygost/gost3412.py +++ /dev/null @@ -1,186 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST 34.12-2015 64 and 128 bit block ciphers (:rfc:`7801`) - -Several precalculations are performed during this module importing. -""" - -from pygost.gost28147 import block2ns as gost28147_block2ns -from pygost.gost28147 import decrypt as gost28147_decrypt -from pygost.gost28147 import encrypt as gost28147_encrypt -from pygost.gost28147 import ns2block as gost28147_ns2block -from pygost.utils import strxor -from pygost.utils import xrange - - -KEYSIZE = 32 - -LC = bytearray(( - 148, 32, 133, 16, 194, 192, 1, 251, 1, 192, 194, 16, 133, 32, 148, 1, -)) -PI = bytearray(( - 252, 238, 221, 17, 207, 110, 49, 22, 251, 196, 250, 218, 35, 197, 4, 77, - 233, 119, 240, 219, 147, 46, 153, 186, 23, 54, 241, 187, 20, 205, 95, 193, - 249, 24, 101, 90, 226, 92, 239, 33, 129, 28, 60, 66, 139, 1, 142, 79, 5, - 132, 2, 174, 227, 106, 143, 160, 6, 11, 237, 152, 127, 212, 211, 31, 235, - 52, 44, 81, 234, 200, 72, 171, 242, 42, 104, 162, 253, 58, 206, 204, 181, - 112, 14, 86, 8, 12, 118, 18, 191, 114, 19, 71, 156, 183, 93, 135, 21, 161, - 150, 41, 16, 123, 154, 199, 243, 145, 120, 111, 157, 158, 178, 177, 50, 117, - 25, 61, 255, 53, 138, 126, 109, 84, 198, 128, 195, 189, 13, 87, 223, 245, - 36, 169, 62, 168, 67, 201, 215, 121, 214, 246, 124, 34, 185, 3, 224, 15, - 236, 222, 122, 148, 176, 188, 220, 232, 40, 80, 78, 51, 10, 74, 167, 151, - 96, 115, 30, 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65, 173, 69, 70, - 146, 39, 94, 85, 47, 140, 163, 165, 125, 105, 213, 149, 59, 7, 88, 179, 64, - 134, 172, 29, 247, 48, 55, 107, 228, 136, 217, 231, 137, 225, 27, 131, 73, - 76, 63, 248, 254, 141, 83, 170, 144, 202, 216, 133, 97, 32, 113, 103, 164, - 45, 43, 9, 91, 203, 155, 37, 208, 190, 229, 108, 82, 89, 166, 116, 210, 230, - 244, 180, 192, 209, 102, 175, 194, 57, 75, 99, 182, -)) - -######################################################################## -# Precalculate inverted PI value as a performance optimization. -# Actually it can be computed only once and saved on the disk. -######################################################################## -PIinv = bytearray(256) -for x in xrange(256): - PIinv[PI[x]] = x - - -def gf(a, b): - c = 0 - while b: - if b & 1: - c ^= a - if a & 0x80: - a = (a << 1) ^ 0x1C3 - else: - a <<= 1 - b >>= 1 - return c - -######################################################################## -# Precalculate all possible gf(byte, byte) values as a performance -# optimization. -# Actually it can be computed only once and saved on the disk. -######################################################################## - - -GF = [bytearray(256) for _ in xrange(256)] - -for x in xrange(256): - for y in xrange(256): - GF[x][y] = gf(x, y) - - -def L(blk, rounds=16): - for _ in range(rounds): - t = blk[15] - for i in range(14, -1, -1): - blk[i + 1] = blk[i] - t ^= GF[blk[i]][LC[i]] - blk[0] = t - return blk - - -def Linv(blk): - for _ in range(16): - t = blk[0] - for i in range(15): - blk[i] = blk[i + 1] - t ^= GF[blk[i]][LC[i]] - blk[15] = t - return blk - -######################################################################## -# Precalculate values of the C -- it does not depend on key. -# Actually it can be computed only once and saved on the disk. -######################################################################## - - -C = [] - -for x in range(1, 33): - y = bytearray(16) - y[15] = x - C.append(L(y)) - - -def lp(blk): - return L([PI[v] for v in blk]) - - -class GOST3412Kuznechik(object): - """GOST 34.12-2015 128-bit block cipher Кузнечик (Kuznechik) - """ - blocksize = 16 - - def __init__(self, key): - """ - :param key: encryption/decryption key - :type key: bytes, 32 bytes - - Key scheduling (roundkeys precomputation) is performed here. - """ - kr0 = bytearray(key[:16]) - kr1 = bytearray(key[16:]) - self.ks = [kr0, kr1] - for i in range(4): - for j in range(8): - k = lp(bytearray(strxor(C[8 * i + j], kr0))) - kr0, kr1 = [strxor(k, kr1), kr0] - self.ks.append(kr0) - self.ks.append(kr1) - - def encrypt(self, blk): - blk = bytearray(blk) - for i in range(9): - blk = lp(bytearray(strxor(self.ks[i], blk))) - return bytes(strxor(self.ks[9], blk)) - - def decrypt(self, blk): - blk = bytearray(blk) - for i in range(9, 0, -1): - blk = [PIinv[v] for v in Linv(bytearray(strxor(self.ks[i], blk)))] - return bytes(strxor(self.ks[0], blk)) - - -class GOST3412Magma(object): - """GOST 34.12-2015 64-bit block cipher Магма (Magma) - """ - blocksize = 8 - - def __init__(self, key): - """ - :param key: encryption/decryption key - :type key: bytes, 32 bytes - """ - # Backward compatibility key preparation for 28147-89 key schedule - self.key = b"".join(key[i * 4:i * 4 + 4][::-1] for i in range(8)) - self.sbox = "id-tc26-gost-28147-param-Z" - - def encrypt(self, blk): - return gost28147_ns2block(gost28147_encrypt( - self.sbox, - self.key, - gost28147_block2ns(blk[::-1]), - ))[::-1] - - def decrypt(self, blk): - return gost28147_ns2block(gost28147_decrypt( - self.sbox, - self.key, - gost28147_block2ns(blk[::-1]), - ))[::-1] diff --git a/pygost-5.13/pygost/gost3413.py b/pygost-5.13/pygost/gost3413.py deleted file mode 100644 index f3cb5da..0000000 --- a/pygost-5.13/pygost/gost3413.py +++ /dev/null @@ -1,392 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""GOST R 34.13-2015: Modes of operation for block ciphers - -This module currently includes only padding methods. -""" - -from os import urandom - -from pygost.utils import bytes2long -from pygost.utils import long2bytes -from pygost.utils import strxor -from pygost.utils import xrange - - -KEYSIZE = 32 - - -def pad_size(data_size, blocksize): - """Calculate required pad size to full up blocksize - """ - if data_size < blocksize: - return blocksize - data_size - if data_size % blocksize == 0: - return 0 - return blocksize - data_size % blocksize - - -def pad1(data, blocksize): - """Padding method 1 - - Just fill up with zeros if necessary. - """ - return data + b"\x00" * pad_size(len(data), blocksize) - - -def pad2(data, blocksize): - """Padding method 2 (also known as ISO/IEC 7816-4) - - Add one bit and then fill up with zeros. - """ - return data + b"\x80" + b"\x00" * pad_size(len(data) + 1, blocksize) - - -def unpad2(data, blocksize): - """Unpad method 2 - """ - last_block = bytearray(data[-blocksize:]) - pad_index = last_block.rfind(b"\x80") - if pad_index == -1: - raise ValueError("Invalid padding") - for c in last_block[pad_index + 1:]: - if c != 0: - raise ValueError("Invalid padding") - return data[:-(blocksize - pad_index)] - - -def pad3(data, blocksize): - """Padding method 3 - """ - if pad_size(len(data), blocksize) == 0: - return data - return pad2(data, blocksize) - - -def ecb_encrypt(encrypter, bs, pt): - """ECB encryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes pt: already padded plaintext - """ - if not pt or len(pt) % bs != 0: - raise ValueError("Plaintext is not blocksize aligned") - ct = [] - for i in xrange(0, len(pt), bs): - ct.append(encrypter(pt[i:i + bs])) - return b"".join(ct) - - -def ecb_decrypt(decrypter, bs, ct): - """ECB decryption mode of operation - - :param decrypter: Decrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes ct: ciphertext - """ - if not ct or len(ct) % bs != 0: - raise ValueError("Ciphertext is not blocksize aligned") - pt = [] - for i in xrange(0, len(ct), bs): - pt.append(decrypter(ct[i:i + bs])) - return b"".join(pt) - - -def acpkm(encrypter, bs): - """Perform ACPKM key derivation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - """ - return b"".join([ - encrypter(bytes(bytearray(range(d, d + bs)))) - for d in range(0x80, 0x80 + bs * (KEYSIZE // bs), bs) - ]) - - -def ctr(encrypter, bs, data, iv, _acpkm=None): - """Counter mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes data: plaintext/ciphertext - :param bytes iv: half blocksize-sized initialization vector - - For decryption you use the same function again. - """ - if len(iv) != bs // 2: - raise ValueError("Invalid IV size") - if len(data) > bs * (1 << (8 * (bs // 2 - 1))): - raise ValueError("Too big data") - stream = [] - ctr_value = 0 - ctr_max_value = 1 << (8 * (bs // 2)) - if _acpkm is not None: - acpkm_algo_class, acpkm_section_size_in_bs = _acpkm - acpkm_section_size_in_bs //= bs - for _ in xrange(0, len(data) + pad_size(len(data), bs), bs): - if ( - _acpkm is not None and - ctr_value != 0 and - ctr_value % acpkm_section_size_in_bs == 0 - ): - encrypter = acpkm_algo_class(acpkm(encrypter, bs)).encrypt - stream.append(encrypter(iv + long2bytes(ctr_value, bs // 2))) - ctr_value = (ctr_value + 1) % ctr_max_value - return strxor(b"".join(stream), data) - - -def ctr_acpkm(algo_class, encrypter, section_size, bs, data, iv): - """CTR-ACPKM mode of operation - - :param algo_class: pygost.gost3412's algorithm class - :param encrypter: encrypting function, that takes block as an input - :param int section_size: ACPKM'es section size (N), in bytes - :param int bs: cipher's blocksize, bytes - :param bytes data: plaintext/ciphertext - :param bytes iv: half blocksize-sized initialization vector - - For decryption you use the same function again. - """ - if section_size % bs != 0: - raise ValueError("section_size must be multiple of bs") - return ctr(encrypter, bs, data, iv, _acpkm=(algo_class, section_size)) - - -def ofb(encrypter, bs, data, iv): - """OFB mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes data: plaintext/ciphertext - :param bytes iv: blocksize-sized initialization vector - - For decryption you use the same function again. - """ - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - result = [] - for i in xrange(0, len(data) + pad_size(len(data), bs), bs): - r = r[1:] + [encrypter(r[0])] - result.append(strxor(r[-1], data[i:i + bs])) - return b"".join(result) - - -def cbc_encrypt(encrypter, bs, pt, iv): - """CBC encryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes pt: already padded plaintext - :param bytes iv: blocksize-sized initialization vector - """ - if not pt or len(pt) % bs != 0: - raise ValueError("Plaintext is not blocksize aligned") - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - ct = [] - for i in xrange(0, len(pt), bs): - ct.append(encrypter(strxor(r[0], pt[i:i + bs]))) - r = r[1:] + [ct[-1]] - return b"".join(ct) - - -def cbc_decrypt(decrypter, bs, ct, iv): - """CBC decryption mode of operation - - :param decrypter: Decrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes ct: ciphertext - :param bytes iv: blocksize-sized initialization vector - """ - if not ct or len(ct) % bs != 0: - raise ValueError("Ciphertext is not blocksize aligned") - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - pt = [] - for i in xrange(0, len(ct), bs): - blk = ct[i:i + bs] - pt.append(strxor(r[0], decrypter(blk))) - r = r[1:] + [blk] - return b"".join(pt) - - -def cfb_encrypt(encrypter, bs, pt, iv): - """CFB encryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes pt: plaintext - :param bytes iv: blocksize-sized initialization vector - """ - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - ct = [] - for i in xrange(0, len(pt) + pad_size(len(pt), bs), bs): - ct.append(strxor(encrypter(r[0]), pt[i:i + bs])) - r = r[1:] + [ct[-1]] - return b"".join(ct) - - -def cfb_decrypt(encrypter, bs, ct, iv): - """CFB decryption mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes ct: ciphertext - :param bytes iv: blocksize-sized initialization vector - """ - if len(iv) < bs or len(iv) % bs != 0: - raise ValueError("Invalid IV size") - r = [iv[i:i + bs] for i in range(0, len(iv), bs)] - pt = [] - for i in xrange(0, len(ct) + pad_size(len(ct), bs), bs): - blk = ct[i:i + bs] - pt.append(strxor(encrypter(r[0]), blk)) - r = r[1:] + [blk] - return b"".join(pt) - - -def _mac_shift(bs, data, xor_lsb=0): - num = (bytes2long(data) << 1) ^ xor_lsb - return long2bytes(num, bs)[-bs:] - - -Rb64 = 0b11011 -Rb128 = 0b10000111 - - -def _mac_ks(encrypter, bs): - Rb = Rb128 if bs == 16 else Rb64 - _l = encrypter(bs * b"\x00") - k1 = _mac_shift(bs, _l, Rb) if bytearray(_l)[0] & 0x80 > 0 else _mac_shift(bs, _l) - k2 = _mac_shift(bs, k1, Rb) if bytearray(k1)[0] & 0x80 > 0 else _mac_shift(bs, k1) - return k1, k2 - - -def mac(encrypter, bs, data): - """MAC (known here as CMAC, OMAC1) mode of operation - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize, bytes - :param bytes data: data to authenticate - - Implementation is based on PyCrypto's CMAC one, that is in public domain. - """ - k1, k2 = _mac_ks(encrypter, bs) - if len(data) % bs == 0: - tail_offset = len(data) - bs - else: - tail_offset = len(data) - (len(data) % bs) - prev = bs * b"\x00" - for i in xrange(0, tail_offset, bs): - prev = encrypter(strxor(data[i:i + bs], prev)) - tail = data[tail_offset:] - return encrypter(strxor( - strxor(pad3(tail, bs), prev), - k1 if len(tail) == bs else k2, - )) - - -def acpkm_master(algo_class, encrypter, key_section_size, bs, keymat_len): - """ACPKM-Master key derivation - - :param algo_class: pygost.gost3412's algorithm class - :param encrypter: encrypting function, that takes block as an input - :param int key_section_size: ACPKM'es key section size (T*), in bytes - :param int bs: cipher's blocksize, bytes - :param int keymat_len: length of key material to produce - """ - return ctr_acpkm( - algo_class, - encrypter, - key_section_size, - bs, - data=b"\x00" * keymat_len, - iv=b"\xFF" * (bs // 2), - ) - - -def mac_acpkm_master(algo_class, encrypter, key_section_size, section_size, bs, data): - """OMAC-ACPKM-Master - - :param algo_class: pygost.gost3412's algorithm class - :param encrypter: encrypting function, that takes block as an input - :param int key_section_size: ACPKM'es key section size (T*), in bytes - :param int section_size: ACPKM'es section size (N), in bytes - :param int bs: cipher's blocksize, bytes - :param bytes data: data to authenticate - """ - if len(data) % bs == 0: - tail_offset = len(data) - bs - else: - tail_offset = len(data) - (len(data) % bs) - prev = bs * b"\x00" - sections = len(data) // section_size - if len(data) % section_size != 0: - sections += 1 - keymats = acpkm_master( - algo_class, - encrypter, - key_section_size, - bs, - (KEYSIZE + bs) * sections, - ) - for i in xrange(0, tail_offset, bs): - if i % section_size == 0: - keymat, keymats = keymats[:KEYSIZE + bs], keymats[KEYSIZE + bs:] - key, k1 = keymat[:KEYSIZE], keymat[KEYSIZE:] - encrypter = algo_class(key).encrypt - prev = encrypter(strxor(data[i:i + bs], prev)) - tail = data[tail_offset:] - if len(tail) == bs: - key, k1 = keymats[:KEYSIZE], keymats[KEYSIZE:] - encrypter = algo_class(key).encrypt - k2 = long2bytes(bytes2long(k1) << 1, size=bs) - if bytearray(k1)[0] & 0x80 != 0: - k2 = strxor(k2, long2bytes(Rb128 if bs == 16 else Rb64, size=bs)) - return encrypter(strxor( - strxor(pad3(tail, bs), prev), - k1 if len(tail) == bs else k2, - )) - - -def pad_iso10126(data, blocksize): - """ISO 10126 padding - - Does not exist in 34.13, but added for convenience. - It uses urandom call for getting the randomness. - """ - pad_len = blocksize - len(data) % blocksize - if pad_len == 0: - pad_len = blocksize - return b"".join((data, urandom(pad_len - 1), bytes((pad_len,)))) - - -def unpad_iso10126(data, blocksize): - """Unpad :py:func:`pygost.gost3413.pad_iso10126` - """ - if len(data) % blocksize != 0: - raise ValueError("Data length is not multiple of blocksize") - pad_len = bytearray(data)[-1] - if pad_len > blocksize: - raise ValueError("Padding length is bigger than blocksize") - return data[:-pad_len] diff --git a/pygost-5.13/pygost/iface.py b/pygost-5.13/pygost/iface.py deleted file mode 100644 index e2d6a4c..0000000 --- a/pygost-5.13/pygost/iface.py +++ /dev/null @@ -1,50 +0,0 @@ -from abc import ABCMeta -from abc import abstractmethod - -from pygost.utils import hexenc - - -# This function is taken from six package as is -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get("__slots__") - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop("__dict__", None) - orig_vars.pop("__weakref__", None) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - -@add_metaclass(ABCMeta) -class PEP247(object): - @property - @abstractmethod - def digest_size(self): - """The size of the digest produced by the hashing objects. - """ - - @abstractmethod - def copy(self): - """Return a separate copy of this hashing object. - """ - - @abstractmethod - def update(self, data): - """Hash data into the current state of the hashing object. - """ - - @abstractmethod - def digest(self): - """Return the hash value as a string containing 8-bit data. - """ - - def hexdigest(self): - """Return the hash value as a string containing hexadecimal digits. - """ - return hexenc(self.digest()) diff --git a/pygost-5.13/pygost/kdf.py b/pygost-5.13/pygost/kdf.py deleted file mode 100644 index 4e404c6..0000000 --- a/pygost-5.13/pygost/kdf.py +++ /dev/null @@ -1,81 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Key derivation functions, Р 50.1.113-2016, Р 1323565.1.020-2018 -""" - -import hmac - -from pygost.gost3410_vko import kek_34102012256 -from pygost.gost3410_vko import kek_34102012512 -from pygost.gost34112012256 import GOST34112012256 -from pygost.utils import bytes2long -from pygost.utils import long2bytes - - -def kdf_gostr3411_2012_256(key, label, seed): - """KDF_GOSTR3411_2012_256 - - :param bytes key: initial key - :param bytes label: label - :param bytes seed: seed - :returns: 32 bytes - """ - return hmac.new( - key=key, - msg=b"".join((b"\x01", label, b"\x00", seed, b"\x01\x00")), - digestmod=GOST34112012256, - ).digest() - - -def kdf_tree_gostr3411_2012_256(key, label, seed, keys, i_len=1): - """KDF_TREE_GOSTR3411_2012_256 - - :param bytes key: initial key - :param bytes label: label - :param bytes seed: seed - :param int keys: number of generated keys - :param int i_len: length of iterations value (called "R") - :returns: list of 256-bit keys - """ - keymat = [] - _len = long2bytes(keys * 32 * 8, size=1) - for i in range(keys): - keymat.append(hmac.new( - key=key, - msg=b"".join((long2bytes(i + 1, size=i_len), label, b"\x00", seed, _len)), - digestmod=GOST34112012256, - ).digest()) - return keymat - - -def keg(curve, prv, pub, h): - """Export key generation (Р 1323565.1.020-2018) - - :param GOST3410Curve curve: curve to use - :param long prv: private key - :param pub: public key - :type pub: (long, long) - :param bytes h: "h"-value, 32 bytes - """ - if len(h) != 32: - raise ValueError("h must be 32 bytes long") - ukm = bytes2long(h[:16]) - if ukm == 0: - ukm = 1 - if curve.point_size == 64: - return kek_34102012512(curve, prv, pub, ukm) - k_exp = kek_34102012256(curve, prv, pub, ukm) - return b"".join(kdf_tree_gostr3411_2012_256(k_exp, b"kdf tree", h[16:24], 2)) diff --git a/pygost-5.13/pygost/mgm.py b/pygost-5.13/pygost/mgm.py deleted file mode 100644 index fb51343..0000000 --- a/pygost-5.13/pygost/mgm.py +++ /dev/null @@ -1,168 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Multilinear Galois Mode (MGM) block cipher mode. -""" - -from hmac import compare_digest - -from pygost.gost3413 import pad1 -from pygost.utils import bytes2long -from pygost.utils import long2bytes -from pygost.utils import strxor - - -def _incr(data, bs): - return long2bytes(bytes2long(data) + 1, size=bs // 2) - - -def incr_r(data, bs): - return data[:bs // 2] + _incr(data[bs // 2:], bs) - - -def incr_l(data, bs): - return _incr(data[:bs // 2], bs) + data[bs // 2:] - - -def nonce_prepare(nonce): - """Prepare nonce for MGM usage - - It just clears MSB. - """ - n = bytearray(nonce) - n[0] &= 0x7F - return bytes(n) - - -class MGM(object): - # Implementation is fully based on go.cypherpunks.ru/gogost/mgm - def __init__(self, encrypter, bs, tag_size=None): - """Multilinear Galois Mode (MGM) block cipher mode - - :param encrypter: encrypting function, that takes block as an input - :param int bs: cipher's blocksize - :param int tag_size: authentication tag size - (defaults to blocksize if not specified) - """ - if bs not in (8, 16): - raise ValueError("Only 64/128-bit blocksizes allowed") - self.tag_size = bs if tag_size is None else tag_size - if self.tag_size < 4 or self.tag_size > bs: - raise ValueError("Invalid tag_size") - self.encrypter = encrypter - self.bs = bs - self.max_size = (1 << (bs * 8 // 2)) - 1 - self.r = 0x1B if bs == 8 else 0x87 - - def _validate_nonce(self, nonce): - if len(nonce) != self.bs: - raise ValueError("nonce length must be equal to cipher's blocksize") - if bytearray(nonce)[0] & 0x80 > 0: - raise ValueError("nonce must not have higher bit set") - - def _validate_sizes(self, plaintext, additional_data): - if len(plaintext) == 0 and len(additional_data) == 0: - raise ValueError("At least one of plaintext or additional_data required") - if len(plaintext) + len(additional_data) > self.max_size: - raise ValueError("plaintext+additional_data are too big") - - def _mul(self, x, y): - x = bytes2long(x) - y = bytes2long(y) - z = 0 - max_bit = 1 << (self.bs * 8 - 1) - while y > 0: - if y & 1 == 1: - z ^= x - if x & max_bit > 0: - x = ((x ^ max_bit) << 1) ^ self.r - else: - x <<= 1 - y >>= 1 - return long2bytes(z, size=self.bs) - - def _crypt(self, icn, data): - icn[0] &= 0x7F - enc = self.encrypter(bytes(icn)) - res = [] - while len(data) > 0: - res.append(strxor(self.encrypter(enc), data)) - enc = incr_r(enc, self.bs) - data = data[self.bs:] - return b"".join(res) - - def _auth(self, icn, text, ad): - icn[0] |= 0x80 - enc = self.encrypter(bytes(icn)) - _sum = self.bs * b"\x00" - ad_len = len(ad) - text_len = len(text) - while len(ad) > 0: - _sum = strxor(_sum, self._mul( - self.encrypter(enc), - pad1(ad[:self.bs], self.bs), - )) - enc = incr_l(enc, self.bs) - ad = ad[self.bs:] - while len(text) > 0: - _sum = strxor(_sum, self._mul( - self.encrypter(enc), - pad1(text[:self.bs], self.bs), - )) - enc = incr_l(enc, self.bs) - text = text[self.bs:] - _sum = strxor(_sum, self._mul(self.encrypter(enc), ( - long2bytes(ad_len * 8, size=self.bs // 2) + - long2bytes(text_len * 8, size=self.bs // 2) - ))) - return self.encrypter(_sum)[:self.tag_size] - - def seal(self, nonce, plaintext, additional_data): - """Seal plaintext - - :param bytes nonce: blocksize-sized nonce. - Assure that it does not have MSB bit set - (:py:func:`pygost.mgm.nonce_prepare` helps) - :param bytes plaintext: plaintext to be encrypted and authenticated - :param bytes additional_data: additional data to be authenticated - """ - self._validate_nonce(nonce) - self._validate_sizes(plaintext, additional_data) - icn = bytearray(nonce) - ciphertext = self._crypt(icn, plaintext) - tag = self._auth(icn, ciphertext, additional_data) - return ciphertext + tag - - def open(self, nonce, ciphertext, additional_data): - """Open ciphertext - - :param bytes nonce: blocksize-sized nonce. - Assure that it does not have MSB bit set - (:py:func:`pygost.mgm.nonce_prepare` helps) - :param bytes ciphertext: ciphertext to be decrypted and authenticated - :param bytes additional_data: additional data to be authenticated - :raises ValueError: if ciphertext authentication fails - """ - self._validate_nonce(nonce) - self._validate_sizes(ciphertext, additional_data) - icn = bytearray(nonce) - ciphertext, tag_expected = ( - ciphertext[:-self.tag_size], - ciphertext[-self.tag_size:], - ) - tag = self._auth(icn, ciphertext, additional_data) - if not compare_digest(tag_expected, tag): - raise ValueError("Invalid authentication tag") - return self._crypt(icn, ciphertext) diff --git a/pygost-5.13/pygost/pbkdf2.py b/pygost-5.13/pygost/pbkdf2.py deleted file mode 100644 index 0fd6ddc..0000000 --- a/pygost-5.13/pygost/pbkdf2.py +++ /dev/null @@ -1,41 +0,0 @@ -# coding: utf-8 -"""PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012. - -This implementation is based on Python 3.5.2 source code's one. -PyGOST does not register itself in hashlib anyway, so use it instead. -""" - - -from pygost.utils import bytes2long -from pygost.utils import long2bytes -from pygost.utils import strxor -from pygost.utils import xrange - - -def pbkdf2(hasher, password, salt, iterations, dklen): - """PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012 - """ - inner = hasher() - outer = hasher() - password = password + b"\x00" * (inner.block_size - len(password)) - inner.update(strxor(password, len(password) * b"\x36")) - outer.update(strxor(password, len(password) * b"\x5C")) - - def prf(msg): - icpy = inner.copy() - ocpy = outer.copy() - icpy.update(msg) - ocpy.update(icpy.digest()) - return ocpy.digest() - - dkey = b"" - loop = 1 - while len(dkey) < dklen: - prev = prf(salt + long2bytes(loop, 4)) - rkey = bytes2long(prev) - for _ in xrange(iterations - 1): - prev = prf(prev) - rkey ^= bytes2long(prev) - loop += 1 - dkey += long2bytes(rkey, inner.digest_size) - return dkey[:dklen] diff --git a/pygost-5.13/pygost/stubs/pygost/__init__.pyi b/pygost-5.13/pygost/stubs/pygost/__init__.pyi deleted file mode 100644 index e69de29..0000000 diff --git a/pygost-5.13/pygost/stubs/pygost/gost28147.pyi b/pygost-5.13/pygost/stubs/pygost/gost28147.pyi deleted file mode 100644 index be31261..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost28147.pyi +++ /dev/null @@ -1,101 +0,0 @@ -from typing import Callable -from typing import Dict -from typing import Sequence -from typing import Tuple - - -SBOXES = ... # type: Dict[str, Tuple[Tuple[int, ...], ...]] -BLOCKSIZE = ... # type: int - -Words = Tuple[int, int] - - -def block2ns(data: bytes) -> Words: ... - - -def ns2block(ns: Words) -> bytes: ... - - -def validate_key(key: bytes) -> None: ... - - -def validate_iv(iv: bytes) -> None: ... - - -def validate_sbox(sbox: str) -> None: ... - - -def xcrypt(seq: Sequence[int], sbox: str, key: bytes, ns: Words) -> Words: ... - - -def encrypt(sbox: str, key: bytes, ns: Words) -> Words: ... - - -def decrypt(sbox: str, key: bytes, ns: Words) -> Words: ... - - -def ecb( - key: bytes, - data: bytes, - action: Callable[[str, bytes, Words], Words], - sbox: str = ..., -) -> bytes: ... - - -def ecb_encrypt( - key: bytes, - data: bytes, - sbox: str = ..., -) -> bytes: ... - - -def ecb_decrypt( - key: bytes, - data: bytes, - sbox: str = ..., -) -> bytes: ... - - -def cbc_encrypt( - key: bytes, - data: bytes, - iv: bytes = ..., - pad: bool = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... - - -def cbc_decrypt( - key: bytes, - data: bytes, - pad: bool = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... - - -def cnt( - key: bytes, - data: bytes, - iv: bytes = ..., - sbox: str = ..., -) -> bytes: ... - - -def cfb_encrypt( - key: bytes, - data: bytes, - iv: bytes = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... - - -def cfb_decrypt( - key: bytes, - data: bytes, - iv: bytes = ..., - sbox: str = ..., - mesh: bool = ..., -) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost28147_mac.pyi b/pygost-5.13/pygost/stubs/pygost/gost28147_mac.pyi deleted file mode 100644 index 70d90d6..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost28147_mac.pyi +++ /dev/null @@ -1,25 +0,0 @@ -from pygost.iface import PEP247 - - -class MAC(PEP247): - def __init__( - self, - key: bytes, - data: bytes = ..., - iv: bytes = ..., - sbox: str = ..., - ) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "MAC": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(key: bytes, data: bytes = ..., iv: bytes = ..., sbox: str = ...) -> MAC: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost3410.pyi b/pygost-5.13/pygost/stubs/pygost/gost3410.pyi deleted file mode 100644 index 8f0dcb8..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost3410.pyi +++ /dev/null @@ -1,72 +0,0 @@ -from typing import Dict -from typing import Tuple - - -DEFAULT_CURVE = ... # type: GOST3410Curve -CURVES = ... # type: Dict[str, GOST3410Curve] -PublicKey = Tuple[int, int] - - -class GOST3410Curve(object): - p = ... # type: int - q = ... # type: int - a = ... # type: int - b = ... # type: int - x = ... # type: int - y = ... # type: int - cofactor = ... # type: int - e = ... # type: int - d = ... # type: int - name = ... # type: str - - def __init__( - self, - p: int, - q: int, - a: int, - b: int, - x: int, - y: int, - cofactor: int = 1, - e: int = None, - d: int = None, - name: str = None, - ) -> None: ... - - def pos(self, v: int) -> int: ... - - def exp(self, degree: int, x: int = ..., y: int = ...) -> int: ... - - def st(self) -> Tuple[int, int]: ... - - @property - def point_size(self) -> int: ... - - def contains(self, point: Tuple[int, int]) -> bool: ... - - -def public_key(curve: GOST3410Curve, prv: int) -> PublicKey: ... - - -def sign(curve: GOST3410Curve, prv: int, digest: bytes, rand: bytes = None) -> bytes: ... - - -def verify(curve: GOST3410Curve, pub: PublicKey, digest: bytes, signature: bytes) -> bool: ... - - -def prv_unmarshal(prv: bytes) -> int: ... - - -def prv_marshal(curve: GOST3410Curve, prv: int) -> bytes: ... - - -def pub_marshal(pub: PublicKey) -> bytes: ... - - -def pub_unmarshal(pub: bytes) -> PublicKey: ... - - -def uv2xy(curve: GOST3410Curve, u: int, v: int) -> Tuple[int, int]: ... - - -def xy2uv(curve: GOST3410Curve, x: int, y: int) -> Tuple[int, int]: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost3410_vko.pyi b/pygost-5.13/pygost/stubs/pygost/gost3410_vko.pyi deleted file mode 100644 index 6ea9b82..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost3410_vko.pyi +++ /dev/null @@ -1,17 +0,0 @@ -from pygost.gost3410 import GOST3410Curve -from pygost.gost3410 import PublicKey - - -def ukm_unmarshal(ukm: bytes) -> int: ... - - -def kek(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int) -> bytes: ... - - -def kek_34102001(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int) -> bytes: ... - - -def kek_34102012256(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int = ...) -> bytes: ... - - -def kek_34102012512(curve: GOST3410Curve, prv: int, pub: PublicKey, ukm: int = ...) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost34112012.pyi b/pygost-5.13/pygost/stubs/pygost/gost34112012.pyi deleted file mode 100644 index 3d5cc41..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost34112012.pyi +++ /dev/null @@ -1,18 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST34112012(PEP247): - block_size = ... # type: int - - def __init__(self, data: bytes = ..., digest_size: int = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST34112012": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost34112012256.pyi b/pygost-5.13/pygost/stubs/pygost/gost34112012256.pyi deleted file mode 100644 index a1d2a01..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost34112012256.pyi +++ /dev/null @@ -1,21 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST34112012256(PEP247): - block_size = ... # type: int - - def __init__(self, data: bytes = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST34112012256": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(data: bytes = ...) -> GOST34112012256: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost34112012512.pyi b/pygost-5.13/pygost/stubs/pygost/gost34112012512.pyi deleted file mode 100644 index 349bddd..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost34112012512.pyi +++ /dev/null @@ -1,24 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST34112012512(PEP247): - block_size = ... # type: int - - def __init__(self, data: bytes = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST34112012512": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(data: bytes = ...) -> GOST34112012512: ... - - -def pbkdf2(password: bytes, salt: bytes, iterations: int, dklen: int) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost341194.pyi b/pygost-5.13/pygost/stubs/pygost/gost341194.pyi deleted file mode 100644 index 24de2e4..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost341194.pyi +++ /dev/null @@ -1,25 +0,0 @@ -from pygost.iface import PEP247 - - -class GOST341194(PEP247): - sbox = ... # type: str - block_size = ... # type: int - - def __init__(self, data: bytes = ..., sbox: str = ...) -> None: ... - - @property - def digest_size(self) -> int: ... - - def copy(self) -> "GOST341194": ... - - def update(self, data: bytes) -> None: ... - - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... - - -def new(data: bytes = ..., sbox: str = ...) -> GOST341194: ... - - -def pbkdf2(password: bytes, salt: bytes, iterations: int, dklen: int) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost3412.pyi b/pygost-5.13/pygost/stubs/pygost/gost3412.pyi deleted file mode 100644 index ef278b7..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost3412.pyi +++ /dev/null @@ -1,18 +0,0 @@ -class GOST3412Kuznechik(object): - blocksize = ... # type: int - - def __init__(self, key: bytes) -> None: ... - - def encrypt(self, blk: bytes) -> bytes: ... - - def decrypt(self, blk: bytes) -> bytes: ... - - -class GOST3412Magma(object): - blocksize = ... # type: int - - def __init__(self, key: bytes) -> None: ... - - def encrypt(self, blk: bytes) -> bytes: ... - - def decrypt(self, blk: bytes) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/gost3413.pyi b/pygost-5.13/pygost/stubs/pygost/gost3413.pyi deleted file mode 100644 index 4cfd694..0000000 --- a/pygost-5.13/pygost/stubs/pygost/gost3413.pyi +++ /dev/null @@ -1,81 +0,0 @@ -from typing import Callable - - -def pad_size(data_size: int, blocksize: int) -> int: ... - - -def pad1(data: bytes, blocksize: int) -> bytes: ... - - -def pad2(data: bytes, blocksize: int) -> bytes: ... - - -def unpad2(data: bytes, blocksize: int) -> bytes: ... - - -def pad3(data: bytes, blocksize: int) -> bytes: ... - - -def ecb_encrypt(encrypter: Callable[[bytes], bytes], bs: int, pt: bytes) -> bytes: ... - - -def ecb_decrypt(decrypter: Callable[[bytes], bytes], bs: int, ct: bytes) -> bytes: ... - - -def acpkm(encrypter: Callable[[bytes], bytes], bs: int) -> bytes: ... - - -def ctr(encrypter: Callable[[bytes], bytes], bs: int, data: bytes, iv: bytes) -> bytes: ... - - -def ctr_acpkm( - algo_class: object, - encrypter: Callable[[bytes], bytes], - section_size: int, - bs: int, - data: bytes, - iv: bytes, -) -> bytes: ... - - -def ofb(encrypter: Callable[[bytes], bytes], bs: int, data: bytes, iv: bytes) -> bytes: ... - - -def cbc_encrypt(encrypter: Callable[[bytes], bytes], bs: int, pt: bytes, iv: bytes) -> bytes: ... - - -def cbc_decrypt(decrypter: Callable[[bytes], bytes], bs: int, ct: bytes, iv: bytes) -> bytes: ... - - -def cfb_encrypt(encrypter: Callable[[bytes], bytes], bs: int, pt: bytes, iv: bytes) -> bytes: ... - - -def cfb_decrypt(encrypter: Callable[[bytes], bytes], bs: int, ct: bytes, iv: bytes) -> bytes: ... - - -def mac(encrypter: Callable[[bytes], bytes], bs: int, data: bytes) -> bytes: ... - - -def acpkm_master( - algo_class: object, - encrypter: Callable[[bytes], bytes], - key_section_size: int, - bs: int, - keymat_len: int, -) -> bytes: ... - - -def mac_acpkm_master( - algo_class: object, - encrypter: Callable[[bytes], bytes], - key_section_size: int, - section_size: int, - bs: int, - data: bytes, -) -> bytes: ... - - -def pad_iso10126(data: bytes, blocksize: int) -> bytes: ... - - -def unpad_iso10126(data: bytes, blocksize: int) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/iface.pyi b/pygost-5.13/pygost/stubs/pygost/iface.pyi deleted file mode 100644 index a5c2a85..0000000 --- a/pygost-5.13/pygost/stubs/pygost/iface.pyi +++ /dev/null @@ -1,19 +0,0 @@ -from abc import ABCMeta -from abc import abstractmethod - - -class PEP247(metaclass=ABCMeta): - @abstractmethod - @property - def digest_size(self) -> int: ... - - @abstractmethod - def copy(self) -> "PEP247": ... - - @abstractmethod - def update(self, data: bytes) -> None: ... - - @abstractmethod - def digest(self) -> bytes: ... - - def hexdigest(self) -> str: ... diff --git a/pygost-5.13/pygost/stubs/pygost/kdf.pyi b/pygost-5.13/pygost/stubs/pygost/kdf.pyi deleted file mode 100644 index ccab8af..0000000 --- a/pygost-5.13/pygost/stubs/pygost/kdf.pyi +++ /dev/null @@ -1,22 +0,0 @@ -from typing import Sequence -from typing import Tuple - -from pygost.gost3410 import GOST3410Curve - - -PublicKey = Tuple[int, int] - - -def kdf_gostr3411_2012_256(key: bytes, label: bytes, seed: bytes) -> bytes: ... - - -def kdf_tree_gostr3411_2012_256( - key: bytes, - label: bytes, - seed: bytes, - keys: int, - i_len: int = 1, -) -> Sequence[bytes]: ... - - -def keg(curve: GOST3410Curve, prv: int, pub: PublicKey, h: bytes) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/mgm.pyi b/pygost-5.13/pygost/stubs/pygost/mgm.pyi deleted file mode 100644 index 81906b7..0000000 --- a/pygost-5.13/pygost/stubs/pygost/mgm.pyi +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Callable - - -def nonce_prepare(nonce: bytes) -> bytes: ... - - -class MGM(object): - def __init__( - self, - encrypter: Callable[[bytes], bytes], - bs: int, - tag_size: int = None, - ) -> None: ... - - def seal(self, nonce: bytes, plaintext: bytes, additional_data: bytes) -> bytes: ... - - def open(self, nonce: bytes, ciphertext: bytes, additional_data: bytes) -> bytes: ... diff --git a/pygost-5.13/pygost/stubs/pygost/utils.pyi b/pygost-5.13/pygost/stubs/pygost/utils.pyi deleted file mode 100644 index 76460e5..0000000 --- a/pygost-5.13/pygost/stubs/pygost/utils.pyi +++ /dev/null @@ -1,19 +0,0 @@ -from typing import AnyStr - - -def strxor(a: bytes, b: bytes) -> bytes: ... - - -def hexdec(data: AnyStr) -> bytes: ... - - -def hexenc(data: bytes) -> str: ... - - -def bytes2long(raw: bytes) -> int: ... - - -def long2bytes(n: int, size: int = ...) -> bytes: ... - - -def modinvert(a: int, n: int) -> int: ... diff --git a/pygost-5.13/pygost/stubs/pygost/wrap.pyi b/pygost-5.13/pygost/stubs/pygost/wrap.pyi deleted file mode 100644 index 776a6e7..0000000 --- a/pygost-5.13/pygost/stubs/pygost/wrap.pyi +++ /dev/null @@ -1,31 +0,0 @@ -from typing import Callable - - -def wrap_gost(ukm: bytes, kek: bytes, cek: bytes, sbox: str = ...) -> bytes: ... - - -def unwrap_gost(kek: bytes, data: bytes, sbox: str = ...) -> bytes: ... - - -def wrap_cryptopro(ukm: bytes, kek: bytes, cek: bytes, sbox: str = ...) -> bytes: ... - - -def unwrap_cryptopro(kek: bytes, data: bytes, sbox: str = ...) -> bytes: ... - - -def kexp15( - encrypter_key: Callable[[bytes], bytes], - encrypter_mac: Callable[[bytes], bytes], - bs: int, - key: bytes, - iv: bytes, -) -> bytes: ... - - -def kimp15( - encrypter_key: Callable[[bytes], bytes], - encrypter_mac: Callable[[bytes], bytes], - bs: int, - kexp: bytes, - iv: bytes, -) -> bytes: ... diff --git a/pygost-5.13/pygost/test_cms.py b/pygost-5.13/pygost/test_cms.py deleted file mode 100644 index 7e5781a..0000000 --- a/pygost-5.13/pygost/test_cms.py +++ /dev/null @@ -1,1078 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from base64 import b64decode -from unittest import skipIf -from unittest import TestCase - -from six import text_type - -from pygost.gost28147 import cfb_decrypt -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_marshal -from pygost.gost3410 import pub_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410 import verify -from pygost.gost3410_vko import kek_34102012256 -from pygost.gost3410_vko import ukm_unmarshal -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3413 import ctr_acpkm -from pygost.gost3413 import KEYSIZE -from pygost.gost3413 import mac as omac -from pygost.kdf import kdf_tree_gostr3411_2012_256 -from pygost.kdf import keg -from pygost.utils import hexdec -from pygost.wrap import kimp15 -from pygost.wrap import unwrap_cryptopro -from pygost.wrap import unwrap_gost - -try: - from pyderasn import DecodePathDefBy - from pyderasn import OctetString - - from pygost.asn1schemas.cms import ContentInfo - from pygost.asn1schemas.cms import SignedAttributes - from pygost.asn1schemas.oids import id_cms_mac_attr - from pygost.asn1schemas.oids import id_envelopedData - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm_omac - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_wrap_kexp15 - from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm - from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm_omac - from pygost.asn1schemas.oids import id_gostr3412_2015_magma_wrap_kexp15 - from pygost.asn1schemas.oids import id_messageDigest - from pygost.asn1schemas.oids import id_tc26_agreement_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_agreement_gost3410_2012_512 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetA - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_512 - from pygost.asn1schemas.x509 import Certificate - from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters -except ImportError: - pyderasn_exists = False -else: - pyderasn_exists = True - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestSigned(TestCase): - """SignedData test vectors from "Использование - алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 в - криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms( - self, - content_info_raw, - prv_key_raw, - curve_name, - hasher, - ): - content_info, tail = ContentInfo().decode(content_info_raw) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, signed_data = content_info["content"].defined - self.assertEqual(len(signed_data["signerInfos"]), 1) - curve = CURVES[curve_name] - self.assertTrue(verify( - curve, - public_key(curve, prv_unmarshal(prv_key_raw)), - hasher(bytes(signed_data["encapContentInfo"]["eContent"])).digest()[::-1], - bytes(signed_data["signerInfos"][0]["signature"]), - )) - - def test_256(self): - content_info_raw = b64decode(""" -MIIBBQYJKoZIhvcNAQcCoIH3MIH0AgEBMQ4wDAYIKoUDBwEBAgIFADAbBgkqhkiG -9w0BBwGgDgQMVGVzdCBtZXNzYWdlMYHBMIG+AgEBMFswVjEpMCcGCSqGSIb3DQEJ -ARYaR29zdFIzNDEwLTIwMTJAZXhhbXBsZS5jb20xKTAnBgNVBAMTIEdvc3RSMzQx -MC0yMDEyICgyNTYgYml0KSBleGFtcGxlAgEBMAwGCCqFAwcBAQICBQAwDAYIKoUD -BwEBAQEFAARAkptb2ekZbC94FaGDQeP70ExvTkXtOY9zgz3cCco/hxPhXUVo3eCx -VNwDQ8enFItJZ8DEX4blZ8QtziNCMl5HbA== - """) - prv_key_raw = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - self.process_cms( - content_info_raw, - prv_key_raw, - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - GOST34112012256, - ) - - def test_512(self): - content_info_raw = b64decode(""" -MIIBSQYJKoZIhvcNAQcCoIIBOjCCATYCAQExDjAMBggqhQMHAQECAwUAMBsGCSqG -SIb3DQEHAaAOBAxUZXN0IG1lc3NhZ2UxggECMIH/AgEBMFswVjEpMCcGCSqGSIb3 -DQEJARYaR29zdFIzNDEwLTIwMTJAZXhhbXBsZS5jb20xKTAnBgNVBAMTIEdvc3RS -MzQxMC0yMDEyICg1MTIgYml0KSBleGFtcGxlAgEBMAwGCCqFAwcBAQIDBQAwDAYI -KoUDBwEBAQIFAASBgFyVohNhMHUi/+RAF3Gh/cC7why6v+4jPWVlx1TYlXtV8Hje -hI2Y+rP52/LO6EUHG/XcwCBbUxmRWsbUSRRBAexmaafkSdvv2FFwC8kHOcti+UPX -PS+KRYxT8vhcsBLWWxDkc1McI7aF09hqtED36mQOfACzeJjEoUjALpmJob1V - """) - prv_key_raw = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - self.process_cms( - content_info_raw, - prv_key_raw, - "id-tc26-gost-3410-12-512-paramSetB", - GOST34112012512, - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestDigested(TestCase): - """DigestedData test vectors from "Использование - алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 в - криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms(self, content_info_raw, hasher): - content_info, tail = ContentInfo().decode(content_info_raw) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, digested_data = content_info["content"].defined - self.assertSequenceEqual( - hasher(bytes(digested_data["encapContentInfo"]["eContent"])).digest(), - bytes(digested_data["digest"]), - ) - - def test_256(self): - content_info_raw = b64decode(""" -MIGdBgkqhkiG9w0BBwWggY8wgYwCAQAwDAYIKoUDBwEBAgIFADBXBgkqhkiG9w0B -BwGgSgRI0eUg4uXy8OgsINHy8Ojh7uboIOLt8/boLCDi5f7y+iDxIOzu8P8g8fLw -5evg7Ogg7eAg9fDg4fD7/yDv6/rq+yDI4+7w5eL7BCCd0v5OkECeXah/U5dtdAWw -wMrGKPxmmnQdUAY8VX6PUA== - """) - self.process_cms(content_info_raw, GOST34112012256) - - def test_512(self): - content_info_raw = b64decode(""" -MIG0BgkqhkiG9w0BBwWggaYwgaMCAQAwDAYIKoUDBwEBAgMFADBOBgkqhkiG9w0B -BwGgQQQ/MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAx -MjM0NTY3ODkwMTIzNDU2Nzg5MDEyBEAbVNAaSvW51cw9htaNKFRisZq8JHUiLzXA -hRIr5Lof+gCtMPh2ezqCOExldPAkwxHipIEzKwjvf0F5eJHBZG9I - """) - self.process_cms(content_info_raw, GOST34112012512) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestEnvelopedKTRI(TestCase): - """EnvelopedData KeyTransRecipientInfo-based test vectors from - "Использование алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 - в криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms( - self, - content_info_raw, - prv_key_our, - curve_name, - keker, - plaintext_expected, - ): - sbox = "id-tc26-gost-28147-param-Z" - content_info, tail = ContentInfo().decode(content_info_raw, ctx={ - "defines_by_path": [ - ( - ( - "content", - DecodePathDefBy(id_envelopedData), - "recipientInfos", - any, - "ktri", - "encryptedKey", - DecodePathDefBy(spki_algorithm), - "transportParameters", - "ephemeralPublicKey", - "algorithm", - "algorithm", - ), - ( - ( - ("..", "subjectPublicKey"), - { - id_tc26_gost3410_2012_256: OctetString(), - id_tc26_gost3410_2012_512: OctetString(), - }, - ), - ), - ) for spki_algorithm in ( - id_tc26_gost3410_2012_256, - id_tc26_gost3410_2012_512, - ) - ], - }) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, enveloped_data = content_info["content"].defined - eci = enveloped_data["encryptedContentInfo"] - ri = enveloped_data["recipientInfos"][0] - self.assertIsNotNone(ri["ktri"]["encryptedKey"].defined) - _, encrypted_key = ri["ktri"]["encryptedKey"].defined - ukm = bytes(encrypted_key["transportParameters"]["ukm"]) - spk = encrypted_key["transportParameters"]["ephemeralPublicKey"]["subjectPublicKey"] - self.assertIsNotNone(spk.defined) - _, pub_key_their = spk.defined - curve = CURVES[curve_name] - kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) - key_wrapped = bytes(encrypted_key["sessionEncryptedKey"]["encryptedKey"]) - mac = bytes(encrypted_key["sessionEncryptedKey"]["macKey"]) - cek = unwrap_cryptopro(kek, ukm + key_wrapped + mac, sbox=sbox) - ciphertext = bytes(eci["encryptedContent"]) - self.assertIsNotNone(eci["contentEncryptionAlgorithm"]["parameters"].defined) - _, encryption_params = eci["contentEncryptionAlgorithm"]["parameters"].defined - iv = bytes(encryption_params["iv"]) - self.assertSequenceEqual( - cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), - plaintext_expected, - ) - - def test_256(self): - content_info_raw = b64decode(""" -MIIKGgYJKoZIhvcNAQcDoIIKCzCCCgcCAQAxggE0MIIBMAIBADBbMFYxKTAnBgkq -hkiG9w0BCQEWGkdvc3RSMzQxMC0yMDEyQGV4YW1wbGUuY29tMSkwJwYDVQQDEyBH -b3N0UjM0MTAtMjAxMiAyNTYgYml0cyBleGNoYW5nZQIBATAfBggqhQMHAQEBATAT -BgcqhQMCAiQABggqhQMHAQECAgSBrDCBqTAoBCCVJxUMdbKRzCJ5K1NWJIXnN7Ul -zaceeFlblA2qH4wZrgQEsHnIG6B9BgkqhQMHAQIFAQGgZjAfBggqhQMHAQEBATAT -BgcqhQMCAiQABggqhQMHAQECAgNDAARAFoqoLg1lV780co6GdwtjLtS4KCXv9VGR -sd7PTPHCT/5iGbvOlKNW2I8UhayJ0dv7RV7Nb1lDIxPxf4Mbp2CikgQI1b4+WpGE -sfQwggjIBgkqhkiG9w0BBwEwHwYGKoUDAgIVMBUECHYNkdvFoYdyBgkqhQMHAQIF -AQGAggiYvFFpJKILAFdXjcdLLYv4eruXzL/wOXL8y9HHIDMbSzV1GM033J5Yt/p4 -H6JYe1L1hjAfE/BAAYBndof2sSUxC3/I7xj+b7M8BZ3GYPqATPtR4aCQDK6z91lx -nDBAWx0HdsStT5TOj/plMs4zJDadvIJLfjmGkt0Np8FSnSdDPOcJAO/jcwiOPopg -+Z8eIuZNmY4seegTLue+7DGqvqi1GdZdMnvXBFIKc9m5DUsC7LdyboqKImh6giZE -YZnxb8a2naersPylhrf+zp4Piwwv808yOrD6LliXUiH0RojlmuaQP4wBkb7m073h -MeAWEWSvyXzOvOOuFST/hxPEupiTRoHPUdfboJT3tNpizUhE384SrvXHpwpgivQ4 -J0zF2/uzTBEupXR6dFC9rTHAK3X79SltqBNnHyIXBwe+BMqTmKTfnlPVHBUfTXZg -oakDItwKwa1MBOZeciwtUFza+7o9FZhKIandb848chGdgd5O9ksaXvPJDIPxQjZd -EBVhnXLlje4TScImwTdvYB8GsI8ljKb2bL3FjwQWGbPaOjXc2D9w+Ore8bk1E4TA -ayhypU7MH3Mq1EBZ4j0iROEFBQmYRZn8vAKZ0K7aPxcDeAnKAJxdokqrMkLgI6WX -0glh/3Cs9dI+0D2GqMSygauKCD0vTIo3atkEQswDZR4pMx88gB4gmx7iIGrc/ZXs -ZqHI7NQqeKtBwv2MCIj+/UTqdYDqbaniDwdVS8PE9nQnNU4gKffq3JbT+wRjJv6M -Dr231bQHgAsFTVKbZgoL4gj4V7bLQUmW06+W1BQUJ2+Sn7fp+Xet9Xd3cGtNdxzQ -zl6sGuiOlTNe0bfKP7QIMC7ekjflLBx8nwa2GZG19k3O0Z9JcDdN/kz6bGpPNssY -AIOkTvLQjxIM9MhRqIv6ee0rowTWQPwXJP7yHApop4XZvVX6h9gG2gazqbDej2lo -tAcfRAKj/LJ/bk9+OlNXOXVCKnwE1kXxZDsNJ51GdCungC56U/hmd3C1RhSLTpEc -FlOWgXKNjbn6SQrlq1yASKKr80T0fL7PFoYwKZoQbKMAVZQC1VBWQltHkEzdL73x -FwgZULNfdflF8sEhFC/zsVqckD/UnhzJz88PtCslMArJ7ntbEF1GzsSSfRfjBqnl -kSUreE5XX6+c9yp5HcJBiMzp6ZqqWWaED5Y5xp1hZeYjuKbDMfY4tbWVc7Hy0dD2 -KGfZLp5umqvPNs7aVBPmvuxtrnxcJlUB8u2HoiHc6/TuhrpaopYGBhxL9+kezuLR -v18nsAg8HOmcCNUS46NXQj/Mdpx8W+RsyzCQkJjieT/Yed20Zxq1zJoXIS0xAaUH -TdE2dWqiT6TGlh/KQYk3KyFPNnDmzJm04a2VWIwpp4ypXyxrB7XxnVY6Q4YBYbZs -FycxGjJWqj7lwc+lgZ8YV2WJ4snEo2os8SsA2GFWcUMiVTHDnEJvphDHmhWsf26A -bbRqwaRXNjhj05DamTRsczgvfjdl1pk4lJYE4ES3nixtMe4s1X8nSmM4KvfyVDul -J8uTpw1ZFnolTdfEL63BSf4FREoEqKB7cKuD7cpn7Rg4kRdM0/BLZGuxkH+pGMsI -Bb8LecUWyjGsI6h74Wz/U2uBrfgdRqhR+UsfB2QLaRgM6kCXZ4vM0auuzBViFCwK -tYMHzZWWz8gyVtJ0mzt1DrHCMx4pTS4yOhv4RkXBS/rub4VhVIsOGOGar5ZYtH47 -uBbdw3NC05JIFM7lI31d0s1fvvkTUR7eaqRW+SnR2c2oHpWlSO+Q0mrzx+vvOTdj -xa713YtklBvyUUQr2SIbsXGpFnwjn+sXK1onAavp/tEax8sNZvxg5yeseFcWn+gD -4rjk9FiSd1wp4fTDQFJ19evqruqKlq6k18l/ZAyUcEbIWSz2s3HfAAoAQyFPX1Q2 -95gVhRRw6lP4S6VPCfn/f+5jV4TcT6W/giRaHIk9Hty+g8bx1bFXaKVkQZ5R2Vmk -qsZ65ZgCrYQJmcErPmYybvP7NBeDS4AOSgBQAGMQF4xywdNm6bniWWo3N/xkFv32 -/25x8okGgD8QcYKmhzieLSSzOvM/exB14RO84YZOkZzm01Jll0nac/LEazKoVWbn -0VdcQ7pYEOqeMBXipsicNVYA/uhonp6op9cpIVYafPr0npCGwwhwcRuOrgSaZyCn -VG2tPkEOv9LKmUbhnaDA2YUSzOOjcCpIVvTSBnUEiorYpfRYgQLrbcd2qhVvNCLX -8ujZfMqXQXK8n5BK8JxNtczvaf+/2dfv1dQl0lHEAQhbNcsJ0t5GPhsSCC5oMBJl -ZJuOEO/8PBWKEnMZOM+Dz7gEgsBhGyMFFrKpiwQRpyEshSD2QpnK6Lp0t5C8Za2G -lhyZsEr+93AYOb5mm5+z02B4Yq9+RpepvjoqVeq/2uywZNq9MS98zVgNsmpryvTZ -3HJHHB20u2jcVu0G3Nhiv22lD70JWCYFAOupjgVcUcaBxjxwUMAvgHg7JZqs6mC6 -tvTKwQ4NtDhoAhARlDeWSwCWb2vPH2H7Lmqokif1RfvJ0hrLzkJuHdWrzIYzXpPs -+v9XJxLvbdKi9KU1Halq9S8dXT1fvs9DJTpUV/KW7QkRsTQJhTJBkQ07WUSJ4gBS -Qp4efxSRNIfMj7DR6qLLf13RpIPTJO9/+gNuBIFcupWVfUL7tJZt8Qsf9eGwZfP+ -YyhjC8AyZjH4/9RzLHSjuq6apgw3Mzw0j572Xg6xDLMK8C3Tn/vrLOvAd96b9MkF -3+ZHSLW3IgOiy+1jvK/20CZxNWc+pey8v4zji1hI17iohsipX/uZKRxhxF6+Xn2R -UQp6qoxHAspNXgWQ57xg7C3+gmi4ciVr0fT9pg54ogcowrRH+I6wd0EpeWPbzfnQ -pRmMVN+YtRsrEHwH3ToQ/i4vrtgA+eONuKT2uKZFikxA+VNmeeGdhkgqETMihQ== - """) - prv_key_our = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - keker, - b"Test data to encrypt.\n" * 100, - ) - - def test_512(self): - content_info_raw = b64decode(""" -MIIB0gYJKoZIhvcNAQcDoIIBwzCCAb8CAQAxggF8MIIBeAIBADBbMFYxKTAnBgkq -hkiG9w0BCQEWGkdvc3RSMzQxMC0yMDEyQGV4YW1wbGUuY29tMSkwJwYDVQQDEyBH -b3N0UjM0MTAtMjAxMiA1MTIgYml0cyBleGNoYW5nZQIBATAhBggqhQMHAQEBAjAV -BgkqhQMHAQIBAgIGCCqFAwcBAQIDBIHyMIHvMCgEIIsYzbVLn33aLinQ7SLNA7y+ -Lrm02khqDCfXrNS9iiMhBATerS8zoIHCBgkqhQMHAQIFAQGggaowIQYIKoUDBwEB -AQIwFQYJKoUDBwECAQICBggqhQMHAQECAwOBhAAEgYAYiTVLKpSGaAvjJEDQ0hdK -qR/jek5Q9Q2pXC+NkOimQh7dpCi+wcaHlPcBk96hmpnOFvLaiokX8V6jqtBl5gdk -M40kOXv8kcDdTzEVKA/ZLxA8xanL+gTD6ZjaPsUu06nsA2MoMBWcHLUzueaP3bGT -/yHTV+Za5xdcQehag/lNBgQIvCw4uUl0XC4wOgYJKoZIhvcNAQcBMB8GBiqFAwIC -FTAVBAj+1QzaXaN9FwYJKoUDBwECBQEBgAyK54euw0sHhEVEkA0= - """) - prv_key_our = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-tc26-gost-3410-12-512-paramSetB", - keker, - b"Test message", - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestEnvelopedKARI(TestCase): - """EnvelopedData KeyAgreeRecipientInfo-based test vectors from - "Использование алгоритмов ГОСТ 28147-89, ГОСТ Р 34.11 и ГОСТ Р 34.10 - в криптографических сообщениях формата CMS" (TK26CMS.pdf) - """ - - def process_cms( - self, - content_info_raw, - prv_key_our, - curve_name, - keker, - plaintext_expected, - ): - sbox = "id-tc26-gost-28147-param-Z" - content_info, tail = ContentInfo().decode(content_info_raw, ctx={ - "defines_by_path": [ - ( - ( - "content", - DecodePathDefBy(id_envelopedData), - "recipientInfos", - any, - "kari", - "originator", - "originatorKey", - "algorithm", - "algorithm", - ), - ( - ( - ("..", "publicKey"), - { - id_tc26_gost3410_2012_256: OctetString(), - id_tc26_gost3410_2012_512: OctetString(), - }, - ), - ), - ) for _ in ( - id_tc26_gost3410_2012_256, - id_tc26_gost3410_2012_512, - ) - ], - }) - self.assertSequenceEqual(tail, b"") - self.assertIsNotNone(content_info["content"].defined) - _, enveloped_data = content_info["content"].defined - eci = enveloped_data["encryptedContentInfo"] - kari = enveloped_data["recipientInfos"][0]["kari"] - self.assertIsNotNone(kari["originator"]["originatorKey"]["publicKey"].defined) - _, pub_key_their = kari["originator"]["originatorKey"]["publicKey"].defined - ukm = bytes(kari["ukm"]) - rek = kari["recipientEncryptedKeys"][0] - curve = CURVES[curve_name] - kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) - self.assertIsNotNone(rek["encryptedKey"].defined) - _, encrypted_key = rek["encryptedKey"].defined - key_wrapped = bytes(encrypted_key["encryptedKey"]) - mac = bytes(encrypted_key["macKey"]) - cek = unwrap_gost(kek, ukm + key_wrapped + mac, sbox=sbox) - ciphertext = bytes(eci["encryptedContent"]) - self.assertIsNotNone(eci["contentEncryptionAlgorithm"]["parameters"].defined) - _, encryption_params = eci["contentEncryptionAlgorithm"]["parameters"].defined - iv = bytes(encryption_params["iv"]) - self.assertSequenceEqual( - cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), - plaintext_expected, - ) - - def test_256(self): - content_info_raw = b64decode(""" -MIIBhgYJKoZIhvcNAQcDoIIBdzCCAXMCAQIxggEwoYIBLAIBA6BooWYwHwYIKoUD -BwEBAQEwEwYHKoUDAgIkAAYIKoUDBwEBAgIDQwAEQPAdWM4pO38iZ49UjaXQpq+a -jhTa4KwY4B9TFMK7AiYmbFKE0eX/wvu69kFMQ2o3OJTnMOlr1WHiPYOmNO6C5hOh -CgQIX+vNomZakEIwIgYIKoUDBwEBAQEwFgYHKoUDAgINADALBgkqhQMHAQIFAQEw -gYwwgYkwWzBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxl -LmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgMjU2IGJpdHMgZXhjaGFuZ2UC -AQEEKjAoBCCNhrZOr7x2fsjjQAeDMv/tSoNRQSSQzzxgqdnYxJ3fIAQEgYLqVDA6 -BgkqhkiG9w0BBwEwHwYGKoUDAgIVMBUECHVmR/S+hlYiBgkqhQMHAQIFAQGADEI9 -UNjyuY+54uVcHw== - """) - prv_key_our = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - keker, - b"Test message", - ) - - def test_512(self): - content_info_raw = b64decode(""" -MIIBzAYJKoZIhvcNAQcDoIIBvTCCAbkCAQIxggF2oYIBcgIBA6CBraGBqjAhBggq -hQMHAQEBAjAVBgkqhQMHAQIBAgIGCCqFAwcBAQIDA4GEAASBgCB0nQy/Ljva/mRj -w6o+eDKIvnxwYIQB5XCHhZhCpHNZiWcFxFpYXZLWRPKifOxV7NStvqGE1+fkfhBe -btkQu0tdC1XL3LO2Cp/jX16XhW/IP5rKV84qWr1Owy/6tnSsNRb+ez6IttwVvaVV -pA6ONFy9p9gawoC8nitvAVJkWW0PoQoECDVfxzxgMTAHMCIGCCqFAwcBAQECMBYG -ByqFAwICDQAwCwYJKoUDBwECBQEBMIGMMIGJMFswVjEpMCcGCSqGSIb3DQEJARYa -R29zdFIzNDEwLTIwMTJAZXhhbXBsZS5jb20xKTAnBgNVBAMTIEdvc3RSMzQxMC0y -MDEyIDUxMiBiaXRzIGV4Y2hhbmdlAgEBBCowKAQg8C/OcxRR0Uq8nDjHrQlayFb3 -WFUZEnEuAKcuG6dTOawEBLhi9hIwOgYJKoZIhvcNAQcBMB8GBiqFAwICFTAVBAiD -1wH+CX6CwgYJKoUDBwECBQEBgAzUvQI4H2zRfgNgdlY= - """) - prv_key_our = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - - def keker(curve, prv, pub, ukm): - return kek_34102012256( - curve, - prv_unmarshal(prv), - pub_unmarshal(pub), - ukm_unmarshal(ukm), - ) - - self.process_cms( - content_info_raw, - prv_key_our, - "id-tc26-gost-3410-12-512-paramSetB", - keker, - b"Test message", - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestR132356510252019(TestCase): - """Test vectors from Р 1323565.1.025-2019 - """ - def setUp(self): - self.curve256 = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - self.curve512 = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - self.psk = hexdec("8F5EEF8814D228FB2BBC5612323730CFA33DB7263CC2C0A01A6C6953F33D61D5")[::-1] - - self.ca_prv = prv_unmarshal(hexdec("092F8D059E97E22B90B1AE99F0087FC4D26620B91550CBB437C191005A290810")[::-1]) - self.ca_pub = public_key(self.curve256, self.ca_prv) - self.ca_cert = Certificate().decod(b64decode(""" -MIIB8DCCAZ2gAwIBAgIEAYy6gTAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA4MQ0wCwYDVQQKEwRUSzI2MScwJQYD -VQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwaDAhBggqhQMHAQEB -ATAVBgkqhQMHAQIBAQEGCCqFAwcBAQICA0MABEAaSoKcjw54UACci6svELNF0IYM -RIW8urUsqamIpoG46XCqrVOuI6Q13N4dwcRsbZdqByf+GC2f5ZfO3baN5bTKo4GF -MIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJjsCecS2npzESoTowODENMAsGA1UE -ChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0 -ggQBjLqBMB0GA1UdDgQWBBSA2Qz3mfhmTZNTiY7AnnEtp6cxEjAKBggqhQMHAQED -AgNBAAgv248F4OeNCkhlzJWec0evHYnMBlSzk1lDm0F875B7CqMrKh2MtJHXenbj -Gc2uRn2IwgmSf/LZDrYsKKqZSxk= -""")) - - self.sender256_prv = prv_unmarshal(hexdec("0B20810E449978C7C3B76C6FF77A16C532421139344A058EF56310B6B6F377E8")[::-1]) - self.sender256_pub = public_key(self.curve256, self.sender256_prv) - self.sender256_cert = Certificate().decod(b64decode(""" -MIIB8zCCAaCgAwIBAgIEAYy6gjAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYD -VQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwaDAhBggqhQMH -AQEBATAVBgkqhQMHAQIBAQEGCCqFAwcBAQICA0MABECWKQ0TYllqg4GmY3tBJiyz -pXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZhuJaJfqZ6VbT -o4GFMIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJjsCecS2npzESoTowODENMAsG -A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt -Yml0ggQBjLqBMB0GA1UdDgQWBBTRnChHSWbQYwnJC62n2zu5Njd03zAKBggqhQMH -AQEDAgNBAB41oijaXSEn58l78y2rhxY35/lKEq4XWZ70FtsNlVxWATyzgO5Wliwn -t1O4GoZsxx8r6T/i7VG65UNmQlwdOKQ= -""")) - - self.recipient256_prv = prv_unmarshal(hexdec("0DC8DC1FF2BC114BABC3F1CA8C51E4F58610427E197B1C2FBDBA4AE58CBFB7CE")[::-1]) - self.recipient256_pub = public_key(self.curve256, self.recipient256_prv) - self.recipient256_cert = Certificate().decod(b64decode(""" -MIIB8jCCAZ+gAwIBAgIEAYy6gzAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA6MQ0wCwYDVQQKEwRUSzI2MSkwJwYD -VQQDEyBSRUNJUElFTlQ6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdDBoMCEGCCqFAwcB -AQEBMBUGCSqFAwcBAgEBAQYIKoUDBwEBAgIDQwAEQL8nghlzLGMKWHuWhNMPMN5u -L6SkGqRiJ6qZxZb+4dPKbBT9LNVvNKtwUed+BeE5kfqOfolPgFusnL1rnO9yREOj -gYUwgYIwYQYDVR0BBFowWIAUgNkM95n4Zk2TU4mOwJ5xLaenMRKhOjA4MQ0wCwYD -VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1i -aXSCBAGMuoEwHQYDVR0OBBYEFLue+PUb9Oe+pziBU+MvNejjgrzFMAoGCCqFAwcB -AQMCA0EAPP9Oad1/5jwokSjPpccsQ0xCdVYM+mGQ0IbpiZxQj8gnkt8sq4jR6Ya+ -I/BDkbZNDNE27TU1p3t5rE9NMEeViA== -""")) - - self.sender512_prv = prv_unmarshal(hexdec("F95A5D44C5245F63F2E7DF8E782C1924EADCB8D06C52D91023179786154CBDB1561B4DF759D69F67EE1FBD5B68800E134BAA12818DA4F3AC75B0E5E6F9256911")[::-1]) - self.sender512_pub = public_key(self.curve512, self.sender512_prv) - self.sender512_cert = Certificate().decod(b64decode(""" -MIICNjCCAeOgAwIBAgIEAYy6hDAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYD -VQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDUxMi1iaXQwgaowIQYIKoUD -BwEBAQIwFQYJKoUDBwECAQIBBggqhQMHAQECAwOBhAAEgYC0i7davCkOGGVcYqFP -tS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO+K21LDpYVfDPs2Sqa13ZN+Ts -/JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0EmZf8T3ae/J1Jo6xGunecH1/G4 -hMts9HYLnxbwJDMNVGuIHV6gzqOBhTCBgjBhBgNVHQEEWjBYgBSA2Qz3mfhmTZNT -iY7AnnEtp6cxEqE6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6 -IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQUK+l9HAscONGx -zCcRpxRAmFHvlXowCgYIKoUDBwEBAwIDQQAbjA0Q41/rIKOOvjHKsAsoEJM+WJf6 -/PKXg2JaStthmw99bdtwwkU/qDbcje2tF6mt+XWyQBXwvfeES1GFY9fJ -""")) - - self.recipient512_prv = prv_unmarshal(hexdec("A50315981F0A7C7FC05B4EB9591A62B1F84BD6FD518ACFCEDF0A7C9CF388D1F18757C056ADA5B38CBF24CDDB0F1519EF72DB1712CEF1920952E94AF1F9C575DC")[::-1]) - self.recipient512_pub = public_key(self.curve512, self.recipient512_prv) - self.recipient512_cert = Certificate().decod(b64decode(""" -MIICNTCCAeKgAwIBAgIEAYy6hTAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 -MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw -MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA6MQ0wCwYDVQQKEwRUSzI2MSkwJwYD -VQQDEyBSRUNJUElFTlQ6IEdPU1QgMzQuMTAtMTIgNTEyLWJpdDCBqjAhBggqhQMH -AQEBAjAVBgkqhQMHAQIBAgEGCCqFAwcBAQIDA4GEAASBgKauwGYvUkzz19g0LP/p -zeRdmwy1m+QSy9W5ZrL/AGuJofm2ARjz40ozNbW6bp9hkHu8x66LX7u5zz+QeS2+ -X5om18UXriComgO0+qhZbc+Hzu0eQ8FjOd8LpLk3TzzfBltfLOX5IiPLjeum+pSP -0QjoXAVcrop//B4yvZIukvROo4GFMIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJ -jsCecS2npzESoTowODENMAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjog -R09TVCAzNC4xMC0xMiAyNTYtYml0ggQBjLqBMB0GA1UdDgQWBBSrXT5VKhm/5uff -kwW0XpG19k6AajAKBggqhQMHAQEDAgNBAAJBpsHRrQKZGb22LOzaReEB8rl2MbIR -ja64NaM5h+cAFoHm6t/k+ziLh2A11rTakR+5of4NQ3EjEhuPtomP2tc= -""")) - - def test_certs(self): - """Certificates signatures - """ - for prv, pub, curve, cert in ( - (self.ca_prv, self.ca_pub, self.curve256, self.ca_cert), - (self.sender256_prv, self.sender256_pub, self.curve256, self.sender256_cert), - (self.recipient256_prv, self.recipient256_pub, self.curve256, self.recipient256_cert), - (self.sender512_prv, self.sender512_pub, self.curve512, self.sender512_cert), - (self.recipient512_prv, self.recipient512_pub, self.curve512, self.recipient512_cert), - ): - pub_our = public_key(curve, prv) - self.assertEqual(pub_our, pub) - self.assertSequenceEqual( - pub_marshal(pub_our), - bytes(OctetString().decod(bytes( - cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - ))), - ) - - for cert in ( - self.ca_cert, - self.sender256_cert, - self.recipient256_cert, - self.sender512_cert, - self.recipient512_cert, - ): - self.assertTrue(verify( - self.curve256, - self.ca_pub, - GOST34112012256(cert["tbsCertificate"].encode()).digest()[::-1], - bytes(cert["signatureValue"]), - )) - - def test_signed_with_attrs(self): - ci = ContentInfo().decod(b64decode(""" -MIIENwYJKoZIhvcNAQcCoIIEKDCCBCQCAQExDDAKBggqhQMHAQECAzA7BgkqhkiG -9w0BBwGgLgQsyu7t8vDu6/zt++kg7/Do7OXwIOTr/yDx8vDz6vLz8PsgU2lnbmVk -RGF0YS6gggI6MIICNjCCAeOgAwIBAgIEAYy6hDAKBggqhQMHAQEDAjA4MQ0wCwYD -VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1i -aXQwHhcNMDEwMTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRU -SzI2MSowKAYDVQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDUxMi1iaXQw -gaowIQYIKoUDBwEBAQIwFQYJKoUDBwECAQIBBggqhQMHAQECAwOBhAAEgYC0i7da -vCkOGGVcYqFPtS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO+K21LDpYVfDP -s2Sqa13ZN+Ts/JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0EmZf8T3ae/J1Jo -6xGunecH1/G4hMts9HYLnxbwJDMNVGuIHV6gzqOBhTCBgjBhBgNVHQEEWjBYgBSA -2Qz3mfhmTZNTiY7AnnEtp6cxEqE6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMT -HkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQU -K+l9HAscONGxzCcRpxRAmFHvlXowCgYIKoUDBwEBAwIDQQAbjA0Q41/rIKOOvjHK -sAsoEJM+WJf6/PKXg2JaStthmw99bdtwwkU/qDbcje2tF6mt+XWyQBXwvfeES1GF -Y9fJMYIBlDCCAZACAQEwQDA4MQ0wCwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBU -SzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQCBAGMuoQwCgYIKoUDBwEBAgOgga0w -GAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzIw -MTk1NTIyWjAiBgkqhkiG9w0BCWIxFQQTU2lnbmVkIGF0dHIncyB2YWx1ZTBPBgkq -hkiG9w0BCQQxQgRAUdPHEukF5BIfo9DoQIMdnB0ZLkzq0RueEUZSNv07A7C+GKWi -G62fueArg8uPCHPTUN6d/42p33fgMkEwH7f7cDAKBggqhQMHAQEBAgSBgGUnVka8 -FvTlClmOtj/FUUacBdE/nEBeMLOO/535VDYrXlftPE6zQf/4ghS7TQG2VRGQ3GWD -+L3+W09A7d5uyyTEbvgtdllUG0OyqFwKmJEaYsMin87SFVs0cn1PGV1fOKeLluZa -bLx5whxd+mzlpekL5i6ImRX+TpERxrA/xSe5 -""")) - _, sd = ci["content"].defined - content = bytes(sd["encapContentInfo"]["eContent"]) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры SignedData."), - ) - si = sd["signerInfos"][0] - self.assertEqual( - si["digestAlgorithm"]["algorithm"], - id_tc26_gost3411_2012_512, - ) - digest = [ - bytes(attr["attrValues"][0].defined[1]) for attr in si["signedAttrs"] - if attr["attrType"] == id_messageDigest - ][0] - self.assertSequenceEqual(digest, GOST34112012512(content).digest()) - self.assertTrue(verify( - self.curve512, - self.sender512_pub, - GOST34112012512( - SignedAttributes(si["signedAttrs"]).encode() - ).digest()[::-1], - bytes(si["signature"]), - )) - - def test_signed_without_attrs(self): - ci = ContentInfo().decod(b64decode(""" -MIIDAQYJKoZIhvcNAQcCoIIC8jCCAu4CAQExDDAKBggqhQMHAQECAjA7BgkqhkiG -9w0BBwGgLgQsyu7t8vDu6/zt++kg7/Do7OXwIOTr/yDx8vDz6vLz8PsgU2lnbmVk -RGF0YS6gggH3MIIB8zCCAaCgAwIBAgIEAYy6gjAKBggqhQMHAQEDAjA4MQ0wCwYD -VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1i -aXQwHhcNMDEwMTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRU -SzI2MSowKAYDVQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQw -aDAhBggqhQMHAQEBATAVBgkqhQMHAQIBAQEGCCqFAwcBAQICA0MABECWKQ0TYllq -g4GmY3tBJiyzpXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZ -huJaJfqZ6VbTo4GFMIGCMGEGA1UdAQRaMFiAFIDZDPeZ+GZNk1OJjsCecS2npzES -oTowODENMAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4x -MC0xMiAyNTYtYml0ggQBjLqBMB0GA1UdDgQWBBTRnChHSWbQYwnJC62n2zu5Njd0 -3zAKBggqhQMHAQEDAgNBAB41oijaXSEn58l78y2rhxY35/lKEq4XWZ70FtsNlVxW -ATyzgO5Wliwnt1O4GoZsxx8r6T/i7VG65UNmQlwdOKQxgaIwgZ8CAQEwQDA4MQ0w -CwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1 -Ni1iaXQCBAGMuoIwCgYIKoUDBwEBAgIwCgYIKoUDBwEBAQEEQC6jZPA59szL9FiA -0wC71EBE42ap6gKxklT800cu2FvbLu972GJYNSI7+UeanVU37OVWyenEXi2E5HkU -94kBe8Q= -""")) - _, sd = ci["content"].defined - content = bytes(sd["encapContentInfo"]["eContent"]) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры SignedData."), - ) - si = sd["signerInfos"][0] - self.assertEqual( - si["digestAlgorithm"]["algorithm"], - id_tc26_gost3411_2012_256, - ) - self.assertTrue(verify( - self.curve256, - self.sender256_pub, - GOST34112012256(content).digest()[::-1], - bytes(si["signature"]), - )) - - def test_kari_ephemeral(self): - ci = ContentInfo().decod(b64decode(""" -MIIB/gYJKoZIhvcNAQcDoIIB7zCCAesCAQIxggFioYIBXgIBA6CBo6GBoDAXBggq -hQMHAQEBAjALBgkqhQMHAQIBAgEDgYQABIGAe+itJVNbHM35RHfzuwFJPYdPXqtW -8hNEF7Z/XFEE2T71SRkhFX7ozYKQNh/TkVY9D4vG0LnD9Znr/pJyOjpsNb+dPcKX -Kbk/0JQxoPGHxFzASVAFq0ov/yBe2XGFWMeKUqtaAr7SvoYS0oEhT5EuT8BXmecd -nRe7NqOzESpb15ahIgQgsqHxOcdOp03l11S7k3OH1k1HNa5F8m9ctrOzH2846FMw -FwYJKoUDBwEBBwIBMAoGCCqFAwcBAQYCMHYwdDBAMDgxDTALBgNVBAoTBFRLMjYx -JzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdAIEAYy6hQQw -SxLc18zMwzLwXbcKqYhV/VzsdBgVArOHsSBIbaThJWE7zI37VGPMQJM5VXJ7GVcL -MF0GCSqGSIb3DQEHATAfBgkqhQMHAQEFAgIwEgQQ6EeVlADDCz2cdEWKy+tM94Av -yIFl/Ie4VeFFuczTsMsIaOUEe3Jn9GeVp8hZSj3O2q4hslQ/u/+Gj4QkSHm/M0ih -ITAfBgkqhQMHAQAGAQExEgQQs1t6D3J3WCEvxunnEE15NQ== -""")) - _, ed = ci["content"].defined - kari = ed["recipientInfos"][0]["kari"] - orig_key = kari["originator"]["originatorKey"] - self.assertEqual(orig_key["algorithm"]["algorithm"], id_tc26_gost3410_2012_512) - self.assertEqual( - GostR34102012PublicKeyParameters().decod( - bytes(orig_key["algorithm"]["parameters"]) - )["publicKeyParamSet"], - id_tc26_gost3410_2012_512_paramSetA, - ) - orig_pub = pub_unmarshal( - bytes(OctetString().decod(bytes(orig_key["publicKey"]))), - ) - ukm = bytes(kari["ukm"]) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_wrap_kexp15, - ) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_512, - ) - kexp = bytes(kari["recipientEncryptedKeys"][0]["encryptedKey"]) - keymat = keg(self.curve512, self.recipient512_prv, orig_pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Kuznechik(kek).encrypt, - GOST3412Kuznechik(kim).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - ukm[24:24 + GOST3412Kuznechik.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm_omac, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - self.assertEqual(ed["unprotectedAttrs"][0]["attrType"], id_cms_mac_attr) - encrypted_mac = bytes(ed["unprotectedAttrs"][0]["attrValues"][0].defined[1]) - encrypted_content = bytes(eci["encryptedContent"]) - cek_enc, cek_mac = kdf_tree_gostr3411_2012_256( - cek, b"kdf tree", eci_ukm[GOST3412Kuznechik.blocksize // 2:], 2, - ) - content_and_tag = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(cek_enc).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - encrypted_content + encrypted_mac, - eci_ukm[:GOST3412Kuznechik.blocksize // 2], - ) - content = content_and_tag[:-GOST3412Kuznechik.blocksize] - tag_expected = content_and_tag[-GOST3412Kuznechik.blocksize:] - self.assertSequenceEqual( - omac( - GOST3412Kuznechik(cek_mac).encrypt, - GOST3412Kuznechik.blocksize, - content, - ), - tag_expected, - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_kari_static(self): - ci = ContentInfo().decod(b64decode(""" -MIIBawYJKoZIhvcNAQcDoIIBXDCCAVgCAQIxgfehgfQCAQOgQjBAMDgxDTALBgNV -BAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJp -dAIEAYy6gqEiBCBvcfyuSF57y8vVyaw8Z0ch3wjC4lPKTrpVRXty4Rhk5DAXBgkq -hQMHAQEHAQEwCgYIKoUDBwEBBgEwbjBsMEAwODENMAsGA1UEChMEVEsyNjEnMCUG -A1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0AgQBjLqDBChPbi6B -krXuLPexPAL2oUGCFWDGQHqINL5ExuMBG7/5XQRqriKARVa0MFkGCSqGSIb3DQEH -ATAbBgkqhQMHAQEFAQEwDgQMdNdCKnYAAAAwqTEDgC9O2bYyTGQJ8WUQGq0zHwzX -L0jFhWHTF1tcAxYmd9pX5i89UwIxhtYqyjX1QHju2g== -""")) - _, ed = ci["content"].defined - kari = ed["recipientInfos"][0]["kari"] - ukm = bytes(kari["ukm"]) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_wrap_kexp15, - ) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_256, - ) - kexp = bytes(kari["recipientEncryptedKeys"][0]["encryptedKey"]) - keymat = keg( - self.curve256, - self.recipient256_prv, - self.sender256_pub, - ukm, - ) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Magma(kek).encrypt, - GOST3412Magma(kim).encrypt, - GOST3412Magma.blocksize, - kexp, - ukm[24:24 + GOST3412Magma.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_ctracpkm, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(cek).encrypt, - 8 * 1024, - GOST3412Magma.blocksize, - bytes(eci["encryptedContent"]), - eci_ukm[:GOST3412Magma.blocksize // 2], - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_ktri_256(self): - ci = ContentInfo().decod(b64decode(""" -MIIBlQYJKoZIhvcNAQcDoIIBhjCCAYICAQAxggEcMIIBGAIBADBAMDgxDTALBgNV -BAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJp -dAIEAYy6gzAXBgkqhQMHAQEHAgEwCgYIKoUDBwEBBgEEgbcwgbQEMFiMredFR3Mv -3g2wqyVXRnrhYEBMNFaqqgBpHwPQh3bF98tt9HZPxRDCww0OPfxeuTBeMBcGCCqF -AwcBAQEBMAsGCSqFAwcBAgEBAQNDAARAdFJ9ww+3ptvQiaQpizCldNYhl4DB1rl8 -Fx/2FIgnwssCbYRQ+UuRsTk9dfLLTGJG3JIEXKFxXWBgOrK965A5pAQg9f2/EHxG -DfetwCe1a6uUDCWD+wp5dYOpfkry8YRDEJgwXQYJKoZIhvcNAQcBMB8GCSqFAwcB -AQUCATASBBDUHNxmVclO/v3OaY9P7jxOgC+sD9CHGlEMRUpfGn6yfFDMExmYeby8 -LzdPJe1MkYV0qQgdC1zI3nQ7/4taf+4zRA== -""")) - _, ed = ci["content"].defined - ktri = ed["recipientInfos"][0]["ktri"] - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_wrap_kexp15, - ) - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_256, - ) - _, encrypted_key = ktri["encryptedKey"].defined - self.assertEqual( - encrypted_key["ephemeralPublicKey"]["algorithm"]["algorithm"], - id_tc26_gost3410_2012_256, - ) - pub = pub_unmarshal(bytes(OctetString().decod( - bytes(encrypted_key["ephemeralPublicKey"]["subjectPublicKey"]) - ))) - ukm = bytes(encrypted_key["ukm"]) - kexp = bytes(encrypted_key["encryptedKey"]) - keymat = keg(self.curve256, self.recipient256_prv, pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Kuznechik(kek).encrypt, - GOST3412Kuznechik(kim).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - ukm[24:24 + GOST3412Kuznechik.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(cek).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - bytes(eci["encryptedContent"]), - eci_ukm[:GOST3412Kuznechik.blocksize // 2], - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_ktri_512(self): - ci = ContentInfo().decod(b64decode(""" -MIIB5wYJKoZIhvcNAQcDoIIB2DCCAdQCAQAxggFXMIIBUwIBADBAMDgxDTALBgNVBAoTBFRL -MjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdAIEAYy6hTAXBgkq -hQMHAQEHAQEwCgYIKoUDBwEBBgIEgfIwge8EKDof9JLTJVuIfP+c+imDCGyOLtAYENkoXpeU -CdiGn0Lt65t3TN9G0bUwgaAwFwYIKoUDBwEBAQIwCwYJKoUDBwECAQIBA4GEAASBgDD9XXHn -0j4EwY3DGB1wzHeThPRDlCwIvpmqWy00QDhS3fLRWiETSe9uMLeg27zI/EiserKMasNZum/i -d09cmP8aTNIDNRtI5H9M0mH7LpEtY8L901MszvOKHLDYdemvz0JUqOvBtvoeQ6sV4Gl45zXx -HTzBWlBw1FLX/ITWLapaBCAa09foTeA+PObBznGuCOPoKy+xz/9IIVmZidI6EYkIrzBZBgkq -hkiG9w0BBwEwGwYJKoUDBwEBBQECMA4EDA4z1UwRL4WYzKFX/oAv8eEX3fWt6hxDpjO0rI7/ -CiJ/CwYGCKODJ9h63vAwlsWwcPwAjxcsLvCNlv6i4NqhGTAXBgkqhQMHAQAGAQExCgQIs2DT -LuZ22Yw= -""")) - _, ed = ci["content"].defined - ktri = ed["recipientInfos"][0]["ktri"] - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_wrap_kexp15, - ) - self.assertEqual( - ktri["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_512, - ) - _, encrypted_key = ktri["encryptedKey"].defined - self.assertEqual( - encrypted_key["ephemeralPublicKey"]["algorithm"]["algorithm"], - id_tc26_gost3410_2012_512, - ) - pub = pub_unmarshal( - bytes(OctetString().decod( - bytes(encrypted_key["ephemeralPublicKey"]["subjectPublicKey"]) - )), - ) - ukm = bytes(encrypted_key["ukm"]) - kexp = bytes(encrypted_key["encryptedKey"]) - keymat = keg(self.curve512, self.recipient512_prv, pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Magma(kek).encrypt, - GOST3412Magma(kim).encrypt, - GOST3412Magma.blocksize, - kexp, - ukm[24:24 + GOST3412Magma.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_ctracpkm_omac, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - self.assertEqual(ed["unprotectedAttrs"][0]["attrType"], id_cms_mac_attr) - encrypted_mac = bytes(ed["unprotectedAttrs"][0]["attrValues"][0].defined[1]) - encrypted_content = bytes(eci["encryptedContent"]) - cek_enc, cek_mac = kdf_tree_gostr3411_2012_256( - cek, b"kdf tree", eci_ukm[GOST3412Magma.blocksize // 2:], 2, - ) - content_and_tag = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(cek_enc).encrypt, - 8 * 1024, - GOST3412Magma.blocksize, - encrypted_content + encrypted_mac, - eci_ukm[:GOST3412Magma.blocksize // 2], - ) - content = content_and_tag[:-GOST3412Magma.blocksize] - tag_expected = content_and_tag[-GOST3412Magma.blocksize:] - self.assertSequenceEqual( - omac( - GOST3412Magma(cek_mac).encrypt, - GOST3412Magma.blocksize, - content, - ), - tag_expected, - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EnvelopedData."), - ) - - def test_digested256(self): - ci = ContentInfo().decod(b64decode(""" -MH0GCSqGSIb3DQEHBaBwMG4CAQAwCgYIKoUDBwEBAgIwOwYJKoZIhvcNAQcBoC4ELMru7fLw -7uv87fvpIO/w6Ozl8CDk6/8g8fLw8+ry8/D7IERpZ2VzdERhdGEuBCD/esPQYsGkzxZV8uUM -IAWt6SI8KtxBP8NyG8AGbJ8i/Q== -""")) - _, dd = ci["content"].defined - eci = dd["encapContentInfo"] - self.assertSequenceEqual( - GOST34112012256(bytes(eci["eContent"])).digest(), - bytes(dd["digest"]), - ) - - def test_digested512(self): - ci = ContentInfo().decod(b64decode(""" -MIGfBgkqhkiG9w0BBwWggZEwgY4CAQAwCgYIKoUDBwEBAgMwOwYJKoZIhvcNAQcBoC4ELMru -7fLw7uv87fvpIO/w6Ozl8CDk6/8g8fLw8+ry8/D7IERpZ2VzdERhdGEuBEDe4VUvcKSRvU7R -FVhFjajXY+nJSUkUsoi3oOeJBnru4PErt8RusPrCJs614ciHCM+ehrC4a+M1Nbq77F/Wsa/v -""")) - _, dd = ci["content"].defined - eci = dd["encapContentInfo"] - self.assertSequenceEqual( - GOST34112012512(bytes(eci["eContent"])).digest(), - bytes(dd["digest"]), - ) - - def test_encrypted_kuznechik(self): - ci = ContentInfo().decod(b64decode(""" -MHEGCSqGSIb3DQEHBqBkMGICAQAwXQYJKoZIhvcNAQcBMB8GCSqFAwcBAQUCATASBBBSwX+z -yOEPPuGyfpsRG4AigC/P8ftTdQMStfIThVkE/vpJlwaHgGv83m2bsPayeyuqpoTeEMOaqGcO -0MxHWsC9hQ== -""")) - _, ed = ci["content"].defined - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm, - ) - ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(self.psk).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - bytes(eci["encryptedContent"]), - ukm[:GOST3412Kuznechik.blocksize // 2], - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EncryptedData."), - ) - - def test_encrypted_magma(self): - ci = ContentInfo().decod(b64decode(""" -MIGIBgkqhkiG9w0BBwagezB5AgEAMFkGCSqGSIb3DQEHATAbBgkqhQMHAQEFAQIwDgQMuncO -u3uYPbI30vFCgC9Nsws4R09yLp6jUtadncWUPZGmCGpPKnXGgNHvEmUArgKJvu4FPHtLkHuL -eQXZg6EZMBcGCSqFAwcBAAYBATEKBAjCbQoH632oGA== -""")) - _, ed = ci["content"].defined - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_magma_ctracpkm_omac, - ) - ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - self.assertEqual(ed["unprotectedAttrs"][0]["attrType"], id_cms_mac_attr) - encrypted_mac = bytes(ed["unprotectedAttrs"][0]["attrValues"][0].defined[1]) - cek_enc, cek_mac = kdf_tree_gostr3411_2012_256( - self.psk, b"kdf tree", ukm[GOST3412Magma.blocksize // 2:], 2, - ) - content_and_tag = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(cek_enc).encrypt, - 8 * 1024, - GOST3412Magma.blocksize, - bytes(eci["encryptedContent"]) + encrypted_mac, - ukm[:GOST3412Magma.blocksize // 2], - ) - content = content_and_tag[:-GOST3412Magma.blocksize] - tag_expected = content_and_tag[-GOST3412Magma.blocksize:] - self.assertSequenceEqual( - omac( - GOST3412Magma(cek_mac).encrypt, - GOST3412Magma.blocksize, - content, - ), - tag_expected, - ) - self.assertEqual( - content.decode("cp1251"), - text_type(u"Контрольный пример для структуры EncryptedData."), - ) diff --git a/pygost-5.13/pygost/test_gost28147.py b/pygost-5.13/pygost/test_gost28147.py deleted file mode 100644 index a83e930..0000000 --- a/pygost-5.13/pygost/test_gost28147.py +++ /dev/null @@ -1,384 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost28147 import block2ns -from pygost.gost28147 import BLOCKSIZE -from pygost.gost28147 import cbc_decrypt -from pygost.gost28147 import cbc_encrypt -from pygost.gost28147 import cfb_decrypt -from pygost.gost28147 import cfb_encrypt -from pygost.gost28147 import cnt -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost28147 import ecb_decrypt -from pygost.gost28147 import ecb_encrypt -from pygost.gost28147 import encrypt -from pygost.gost28147 import KEYSIZE -from pygost.gost28147 import MESH_MAX_DATA -from pygost.gost28147 import ns2block -from pygost.utils import hexdec -from pygost.utils import strxor - - -class ECBTest(TestCase): - def test_gcl(self): - """Test vectors from libgcl3 - """ - sbox = "id-Gost28147-89-TestParamSet" - key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd") - plaintext = bytes(bytearray(( - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, - 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, - 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, - 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, - 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, - 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, - 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, - 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, - 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, - 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, - 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, - 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, - 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, - 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, - 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, - 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, - 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0, - 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8, - 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0, - 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8, - 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, - 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, - 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, - 0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8, - 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, - 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, - ))) - ciphertext = bytes(bytearray(( - 0x4b, 0x8c, 0x4c, 0x98, 0x15, 0xf2, 0x4a, 0xea, - 0x1e, 0xc3, 0x57, 0x09, 0xb3, 0xbc, 0x2e, 0xd1, - 0xe0, 0xd1, 0xf2, 0x22, 0x65, 0x2d, 0x59, 0x18, - 0xf7, 0xdf, 0xfc, 0x80, 0x4b, 0xde, 0x5c, 0x68, - 0x46, 0x53, 0x75, 0x53, 0xa7, 0x46, 0x0d, 0xec, - 0x05, 0x1f, 0x1b, 0xd3, 0x0a, 0x63, 0x1a, 0xb7, - 0x78, 0xc4, 0x43, 0xe0, 0x5d, 0x3e, 0xa4, 0x0e, - 0x2d, 0x7e, 0x23, 0xa9, 0x1b, 0xc9, 0x02, 0xbc, - 0x21, 0x0c, 0x84, 0xcb, 0x0d, 0x0a, 0x07, 0xc8, - 0x7b, 0xd0, 0xfb, 0xb5, 0x1a, 0x14, 0x04, 0x5c, - 0xa2, 0x53, 0x97, 0x71, 0x2e, 0x5c, 0xc2, 0x8f, - 0x39, 0x3f, 0x6f, 0x52, 0xf2, 0x30, 0x26, 0x4e, - 0x8c, 0xe0, 0xd1, 0x01, 0x75, 0x6d, 0xdc, 0xd3, - 0x03, 0x79, 0x1e, 0xca, 0xd5, 0xc1, 0x0e, 0x12, - 0x53, 0x0a, 0x78, 0xe2, 0x0a, 0xb1, 0x1c, 0xea, - 0x3a, 0xf8, 0x55, 0xb9, 0x7c, 0xe1, 0x0b, 0xba, - 0xa0, 0xc8, 0x96, 0xeb, 0x50, 0x5a, 0xd3, 0x60, - 0x43, 0xa3, 0x0f, 0x98, 0xdb, 0xd9, 0x50, 0x6d, - 0x63, 0x91, 0xaf, 0x01, 0x40, 0xe9, 0x75, 0x5a, - 0x46, 0x5c, 0x1f, 0x19, 0x4a, 0x0b, 0x89, 0x9b, - 0xc4, 0xf6, 0xf8, 0xf5, 0x2f, 0x87, 0x3f, 0xfa, - 0x26, 0xd4, 0xf8, 0x25, 0xba, 0x1f, 0x98, 0x82, - 0xfc, 0x26, 0xaf, 0x2d, 0xc0, 0xf9, 0xc4, 0x58, - 0x49, 0xfa, 0x09, 0x80, 0x02, 0x62, 0xa4, 0x34, - 0x2d, 0xcb, 0x5a, 0x6b, 0xab, 0x61, 0x5d, 0x08, - 0xd4, 0x26, 0xe0, 0x08, 0x13, 0xd6, 0x2e, 0x02, - 0x2a, 0x37, 0xe8, 0xd0, 0xcf, 0x36, 0xf1, 0xc7, - 0xc0, 0x3f, 0x9b, 0x21, 0x60, 0xbd, 0x29, 0x2d, - 0x2e, 0x01, 0x48, 0x4e, 0xf8, 0x8f, 0x20, 0x16, - 0x8a, 0xbf, 0x82, 0xdc, 0x32, 0x7a, 0xa3, 0x18, - 0x69, 0xd1, 0x50, 0x59, 0x31, 0x91, 0xf2, 0x6c, - 0x5a, 0x5f, 0xca, 0x58, 0x9a, 0xb2, 0x2d, 0xb2, - ))) - encrypted = ecb_encrypt(key, plaintext, sbox=sbox) - self.assertSequenceEqual(encrypted, ciphertext) - decrypted = ecb_decrypt(key, encrypted, sbox=sbox) - self.assertSequenceEqual(decrypted, plaintext) - - def test_cryptopp(self): - """Test vectors from Crypto++ 5.6.2 - """ - sbox = "AppliedCryptography" - data = ( - (b"BE5EC2006CFF9DCF52354959F1FF0CBFE95061B5A648C10387069C25997C0672", b"0DF82802B741A292", b"07F9027DF7F7DF89"), - (b"B385272AC8D72A5A8B344BC80363AC4D09BF58F41F540624CBCB8FDCF55307D7", b"1354EE9C0A11CD4C", b"4FB50536F960A7B1"), - (b"AEE02F609A35660E4097E546FD3026B032CD107C7D459977ADF489BEF2652262", b"6693D492C4B0CC39", b"670034AC0FA811B5"), - (b"320E9D8422165D58911DFC7D8BBB1F81B0ECD924023BF94D9DF7DCF7801240E0", b"99E2D13080928D79", b"8118FF9D3B3CFE7D"), - (b"C9F703BBBFC63691BFA3B7B87EA8FD5E8E8EF384EF733F1A61AEF68C8FFA265F", b"D1E787749C72814C", b"A083826A790D3E0C"), - (b"728FEE32F04B4C654AD7F607D71C660C2C2670D7C999713233149A1C0C17A1F0", b"D4C05323A4F7A7B5", b"4D1F2E6B0D9DE2CE"), - (b"35FC96402209500FCFDEF5352D1ABB038FE33FC0D9D58512E56370B22BAA133B", b"8742D9A05F6A3AF6", b"2F3BB84879D11E52"), - (b"D416F630BE65B7FE150656183370E07018234EE5DA3D89C4CE9152A03E5BFB77", b"F86506DA04E41CB8", b"96F0A5C77A04F5CE"), - ) - for key, pt, ct in data: - key = hexdec(key) - pt = hexdec(pt) - ct = hexdec(ct) - self.assertSequenceEqual(ecb_encrypt(key, pt, sbox=sbox), ct) - - def test_cryptomanager(self): - """Test vector from http://cryptomanager.com/tv.html - """ - sbox = "id-GostR3411-94-TestParamSet" - key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B") - self.assertSequenceEqual( - ecb_encrypt(key, hexdec(b"1122334455667788"), sbox=sbox), - hexdec(b"03251E14F9D28ACB"), - ) - - -class CFBTest(TestCase): - def test_cryptomanager(self): - """Test vector from http://cryptomanager.com/tv.html - """ - key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B") - sbox = "id-GostR3411-94-TestParamSet" - self.assertSequenceEqual( - cfb_encrypt( - key, - hexdec(b"112233445566778899AABBCCDD800000"), - iv=hexdec(b"0102030405060708"), - sbox=sbox, - ), - hexdec(b"6EE84586DD2BCA0CAD3616940E164242"), - ) - self.assertSequenceEqual( - cfb_decrypt( - key, - hexdec(b"6EE84586DD2BCA0CAD3616940E164242"), - iv=hexdec(b"0102030405060708"), - sbox=sbox, - ), - hexdec(b"112233445566778899AABBCCDD800000"), - ) - - def test_steps(self): - """Check step-by-step operation manually - """ - key = urandom(KEYSIZE) - iv = urandom(BLOCKSIZE) - plaintext = urandom(20) - ciphertext = cfb_encrypt(key, plaintext, iv) - - # First full block - step = encrypt(DEFAULT_SBOX, key, block2ns(iv)) - step = strxor(plaintext[:8], ns2block(step)) - self.assertSequenceEqual(step, ciphertext[:8]) - - # Second full block - step = encrypt(DEFAULT_SBOX, key, block2ns(step)) - step = strxor(plaintext[8:16], ns2block(step)) - self.assertSequenceEqual(step, ciphertext[8:16]) - - # Third non-full block - step = encrypt(DEFAULT_SBOX, key, block2ns(step)) - step = strxor(plaintext[16:] + 4 * b"\x00", ns2block(step)) - self.assertSequenceEqual(step[:4], ciphertext[16:]) - - def test_random(self): - """Random data with various sizes - """ - key = urandom(KEYSIZE) - iv = urandom(BLOCKSIZE) - for size in (5, 8, 16, 120): - pt = urandom(size) - self.assertSequenceEqual( - cfb_decrypt(key, cfb_encrypt(key, pt, iv), iv), - pt, - ) - - -class CTRTest(TestCase): - def test_gcl(self): - """Test vectors from libgcl3 - """ - sbox = "id-Gost28147-89-TestParamSet" - key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd") - plaintext = bytes(bytearray(( - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, - 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, - 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, - 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, - 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, - 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, - 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, - 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, - 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, - 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, - 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, - 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, - 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, - 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, - 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, - 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, - 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0, - 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8, - 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0, - 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8, - 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, - 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, - 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, - 0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8, - 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, - 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0xff, 0xfe, 0xfd, 0xfc, 0xfb, - ))) - ciphertext = bytes(bytearray(( - 0x4a, 0x5e, 0x37, 0x6c, 0xa1, 0x12, 0xd3, 0x55, - 0x09, 0x13, 0x1a, 0x21, 0xac, 0xfb, 0xb2, 0x1e, - 0x8c, 0x24, 0x9b, 0x57, 0x20, 0x68, 0x46, 0xd5, - 0x23, 0x2a, 0x26, 0x35, 0x12, 0x56, 0x5c, 0x69, - 0x2a, 0x2f, 0xd1, 0xab, 0xbd, 0x45, 0xdc, 0x3a, - 0x1a, 0xa4, 0x57, 0x64, 0xd5, 0xe4, 0x69, 0x6d, - 0xb4, 0x8b, 0xf1, 0x54, 0x78, 0x3b, 0x10, 0x8f, - 0x7a, 0x4b, 0x32, 0xe0, 0xe8, 0x4c, 0xbf, 0x03, - 0x24, 0x37, 0x95, 0x6a, 0x55, 0xa8, 0xce, 0x6f, - 0x95, 0x62, 0x12, 0xf6, 0x79, 0xe6, 0xf0, 0x1b, - 0x86, 0xef, 0x36, 0x36, 0x05, 0xd8, 0x6f, 0x10, - 0xa1, 0x41, 0x05, 0x07, 0xf8, 0xfa, 0xa4, 0x0b, - 0x17, 0x2c, 0x71, 0xbc, 0x8b, 0xcb, 0xcf, 0x3d, - 0x74, 0x18, 0x32, 0x0b, 0x1c, 0xd2, 0x9e, 0x75, - 0xba, 0x3e, 0x61, 0xe1, 0x61, 0x96, 0xd0, 0xee, - 0x8f, 0xf2, 0x9a, 0x5e, 0xb7, 0x7a, 0x15, 0xaa, - 0x4e, 0x1e, 0x77, 0x7c, 0x99, 0xe1, 0x41, 0x13, - 0xf4, 0x60, 0x39, 0x46, 0x4c, 0x35, 0xde, 0x95, - 0xcc, 0x4f, 0xd5, 0xaf, 0xd1, 0x4d, 0x84, 0x1a, - 0x45, 0xc7, 0x2a, 0xf2, 0x2c, 0xc0, 0xb7, 0x94, - 0xa3, 0x08, 0xb9, 0x12, 0x96, 0xb5, 0x97, 0x99, - 0x3a, 0xb7, 0x0c, 0x14, 0x56, 0xb9, 0xcb, 0x49, - 0x44, 0xa9, 0x93, 0xa9, 0xfb, 0x19, 0x10, 0x8c, - 0x6a, 0x68, 0xe8, 0x7b, 0x06, 0x57, 0xf0, 0xef, - 0x88, 0x44, 0xa6, 0xd2, 0x98, 0xbe, 0xd4, 0x07, - 0x41, 0x37, 0x45, 0xa6, 0x71, 0x36, 0x76, 0x69, - 0x4b, 0x75, 0x15, 0x33, 0x90, 0x29, 0x6e, 0x33, - 0xcb, 0x96, 0x39, 0x78, 0x19, 0x2e, 0x96, 0xf3, - 0x49, 0x4c, 0x89, 0x3d, 0xa1, 0x86, 0x82, 0x00, - 0xce, 0xbd, 0x54, 0x29, 0x65, 0x00, 0x1d, 0x16, - 0x13, 0xc3, 0xfe, 0x1f, 0x8c, 0x55, 0x63, 0x09, - 0x1f, 0xcd, 0xd4, 0x28, 0xca, - ))) - iv = b"\x02\x01\x01\x01\x01\x01\x01\x01" - encrypted = cnt(key, plaintext, iv=iv, sbox=sbox) - self.assertSequenceEqual(encrypted, ciphertext) - decrypted = cnt(key, encrypted, iv=iv, sbox=sbox) - self.assertSequenceEqual(decrypted, plaintext) - - def test_gcl2(self): - """Test vectors 2 from libgcl3 - """ - sbox = "id-Gost28147-89-TestParamSet" - key = hexdec(b"fc7ad2886f455b50d29008fa622b57d5c65b3c637202025799cadf0768519e8a") - plaintext = bytes(bytearray(( - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, - 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, - 0xff, 0xfe, 0xfd, 0xfc, 0xfb, - ))) - ciphertext = bytes(bytearray(( - 0xd0, 0xbe, 0x60, 0x1a, 0x2c, 0xf1, 0x90, 0x26, - 0x9b, 0x7b, 0x23, 0xb4, 0xd2, 0xcc, 0xe1, 0x15, - 0xf6, 0x05, 0x57, 0x28, 0x88, 0x75, 0xeb, 0x1e, - 0xd3, 0x62, 0xdc, 0xda, 0x9b, 0x62, 0xee, 0x9a, - 0x57, 0x87, 0x8a, 0xf1, 0x82, 0x37, 0x9c, 0x7f, - 0x13, 0xcc, 0x55, 0x38, 0xb5, 0x63, 0x32, 0xc5, - 0x23, 0xa4, 0xcb, 0x7d, 0x51, - ))) - iv = BLOCKSIZE * b"\x00" - encrypted = cnt(key, plaintext, iv=iv, sbox=sbox) - self.assertSequenceEqual(encrypted, ciphertext) - decrypted = cnt(key, encrypted, iv=iv, sbox=sbox) - self.assertSequenceEqual(decrypted, plaintext) - - -class CBCTest(TestCase): - def test_pad_requirement(self): - key = KEYSIZE * b"x" - for s in (b"", b"foo", b"foobarbaz"): - with self.assertRaises(ValueError): - cbc_encrypt(key, s, pad=False) - with self.assertRaises(ValueError): - cbc_decrypt(key, s, pad=False) - - def test_passes(self): - iv = urandom(BLOCKSIZE) - key = KEYSIZE * b"x" - for pt in (b"foo", b"foobarba", b"foobarbaz", 16 * b"x"): - ct = cbc_encrypt(key, pt, iv) - dt = cbc_decrypt(key, ct) - self.assertSequenceEqual(pt, dt) - - def test_iv_existence_check(self): - key = KEYSIZE * b"x" - with self.assertRaises(ValueError): - cbc_decrypt(key, BLOCKSIZE * b"x") - iv = urandom(BLOCKSIZE) - cbc_decrypt(key, cbc_encrypt(key, BLOCKSIZE * b"x", iv)) - - def test_meshing(self): - pt = urandom(MESH_MAX_DATA * 3) - key = urandom(KEYSIZE) - ct = cbc_encrypt(key, pt) - dt = cbc_decrypt(key, ct) - self.assertSequenceEqual(pt, dt) - - -class CFBMeshingTest(TestCase): - def setUp(self): - self.key = urandom(KEYSIZE) - self.iv = urandom(BLOCKSIZE) - - def test_single(self): - pt = b"\x00" - ct = cfb_encrypt(self.key, pt, mesh=True) - dec = cfb_decrypt(self.key, ct, mesh=True) - self.assertSequenceEqual(pt, dec) - - def test_short(self): - pt = urandom(MESH_MAX_DATA - 1) - ct = cfb_encrypt(self.key, pt, mesh=True) - dec = cfb_decrypt(self.key, ct, mesh=True) - dec_plain = cfb_decrypt(self.key, ct) - self.assertSequenceEqual(pt, dec) - self.assertSequenceEqual(pt, dec_plain) - - def test_short_iv(self): - pt = urandom(MESH_MAX_DATA - 1) - ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True) - dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True) - dec_plain = cfb_decrypt(self.key, ct, iv=self.iv) - self.assertSequenceEqual(pt, dec) - self.assertSequenceEqual(pt, dec_plain) - - def test_longer_iv(self): - pt = urandom(MESH_MAX_DATA * 3) - ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True) - dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True) - dec_plain = cfb_decrypt(self.key, ct, iv=self.iv) - self.assertSequenceEqual(pt, dec) - self.assertNotEqual(pt, dec_plain) diff --git a/pygost-5.13/pygost/test_gost28147_mac.py b/pygost-5.13/pygost/test_gost28147_mac.py deleted file mode 100644 index ec1af3f..0000000 --- a/pygost-5.13/pygost/test_gost28147_mac.py +++ /dev/null @@ -1,63 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import TestCase - -from pygost.gost28147_mac import MAC - - -class TestMAC(TestCase): - """Test vectors generated with libgcl3 library - """ - k = b"This is message\xFF length\x0032 bytes" - - def test_a(self): - self.assertSequenceEqual( - MAC(self.k, b"a").hexdigest(), - "bd5d3b5b2b7b57af", - ) - - def test_abc(self): - self.assertSequenceEqual( - MAC(self.k, b"abc").hexdigest(), - "28661e40805b1ff9", - ) - - def test_128U(self): - self.assertSequenceEqual( - MAC(self.k, 128 * b"U").hexdigest(), - "1a06d1bad74580ef", - ) - - def test_13x(self): - self.assertSequenceEqual( - MAC(self.k, 13 * b"x").hexdigest(), - "917ee1f1a668fbd3", - ) - - def test_parts(self): - m = MAC(self.k) - m.update(b"foo") - m.update(b"bar") - self.assertSequenceEqual(m.digest(), MAC(self.k, b"foobar").digest()) - - def test_copy(self): - m = MAC(self.k, b"foo") - c = m.copy() - m.update(b"barbaz") - c.update(b"bar") - c.update(b"baz") - self.assertSequenceEqual(m.digest(), c.digest()) diff --git a/pygost-5.13/pygost/test_gost3410.py b/pygost-5.13/pygost/test_gost3410.py deleted file mode 100644 index cd71535..0000000 --- a/pygost-5.13/pygost/test_gost3410.py +++ /dev/null @@ -1,495 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost3410 import CURVES -from pygost.gost3410 import GOST3410Curve -from pygost.gost3410 import prv_marshal -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410 import sign -from pygost.gost3410 import uv2xy -from pygost.gost3410 import verify -from pygost.gost3410 import xy2uv -from pygost.utils import bytes2long -from pygost.utils import hexdec -from pygost.utils import hexenc -from pygost.utils import long2bytes - - -class Test341001(TestCase): - def test_rfc(self): - """Test vector from :rfc:`5832` - """ - prv = bytes(bytearray(( - 0x7A, 0x92, 0x9A, 0xDE, 0x78, 0x9B, 0xB9, 0xBE, - 0x10, 0xED, 0x35, 0x9D, 0xD3, 0x9A, 0x72, 0xC1, - 0x1B, 0x60, 0x96, 0x1F, 0x49, 0x39, 0x7E, 0xEE, - 0x1D, 0x19, 0xCE, 0x98, 0x91, 0xEC, 0x3B, 0x28 - ))) - pub_x = bytes(bytearray(( - 0x7F, 0x2B, 0x49, 0xE2, 0x70, 0xDB, 0x6D, 0x90, - 0xD8, 0x59, 0x5B, 0xEC, 0x45, 0x8B, 0x50, 0xC5, - 0x85, 0x85, 0xBA, 0x1D, 0x4E, 0x9B, 0x78, 0x8F, - 0x66, 0x89, 0xDB, 0xD8, 0xE5, 0x6F, 0xD8, 0x0B - ))) - pub_y = bytes(bytearray(( - 0x26, 0xF1, 0xB4, 0x89, 0xD6, 0x70, 0x1D, 0xD1, - 0x85, 0xC8, 0x41, 0x3A, 0x97, 0x7B, 0x3C, 0xBB, - 0xAF, 0x64, 0xD1, 0xC5, 0x93, 0xD2, 0x66, 0x27, - 0xDF, 0xFB, 0x10, 0x1A, 0x87, 0xFF, 0x77, 0xDA - ))) - digest = bytes(bytearray(( - 0x2D, 0xFB, 0xC1, 0xB3, 0x72, 0xD8, 0x9A, 0x11, - 0x88, 0xC0, 0x9C, 0x52, 0xE0, 0xEE, 0xC6, 0x1F, - 0xCE, 0x52, 0x03, 0x2A, 0xB1, 0x02, 0x2E, 0x8E, - 0x67, 0xEC, 0xE6, 0x67, 0x2B, 0x04, 0x3E, 0xE5 - ))) - signature = bytes(bytearray(( - 0x41, 0xAA, 0x28, 0xD2, 0xF1, 0xAB, 0x14, 0x82, - 0x80, 0xCD, 0x9E, 0xD5, 0x6F, 0xED, 0xA4, 0x19, - 0x74, 0x05, 0x35, 0x54, 0xA4, 0x27, 0x67, 0xB8, - 0x3A, 0xD0, 0x43, 0xFD, 0x39, 0xDC, 0x04, 0x93, - 0x01, 0x45, 0x6C, 0x64, 0xBA, 0x46, 0x42, 0xA1, - 0x65, 0x3C, 0x23, 0x5A, 0x98, 0xA6, 0x02, 0x49, - 0xBC, 0xD6, 0xD3, 0xF7, 0x46, 0xB6, 0x31, 0xDF, - 0x92, 0x80, 0x14, 0xF6, 0xC5, 0xBF, 0x9C, 0x40 - ))) - prv = bytes2long(prv) - signature = signature[32:] + signature[:32] - - c = CURVES["id-GostR3410-2001-TestParamSet"] - pubX, pubY = public_key(c, prv) - self.assertSequenceEqual(long2bytes(pubX), pub_x) - self.assertSequenceEqual(long2bytes(pubY), pub_y) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - self.assertTrue(verify(c, (pubX, pubY), digest, signature)) - - def test_sequence(self): - c = CURVES["id-GostR3410-2001-TestParamSet"] - prv = prv_unmarshal(urandom(32)) - pubX, pubY = public_key(c, prv_unmarshal(prv_marshal(c, prv))) - for _ in range(20): - digest = urandom(32) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - - -class Test34102012(TestCase): - def test_1(self): - """Test vector from 34.10-2012 standard itself - """ - curve = CURVES["id-GostR3410-2001-TestParamSet"] - prv = bytes2long(hexdec("7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28")) - digest = hexdec("2DFBC1B372D89A1188C09C52E0EEC61FCE52032AB1022E8E67ECE6672B043EE5") - rand = hexdec("77105C9B20BCD3122823C8CF6FCC7B956DE33814E95B7FE64FED924594DCEAB3") - signature = sign(curve, prv, digest, rand) - r = "41aa28d2f1ab148280cd9ed56feda41974053554a42767b83ad043fd39dc0493" - s = "01456c64ba4642a1653c235a98a60249bcd6d3f746b631df928014f6c5bf9c40" - self.assertSequenceEqual(hexenc(signature), s + r) - - def test_2(self): - """Test vector from 34.10-2012 standard itself - """ - curve = GOST3410Curve( - p=3623986102229003635907788753683874306021320925534678605086546150450856166624002482588482022271496854025090823603058735163734263822371964987228582907372403, - q=3623986102229003635907788753683874306021320925534678605086546150450856166623969164898305032863068499961404079437936585455865192212970734808812618120619743, - a=7, - b=1518655069210828534508950034714043154928747527740206436194018823352809982443793732829756914785974674866041605397883677596626326413990136959047435811826396, - x=1928356944067022849399309401243137598997786635459507974357075491307766592685835441065557681003184874819658004903212332884252335830250729527632383493573274, - y=2288728693371972859970012155529478416353562327329506180314497425931102860301572814141997072271708807066593850650334152381857347798885864807605098724013854, - ) - prv = bytes2long(hexdec("0BA6048AADAE241BA40936D47756D7C93091A0E8514669700EE7508E508B102072E8123B2200A0563322DAD2827E2714A2636B7BFD18AADFC62967821FA18DD4")) - digest = hexdec("3754F3CFACC9E0615C4F4A7C4D8DAB531B09B6F9C170C533A71D147035B0C5917184EE536593F4414339976C647C5D5A407ADEDB1D560C4FC6777D2972075B8C") - rand = hexdec("0359E7F4B1410FEACC570456C6801496946312120B39D019D455986E364F365886748ED7A44B3E794434006011842286212273A6D14CF70EA3AF71BB1AE679F1") - signature = sign(curve, prv, digest, rand) - r = "2f86fa60a081091a23dd795e1e3c689ee512a3c82ee0dcc2643c78eea8fcacd35492558486b20f1c9ec197c90699850260c93bcbcd9c5c3317e19344e173ae36" - s = "1081b394696ffe8e6585e7a9362d26b6325f56778aadbc081c0bfbe933d52ff5823ce288e8c4f362526080df7f70ce406a6eeb1f56919cb92a9853bde73e5b4a" - self.assertSequenceEqual(hexenc(signature), s + r) - - def test_gcl3(self): - """Test vector from libgcl3 - """ - p = bytes2long(bytes(bytearray(( - 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7, - 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80, - 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04, - 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D, - 0xF1, 0xD8, 0x52, 0x74, 0x1A, 0xF4, 0x70, 0x4A, - 0x04, 0x58, 0x04, 0x7E, 0x80, 0xE4, 0x54, 0x6D, - 0x35, 0xB8, 0x33, 0x6F, 0xAC, 0x22, 0x4D, 0xD8, - 0x16, 0x64, 0xBB, 0xF5, 0x28, 0xBE, 0x63, 0x73, - )))) - q = bytes2long(bytes(bytearray(( - 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7, - 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80, - 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04, - 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D, - 0xA8, 0x2F, 0x2D, 0x7E, 0xCB, 0x1D, 0xBA, 0xC7, - 0x19, 0x90, 0x5C, 0x5E, 0xEC, 0xC4, 0x23, 0xF1, - 0xD8, 0x6E, 0x25, 0xED, 0xBE, 0x23, 0xC5, 0x95, - 0xD6, 0x44, 0xAA, 0xF1, 0x87, 0xE6, 0xE6, 0xDF, - )))) - a = bytes2long(bytes(bytearray(( - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - )))) - b = bytes2long(bytes(bytearray(( - 0x1C, 0xFF, 0x08, 0x06, 0xA3, 0x11, 0x16, 0xDA, - 0x29, 0xD8, 0xCF, 0xA5, 0x4E, 0x57, 0xEB, 0x74, - 0x8B, 0xC5, 0xF3, 0x77, 0xE4, 0x94, 0x00, 0xFD, - 0xD7, 0x88, 0xB6, 0x49, 0xEC, 0xA1, 0xAC, 0x43, - 0x61, 0x83, 0x40, 0x13, 0xB2, 0xAD, 0x73, 0x22, - 0x48, 0x0A, 0x89, 0xCA, 0x58, 0xE0, 0xCF, 0x74, - 0xBC, 0x9E, 0x54, 0x0C, 0x2A, 0xDD, 0x68, 0x97, - 0xFA, 0xD0, 0xA3, 0x08, 0x4F, 0x30, 0x2A, 0xDC, - )))) - x = bytes2long(bytes(bytearray(( - 0x24, 0xD1, 0x9C, 0xC6, 0x45, 0x72, 0xEE, 0x30, - 0xF3, 0x96, 0xBF, 0x6E, 0xBB, 0xFD, 0x7A, 0x6C, - 0x52, 0x13, 0xB3, 0xB3, 0xD7, 0x05, 0x7C, 0xC8, - 0x25, 0xF9, 0x10, 0x93, 0xA6, 0x8C, 0xD7, 0x62, - 0xFD, 0x60, 0x61, 0x12, 0x62, 0xCD, 0x83, 0x8D, - 0xC6, 0xB6, 0x0A, 0xA7, 0xEE, 0xE8, 0x04, 0xE2, - 0x8B, 0xC8, 0x49, 0x97, 0x7F, 0xAC, 0x33, 0xB4, - 0xB5, 0x30, 0xF1, 0xB1, 0x20, 0x24, 0x8A, 0x9A, - )))) - y = bytes2long(bytes(bytearray(( - 0x2B, 0xB3, 0x12, 0xA4, 0x3B, 0xD2, 0xCE, 0x6E, - 0x0D, 0x02, 0x06, 0x13, 0xC8, 0x57, 0xAC, 0xDD, - 0xCF, 0xBF, 0x06, 0x1E, 0x91, 0xE5, 0xF2, 0xC3, - 0xF3, 0x24, 0x47, 0xC2, 0x59, 0xF3, 0x9B, 0x2C, - 0x83, 0xAB, 0x15, 0x6D, 0x77, 0xF1, 0x49, 0x6B, - 0xF7, 0xEB, 0x33, 0x51, 0xE1, 0xEE, 0x4E, 0x43, - 0xDC, 0x1A, 0x18, 0xB9, 0x1B, 0x24, 0x64, 0x0B, - 0x6D, 0xBB, 0x92, 0xCB, 0x1A, 0xDD, 0x37, 0x1E, - )))) - prv = bytes(bytearray(( - 0x0B, 0xA6, 0x04, 0x8A, 0xAD, 0xAE, 0x24, 0x1B, - 0xA4, 0x09, 0x36, 0xD4, 0x77, 0x56, 0xD7, 0xC9, - 0x30, 0x91, 0xA0, 0xE8, 0x51, 0x46, 0x69, 0x70, - 0x0E, 0xE7, 0x50, 0x8E, 0x50, 0x8B, 0x10, 0x20, - 0x72, 0xE8, 0x12, 0x3B, 0x22, 0x00, 0xA0, 0x56, - 0x33, 0x22, 0xDA, 0xD2, 0x82, 0x7E, 0x27, 0x14, - 0xA2, 0x63, 0x6B, 0x7B, 0xFD, 0x18, 0xAA, 0xDF, - 0xC6, 0x29, 0x67, 0x82, 0x1F, 0xA1, 0x8D, 0xD4, - ))) - pub_x = bytes(bytearray(( - 0x11, 0x5D, 0xC5, 0xBC, 0x96, 0x76, 0x0C, 0x7B, - 0x48, 0x59, 0x8D, 0x8A, 0xB9, 0xE7, 0x40, 0xD4, - 0xC4, 0xA8, 0x5A, 0x65, 0xBE, 0x33, 0xC1, 0x81, - 0x5B, 0x5C, 0x32, 0x0C, 0x85, 0x46, 0x21, 0xDD, - 0x5A, 0x51, 0x58, 0x56, 0xD1, 0x33, 0x14, 0xAF, - 0x69, 0xBC, 0x5B, 0x92, 0x4C, 0x8B, 0x4D, 0xDF, - 0xF7, 0x5C, 0x45, 0x41, 0x5C, 0x1D, 0x9D, 0xD9, - 0xDD, 0x33, 0x61, 0x2C, 0xD5, 0x30, 0xEF, 0xE1, - ))) - pub_y = bytes(bytearray(( - 0x37, 0xC7, 0xC9, 0x0C, 0xD4, 0x0B, 0x0F, 0x56, - 0x21, 0xDC, 0x3A, 0xC1, 0xB7, 0x51, 0xCF, 0xA0, - 0xE2, 0x63, 0x4F, 0xA0, 0x50, 0x3B, 0x3D, 0x52, - 0x63, 0x9F, 0x5D, 0x7F, 0xB7, 0x2A, 0xFD, 0x61, - 0xEA, 0x19, 0x94, 0x41, 0xD9, 0x43, 0xFF, 0xE7, - 0xF0, 0xC7, 0x0A, 0x27, 0x59, 0xA3, 0xCD, 0xB8, - 0x4C, 0x11, 0x4E, 0x1F, 0x93, 0x39, 0xFD, 0xF2, - 0x7F, 0x35, 0xEC, 0xA9, 0x36, 0x77, 0xBE, 0xEC, - ))) - digest = bytes(bytearray(( - 0x37, 0x54, 0xF3, 0xCF, 0xAC, 0xC9, 0xE0, 0x61, - 0x5C, 0x4F, 0x4A, 0x7C, 0x4D, 0x8D, 0xAB, 0x53, - 0x1B, 0x09, 0xB6, 0xF9, 0xC1, 0x70, 0xC5, 0x33, - 0xA7, 0x1D, 0x14, 0x70, 0x35, 0xB0, 0xC5, 0x91, - 0x71, 0x84, 0xEE, 0x53, 0x65, 0x93, 0xF4, 0x41, - 0x43, 0x39, 0x97, 0x6C, 0x64, 0x7C, 0x5D, 0x5A, - 0x40, 0x7A, 0xDE, 0xDB, 0x1D, 0x56, 0x0C, 0x4F, - 0xC6, 0x77, 0x7D, 0x29, 0x72, 0x07, 0x5B, 0x8C, - ))) - signature = bytes(bytearray(( - 0x2F, 0x86, 0xFA, 0x60, 0xA0, 0x81, 0x09, 0x1A, - 0x23, 0xDD, 0x79, 0x5E, 0x1E, 0x3C, 0x68, 0x9E, - 0xE5, 0x12, 0xA3, 0xC8, 0x2E, 0xE0, 0xDC, 0xC2, - 0x64, 0x3C, 0x78, 0xEE, 0xA8, 0xFC, 0xAC, 0xD3, - 0x54, 0x92, 0x55, 0x84, 0x86, 0xB2, 0x0F, 0x1C, - 0x9E, 0xC1, 0x97, 0xC9, 0x06, 0x99, 0x85, 0x02, - 0x60, 0xC9, 0x3B, 0xCB, 0xCD, 0x9C, 0x5C, 0x33, - 0x17, 0xE1, 0x93, 0x44, 0xE1, 0x73, 0xAE, 0x36, - 0x10, 0x81, 0xB3, 0x94, 0x69, 0x6F, 0xFE, 0x8E, - 0x65, 0x85, 0xE7, 0xA9, 0x36, 0x2D, 0x26, 0xB6, - 0x32, 0x5F, 0x56, 0x77, 0x8A, 0xAD, 0xBC, 0x08, - 0x1C, 0x0B, 0xFB, 0xE9, 0x33, 0xD5, 0x2F, 0xF5, - 0x82, 0x3C, 0xE2, 0x88, 0xE8, 0xC4, 0xF3, 0x62, - 0x52, 0x60, 0x80, 0xDF, 0x7F, 0x70, 0xCE, 0x40, - 0x6A, 0x6E, 0xEB, 0x1F, 0x56, 0x91, 0x9C, 0xB9, - 0x2A, 0x98, 0x53, 0xBD, 0xE7, 0x3E, 0x5B, 0x4A, - ))) - prv = bytes2long(prv) - signature = signature[64:] + signature[:64] - c = GOST3410Curve(p, q, a, b, x, y) - pubX, pubY = public_key(c, prv) - self.assertSequenceEqual(long2bytes(pubX), pub_x) - self.assertSequenceEqual(long2bytes(pubY), pub_y) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - self.assertTrue(verify(c, (pubX, pubY), digest, signature)) - - def test_sequence(self): - c = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - prv = bytes2long(urandom(64)) - pubX, pubY = public_key(c, prv_unmarshal(prv_marshal(c, prv))) - for _ in range(20): - digest = urandom(64) - s = sign(c, prv, digest) - self.assertTrue(verify(c, (pubX, pubY), digest, s)) - self.assertNotIn(b"\x00" * 8, s) - - -class TestUVXYConversion(TestCase): - """Twisted Edwards to Weierstrass coordinates conversion and vice versa - """ - def test_curve1(self): - c = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - u, v = (0x0D, bytes2long(hexdec("60CA1E32AA475B348488C38FAB07649CE7EF8DBE87F22E81F92B2592DBA300E7"))) - self.assertEqual(uv2xy(c, u, v), (c.x, c.y)) - self.assertEqual(xy2uv(c, c.x, c.y), (u, v)) - - def test_curve2(self): - c = CURVES["id-tc26-gost-3410-2012-512-paramSetC"] - u, v = (0x12, bytes2long(hexdec("469AF79D1FB1F5E16B99592B77A01E2A0FDFB0D01794368D9A56117F7B38669522DD4B650CF789EEBF068C5D139732F0905622C04B2BAAE7600303EE73001A3D"))) - self.assertEqual(uv2xy(c, u, v), (c.x, c.y)) - self.assertEqual(xy2uv(c, c.x, c.y), (u, v)) - - -class Test34102012SESPAKE(TestCase): - """Test vectors for multiplication from :rfc:`8133` - """ - def test_curve1(self): - c = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] - q_ind = ( - 0xA69D51CAF1A309FA9E9B66187759B0174C274E080356F23CFCBFE84D396AD7BB, - 0x5D26F29ECC2E9AC0404DCF7986FA55FE94986362170F54B9616426A659786DAC, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x59495655D1E7C7424C622485F575CCF121F3122D274101E8AB734CC9C9A9B45E, - 0x48D1C311D33C9B701F3B03618562A4A07A044E3AF31E3999E67B487778B53C62, - ) - ) - self.assertEqual( - c.exp(0x1F2538097D5A031FA68BBB43C84D12B3DE47B7061C0D5E24993E0C873CDBA6B3), - ( - 0xBBC77CF42DC1E62D06227935379B4AA4D14FEA4F565DDF4CB4FA4D31579F9676, - 0x8E16604A4AFDF28246684D4996274781F6CB80ABBBA1414C1513EC988509DABF, - ) - ) - self.assertEqual( - c.exp(0xDC497D9EF6324912FD367840EE509A2032AEDB1C0A890D133B45F596FCCBD45D), - ( - 0x6097341C1BE388E83E7CA2DF47FAB86E2271FD942E5B7B2EB2409E49F742BC29, - 0xC81AA48BDB4CA6FA0EF18B9788AE25FE30857AA681B3942217F9FED151BAB7D0, - ), - ) - - def test_curve2(self): - c = CURVES["id-GostR3410-2001-CryptoPro-B-ParamSet"] - q_ind = ( - 0x3D715A874A4B17CB3B517893A9794A2B36C89D2FFC693F01EE4CC27E7F49E399, - 0x1C5A641FCF7CE7E87CDF8CEA38F3DB3096EACE2FAD158384B53953365F4FE7FE, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x6DC2AE26BC691FCA5A73D9C452790D15E34BA5404D92955B914C8D2662ABB985, - 0x3B02AAA9DD65AE30C335CED12F3154BBAC059F66B088306747453EDF6E5DB077, - ) - ) - self.assertEqual( - c.exp(0x499D72B90299CAB0DA1F8BE19D9122F622A13B32B730C46BD0664044F2144FAD), - ( - 0x61D6F916DB717222D74877F179F7EBEF7CD4D24D8C1F523C048E34A1DF30F8DD, - 0x3EC48863049CFCFE662904082E78503F4973A4E105E2F1B18C69A5E7FB209000, - ) - ) - self.assertEqual( - c.exp(0x0F69FF614957EF83668EDC2D7ED614BE76F7B253DB23C5CC9C52BF7DF8F4669D), - ( - 0x33BC6F7E9C0BA10CFB2B72546C327171295508EA97F8C8BA9F890F2478AB4D6C, - 0x75D57B396C396F492F057E9222CCC686437A2AAD464E452EF426FC8EEED1A4A6, - ), - ) - - def test_curve3(self): - c = CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"] - q_ind = ( - 0x1E36383E43BB6CFA2917167D71B7B5DD3D6D462B43D7C64282AE67DFBEC2559D, - 0x137478A9F721C73932EA06B45CF72E37EB78A63F29A542E563C614650C8B6399, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x945821DAF91E158B839939630655A3B21FF3E146D27041E86C05650EB3B46B59, - 0x3A0C2816AC97421FA0E879605F17F0C9C3EB734CFF196937F6284438D70BDC48, - ) - ) - self.assertEqual( - c.exp(0x3A54AC3F19AD9D0B1EAC8ACDCEA70E581F1DAC33D13FEAFD81E762378639C1A8), - ( - 0x96B7F09C94D297C257A7DA48364C0076E59E48D221CBA604AE111CA3933B446A, - 0x54E4953D86B77ECCEB578500931E822300F7E091F79592CA202A020D762C34A6, - ) - ) - self.assertEqual( - c.exp(0x448781782BF7C0E52A1DD9E6758FD3482D90D3CFCCF42232CF357E59A4D49FD4), - ( - 0x4B9C0AB55A938121F282F48A2CC4396EB16E7E0068B495B0C1DD4667786A3EB7, - 0x223460AA8E09383E9DF9844C5A0F2766484738E5B30128A171B69A77D9509B96, - ), - ) - - def test_curve4(self): - c = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - q_ind = ( - 0x2A17F8833A32795327478871B5C5E88AEFB91126C64B4B8327289BEA62559425D18198F133F400874328B220C74497CD240586CB249E158532CB8090776CD61C, - 0x728F0C4A73B48DA41CE928358FAD26B47A6E094E9362BAE82559F83CDDC4EC3A4676BD3707EDEAF4CD85E99695C64C241EDC622BE87DC0CF87F51F4367F723C5, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x0C0AB53D0E0A9C607CAD758F558915A0A7DC5DC87B45E9A58FDDF30EC3385960283E030CD322D9E46B070637785FD49D2CD711F46807A24C40AF9A42C8E2D740, - 0xDF93A8012B86D3A3D4F8A4D487DA15FC739EB31B20B3B0E8C8C032AAF8072C6337CF7D5B404719E5B4407C41D9A3216A08CA69C271484E9ED72B8AAA52E28B8B, - ) - ) - self.assertEqual( - c.exp(0x3CE54325DB52FE798824AEAD11BB16FA766857D04A4AF7D468672F16D90E7396046A46F815693E85B1CE5464DA9270181F82333B0715057BBE8D61D400505F0E), - ( - 0xB93093EB0FCC463239B7DF276E09E592FCFC9B635504EA4531655D76A0A3078E2B4E51CFE2FA400CC5DE9FBE369DB204B3E8ED7EDD85EE5CCA654C1AED70E396, - 0x809770B8D910EA30BD2FA89736E91DC31815D2D9B31128077EEDC371E9F69466F497DC64DD5B1FADC587F860EE256109138C4A9CD96B628E65A8F590520FC882, - ) - ) - self.assertEqual( - c.exp(0xB5C286A79AA8E97EC0E19BC1959A1D15F12F8C97870BA9D68CC12811A56A3BB11440610825796A49D468CDC9C2D02D76598A27973D5960C5F50BCE28D8D345F4), - ( - 0x238B38644E440452A99FA6B93D9FD7DA0CB83C32D3C1E3CFE5DF5C3EB0F9DB91E588DAEDC849EA2FB867AE855A21B4077353C0794716A6480995113D8C20C7AF, - 0xB2273D5734C1897F8D15A7008B862938C8C74CA7E877423D95243EB7EBD02FD2C456CF9FC956F078A59AA86F19DD1075E5167E4ED35208718EA93161C530ED14, - ), - ) - - def test_curve5(self): - c = CURVES["id-tc26-gost-3410-12-512-paramSetB"] - q_ind = ( - 0x7E1FAE8285E035BEC244BEF2D0E5EBF436633CF50E55231DEA9C9CF21D4C8C33DF85D4305DE92971F0A4B4C07E00D87BDBC720EB66E49079285AAF12E0171149, - 0x2CC89998B875D4463805BA0D858A196592DB20AB161558FF2F4EF7A85725D20953967AE621AFDEAE89BB77C83A2528EF6FCE02F68BDA4679D7F2704947DBC408, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x7D03E65B8050D1E12CBB601A17B9273B0E728F5021CD47C8A4DD822E4627BA5F9C696286A2CDDA9A065509866B4DEDEDC4A118409604AD549F87A60AFA621161, - 0x16037DAD45421EC50B00D50BDC6AC3B85348BC1D3A2F85DB27C3373580FEF87C2C743B7ED30F22BE22958044E716F93A61CA3213A361A2797A16A3AE62957377, - ) - ) - self.assertEqual( - c.exp(0x715E893FA639BF341296E0623E6D29DADF26B163C278767A7982A989462A3863FE12AEF8BD403D59C4DC4720570D4163DB0805C7C10C4E818F9CB785B04B9997), - ( - 0x10C479EA1C04D3C2C02B0576A9C42D96226FF033C1191436777F66916030D87D02FB93738ED7669D07619FFCE7C1F3C4DB5E5DF49E2186D6FA1E2EB5767602B9, - 0x039F6044191404E707F26D59D979136A831CCE43E1C5F0600D1DDF8F39D0CA3D52FBD943BF04DDCED1AA2CE8F5EBD7487ACDEF239C07D015084D796784F35436, - ) - ) - self.assertEqual( - c.exp(0x30FA8C2B4146C2DBBE82BED04D7378877E8C06753BD0A0FF71EBF2BEFE8DA8F3DC0836468E2CE7C5C961281B6505140F8407413F03C2CB1D201EA1286CE30E6D), - ( - 0x34C0149E7BB91AE377B02573FCC48AF7BFB7B16DEB8F9CE870F384688E3241A3A868588CC0EF4364CCA67D17E3260CD82485C202ADC76F895D5DF673B1788E67, - 0x608E944929BD643569ED5189DB871453F13333A1EAF82B2FE1BE8100E775F13DD9925BD317B63BFAF05024D4A738852332B64501195C1B2EF789E34F23DDAFC5, - ), - ) - - def test_curve6(self): - c = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - q_ind = ( - 0xB51ADF93A40AB15792164FAD3352F95B66369EB2A4EF5EFAE32829320363350E, - 0x74A358CC08593612F5955D249C96AFB7E8B0BB6D8BD2BBE491046650D822BE18, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0xDBF99827078956812FA48C6E695DF589DEF1D18A2D4D35A96D75BF6854237629, - 0x9FDDD48BFBC57BEE1DA0CFF282884F284D471B388893C48F5ECB02FC18D67589, - ) - ) - self.assertEqual( - c.exp(0x147B72F6684FB8FD1B418A899F7DBECAF5FCE60B13685BAA95328654A7F0707F), - ( - 0x33FBAC14EAE538275A769417829C431BD9FA622B6F02427EF55BD60EE6BC2888, - 0x22F2EBCF960A82E6CDB4042D3DDDA511B2FBA925383C2273D952EA2D406EAE46, - ) - ) - self.assertEqual( - c.exp(0x30D5CFADAA0E31B405E6734C03EC4C5DF0F02F4BA25C9A3B320EE6453567B4CB), - ( - 0x2B2D89FAB735433970564F2F28CFA1B57D640CB902BC6334A538F44155022CB2, - 0x10EF6A82EEF1E70F942AA81D6B4CE5DEC0DDB9447512962874870E6F2849A96F, - ), - ) - - def test_curve7(self): - c = CURVES["id-tc26-gost-3410-2012-512-paramSetC"] - q_ind = ( - 0x489C91784E02E98F19A803ABCA319917F37689E5A18965251CE2FF4E8D8B298F5BA7470F9E0E713487F96F4A8397B3D09A270C9D367EB5E0E6561ADEEB51581D, - 0x684EA885ACA64EAF1B3FEE36C0852A3BE3BD8011B0EF18E203FF87028D6EB5DB2C144A0DCC71276542BFD72CA2A43FA4F4939DA66D9A60793C704A8C94E16F18, - ) - self.assertEqual( - c.exp(bytes2long(hexdec( - "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702" - )[::-1]), x=q_ind[0], y=q_ind[1]), - ( - 0x0185AE6271A81BB7F236A955F7CAA26FB63849813C0287D96C83A15AE6B6A86467AB13B6D88CE8CD7DC2E5B97FF5F28FAC2C108F2A3CF3DB5515C9E6D7D210E8, - 0xED0220F92EF771A71C64ECC77986DB7C03D37B3E2AB3E83F32CE5E074A762EC08253C9E2102B87532661275C4B1D16D2789CDABC58ACFDF7318DE70AB64F09B8, - ) - ) - self.assertEqual( - c.exp(0x332F930421D14CFE260042159F18E49FD5A54167E94108AD80B1DE60B13DE7999A34D611E63F3F870E5110247DF8EC7466E648ACF385E52CCB889ABF491EDFF0), - ( - 0x561655966D52952E805574F4281F1ED3A2D498932B00CBA9DECB42837F09835BFFBFE2D84D6B6B242FE7B57F92E1A6F2413E12DDD6383E4437E13D72693469AD, - 0xF6B18328B2715BD7F4178615273A36135BC0BF62F7D8BB9F080164AD36470AD03660F51806C64C6691BADEF30F793720F8E3FEAED631D6A54A4C372DCBF80E82, - ) - ) - self.assertEqual( - c.exp(0x38481771E7D054F96212686B613881880BD8A6C89DDBC656178F014D2C093432A033EE10415F13A160D44C2AD61E6E2E05A7F7EC286BCEA3EA4D4D53F8634FA2), - ( - 0xB7C5818687083433BC1AFF61CB5CA79E38232025E0C1F123B8651E62173CE6873F3E6FFE7281C2E45F4F524F66B0C263616ED08FD210AC4355CA3292B51D71C3, - 0x497F14205DBDC89BDDAF50520ED3B1429AD30777310186BE5E68070F016A44E0C766DB08E8AC23FBDFDE6D675AA4DF591EB18BA0D348DF7AA40973A2F1DCFA55, - ), - ) diff --git a/pygost-5.13/pygost/test_gost3410_vko.py b/pygost-5.13/pygost/test_gost3410_vko.py deleted file mode 100644 index a8e298e..0000000 --- a/pygost-5.13/pygost/test_gost3410_vko.py +++ /dev/null @@ -1,125 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410_vko import kek_34102001 -from pygost.gost3410_vko import kek_34102012256 -from pygost.gost3410_vko import kek_34102012512 -from pygost.gost3410_vko import ukm_unmarshal -from pygost.utils import bytes2long -from pygost.utils import hexdec - - -class TestVKO34102001(TestCase): - def test_vector(self): - curve = CURVES["id-GostR3410-2001-TestParamSet"] - ukm = ukm_unmarshal(hexdec("5172be25f852a233")) - prv1 = prv_unmarshal(hexdec("1df129e43dab345b68f6a852f4162dc69f36b2f84717d08755cc5c44150bf928")) - prv2 = prv_unmarshal(hexdec("5b9356c6474f913f1e83885ea0edd5df1a43fd9d799d219093241157ac9ed473")) - kek = hexdec("ee4618a0dbb10cb31777b4b86a53d9e7ef6cb3e400101410f0c0f2af46c494a6") - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - self.assertSequenceEqual(kek_34102001(curve, prv1, pub2, ukm), kek) - self.assertSequenceEqual(kek_34102001(curve, prv2, pub1, ukm), kek) - - def test_sequence(self): - curve = CURVES["id-GostR3410-2001-TestParamSet"] - for _ in range(10): - ukm = ukm_unmarshal(urandom(8)) - prv1 = bytes2long(urandom(32)) - prv2 = bytes2long(urandom(32)) - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - kek1 = kek_34102001(curve, prv1, pub2, ukm) - kek2 = kek_34102001(curve, prv2, pub1, ukm) - self.assertSequenceEqual(kek1, kek2) - kek1 = kek_34102001(curve, prv1, pub1, ukm) - kek2 = kek_34102001(curve, prv2, pub2, ukm) - self.assertNotEqual(kek1, kek2) - - -class TestVKO34102012256(TestCase): - """RFC 7836 - """ - def test_vector(self): - curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - ukm = ukm_unmarshal(hexdec("1d80603c8544c727")) - prvA = prv_unmarshal(hexdec("c990ecd972fce84ec4db022778f50fcac726f46708384b8d458304962d7147f8c2db41cef22c90b102f2968404f9b9be6d47c79692d81826b32b8daca43cb667")) - pubA = pub_unmarshal(hexdec("aab0eda4abff21208d18799fb9a8556654ba783070eba10cb9abb253ec56dcf5d3ccba6192e464e6e5bcb6dea137792f2431f6c897eb1b3c0cc14327b1adc0a7914613a3074e363aedb204d38d3563971bd8758e878c9db11403721b48002d38461f92472d40ea92f9958c0ffa4c93756401b97f89fdbe0b5e46e4a4631cdb5a")) - prvB = prv_unmarshal(hexdec("48c859f7b6f11585887cc05ec6ef1390cfea739b1a18c0d4662293ef63b79e3b8014070b44918590b4b996acfea4edfbbbcccc8c06edd8bf5bda92a51392d0db")) - pubB = pub_unmarshal(hexdec("192fe183b9713a077253c72c8735de2ea42a3dbc66ea317838b65fa32523cd5efca974eda7c863f4954d1147f1f2b25c395fce1c129175e876d132e94ed5a65104883b414c9b592ec4dc84826f07d0b6d9006dda176ce48c391e3f97d102e03bb598bf132a228a45f7201aba08fc524a2d77e43a362ab022ad4028f75bde3b79")) - vko = hexdec("c9a9a77320e2cc559ed72dce6f47e2192ccea95fa648670582c054c0ef36c221") - self.assertSequenceEqual(kek_34102012256(curve, prvA, pubB, ukm), vko) - self.assertSequenceEqual(kek_34102012256(curve, prvB, pubA, ukm), vko) - - def test_sequence(self): - curve = CURVES["id-tc26-gost-3410-2012-256-paramSetA"] - for _ in range(10): - ukm = ukm_unmarshal(urandom(8)) - prv1 = bytes2long(urandom(32)) - prv2 = bytes2long(urandom(32)) - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - kek1 = kek_34102012256(curve, prv1, pub2, ukm) - kek2 = kek_34102012256(curve, prv2, pub1, ukm) - self.assertSequenceEqual(kek1, kek2) - kek1 = kek_34102012256(curve, prv1, pub1, ukm) - kek2 = kek_34102012256(curve, prv2, pub2, ukm) - self.assertNotEqual(kek1, kek2) - - def test_pub_is_not_on_curve(self): - with self.assertRaises(ValueError): - kek_34102012256( - CURVES["id-tc26-gost-3410-2012-256-paramSetA"], - bytes2long(urandom(32)), - pub_unmarshal(urandom(64)), - ) - - -class TestVKO34102012512(TestCase): - """RFC 7836 - """ - def test_vector(self): - curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - ukm = ukm_unmarshal(hexdec("1d80603c8544c727")) - prvA = prv_unmarshal(hexdec("c990ecd972fce84ec4db022778f50fcac726f46708384b8d458304962d7147f8c2db41cef22c90b102f2968404f9b9be6d47c79692d81826b32b8daca43cb667")) - pubA = pub_unmarshal(hexdec("aab0eda4abff21208d18799fb9a8556654ba783070eba10cb9abb253ec56dcf5d3ccba6192e464e6e5bcb6dea137792f2431f6c897eb1b3c0cc14327b1adc0a7914613a3074e363aedb204d38d3563971bd8758e878c9db11403721b48002d38461f92472d40ea92f9958c0ffa4c93756401b97f89fdbe0b5e46e4a4631cdb5a")) - prvB = prv_unmarshal(hexdec("48c859f7b6f11585887cc05ec6ef1390cfea739b1a18c0d4662293ef63b79e3b8014070b44918590b4b996acfea4edfbbbcccc8c06edd8bf5bda92a51392d0db")) - pubB = pub_unmarshal(hexdec("192fe183b9713a077253c72c8735de2ea42a3dbc66ea317838b65fa32523cd5efca974eda7c863f4954d1147f1f2b25c395fce1c129175e876d132e94ed5a65104883b414c9b592ec4dc84826f07d0b6d9006dda176ce48c391e3f97d102e03bb598bf132a228a45f7201aba08fc524a2d77e43a362ab022ad4028f75bde3b79")) - vko = hexdec("79f002a96940ce7bde3259a52e015297adaad84597a0d205b50e3e1719f97bfa7ee1d2661fa9979a5aa235b558a7e6d9f88f982dd63fc35a8ec0dd5e242d3bdf") - self.assertSequenceEqual(kek_34102012512(curve, prvA, pubB, ukm), vko) - self.assertSequenceEqual(kek_34102012512(curve, prvB, pubA, ukm), vko) - - def test_sequence(self): - curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"] - for _ in range(10): - ukm = ukm_unmarshal(urandom(8)) - prv1 = bytes2long(urandom(32)) - prv2 = bytes2long(urandom(32)) - pub1 = public_key(curve, prv1) - pub2 = public_key(curve, prv2) - kek1 = kek_34102012512(curve, prv1, pub2, ukm) - kek2 = kek_34102012512(curve, prv2, pub1, ukm) - self.assertSequenceEqual(kek1, kek2) - kek1 = kek_34102012512(curve, prv1, pub1, ukm) - kek2 = kek_34102012512(curve, prv2, pub2, ukm) - self.assertNotEqual(kek1, kek2) diff --git a/pygost-5.13/pygost/test_gost34112012.py b/pygost-5.13/pygost/test_gost34112012.py deleted file mode 100644 index c7c2df9..0000000 --- a/pygost-5.13/pygost/test_gost34112012.py +++ /dev/null @@ -1,159 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from random import randint -from unittest import skip -from unittest import TestCase -import hmac - -from pygost import gost34112012256 -from pygost import gost34112012512 -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost34112012512 import pbkdf2 -from pygost.utils import hexdec -from pygost.utils import hexenc - - -class TestCopy(TestCase): - def runTest(self): - m = GOST34112012256() - c = m.copy() - m.update(b"foobar") - c.update(b"foo") - c.update(b"bar") - self.assertSequenceEqual(m.digest(), c.digest()) - - -class TestSymmetric(TestCase): - def runTest(self): - chunks = [] - for _ in range(randint(1, 10)): - chunks.append(urandom(randint(20, 80))) - m = GOST34112012256() - for chunk in chunks: - m.update(chunk) - self.assertSequenceEqual( - m.hexdigest(), - GOST34112012256(b"".join(chunks)).hexdigest(), - ) - - -class TestHMAC(TestCase): - """RFC 7836 - """ - def test_256(self): - for digestmod in (GOST34112012256, gost34112012256): - self.assertSequenceEqual( - hmac.new( - key=hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - msg=hexdec("0126bdb87800af214341456563780100"), - digestmod=digestmod, - ).hexdigest(), - "a1aa5f7de402d7b3d323f2991c8d4534013137010a83754fd0af6d7cd4922ed9", - ) - - def test_512(self): - for digestmod in (GOST34112012512, gost34112012512): - self.assertSequenceEqual( - hmac.new( - key=hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - msg=hexdec("0126bdb87800af214341456563780100"), - digestmod=digestmod, - ).hexdigest(), - "a59bab22ecae19c65fbde6e5f4e9f5d8549d31f037f9df9b905500e171923a773d5f1530f2ed7e964cb2eedc29e9ad2f3afe93b2814f79f5000ffc0366c251e6", - ) - - -class TestVectors(TestCase): - def test_m1(self): - m = hexdec("323130393837363534333231303938373635343332313039383736353433323130393837363534333231303938373635343332313039383736353433323130")[::-1] - self.assertSequenceEqual( - GOST34112012512(m).digest(), - hexdec("486f64c1917879417fef082b3381a4e211c324f074654c38823a7b76f830ad00fa1fbae42b1285c0352f227524bc9ab16254288dd6863dccd5b9f54a1ad0541b")[::-1] - ) - self.assertSequenceEqual( - GOST34112012256(m).digest(), - hexdec("00557be5e584fd52a449b16b0251d05d27f94ab76cbaa6da890b59d8ef1e159d")[::-1] - ) - - def test_m2(self): - m = u"Се ветри, Стрибожи внуци, веютъ с моря стрелами на храбрыя плъкы Игоревы".encode("cp1251") - self.assertSequenceEqual(m, hexdec("fbe2e5f0eee3c820fbeafaebef20fffbf0e1e0f0f520e0ed20e8ece0ebe5f0f2f120fff0eeec20f120faf2fee5e2202ce8f6f3ede220e8e6eee1e8f0f2d1202ce8f0f2e5e220e5d1")[::-1]) - self.assertSequenceEqual( - GOST34112012512(m).digest(), - hexdec("28fbc9bada033b1460642bdcddb90c3fb3e56c497ccd0f62b8a2ad4935e85f037613966de4ee00531ae60f3b5a47f8dae06915d5f2f194996fcabf2622e6881e")[::-1] - ) - self.assertSequenceEqual( - GOST34112012256(m).digest(), - hexdec("508f7e553c06501d749a66fc28c6cac0b005746d97537fa85d9e40904efed29d")[::-1] - ) - - def test_habr144(self): - """Test vector from https://habr.com/ru/post/452200/ - """ - m = hexdec("d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000002400000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") - self.assertSequenceEqual( - GOST34112012256(m).hexdigest(), - "c766085540caaa8953bfcf7a1ba220619cee50d65dc242f82f23ba4b180b18e0", - ) - - -class TestPBKDF2(TestCase): - """http://tc26.ru/.../R_50.1.111-2016.pdf - """ - def test_1(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 1, 64)), - "64770af7f748c3b1c9ac831dbcfd85c26111b30a8a657ddc3056b80ca73e040d2854fd36811f6d825cc4ab66ec0a68a490a9e5cf5156b3a2b7eecddbf9a16b47", - ) - - def test_2(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 2, 64)), - "5a585bafdfbb6e8830d6d68aa3b43ac00d2e4aebce01c9b31c2caed56f0236d4d34b2b8fbd2c4e89d54d46f50e47d45bbac301571743119e8d3c42ba66d348de", - ) - - def test_3(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 4096, 64)), - "e52deb9a2d2aaff4e2ac9d47a41f34c20376591c67807f0477e32549dc341bc7867c09841b6d58e29d0347c996301d55df0d34e47cf68f4e3c2cdaf1d9ab86c3", - ) - - @skip("it takes too long") - def test_4(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 1677216, 64)), - "49e4843bba76e300afe24c4d23dc7392def12f2c0e244172367cd70a8982ac361adb601c7e2a314e8cb7b1e9df840e36ab5615be5d742b6cf203fb55fdc48071", - ) - - def test_5(self): - self.assertSequenceEqual( - hexenc(pbkdf2( - b"passwordPASSWORDpassword", - b"saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - 100, - )), - "b2d8f1245fc4d29274802057e4b54e0a0753aa22fc53760b301cf008679e58fe4bee9addcae99ba2b0b20f431a9c5e50f395c89387d0945aedeca6eb4015dfc2bd2421ee9bb71183ba882ceebfef259f33f9e27dc6178cb89dc37428cf9cc52a2baa2d3a", - ) - - def test_6(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"pass\x00word", b"sa\x00lt", 4096, 64)), - "50df062885b69801a3c10248eb0a27ab6e522ffeb20c991c660f001475d73a4e167f782c18e97e92976d9c1d970831ea78ccb879f67068cdac1910740844e830", - ) diff --git a/pygost-5.13/pygost/test_gost341194.py b/pygost-5.13/pygost/test_gost341194.py deleted file mode 100644 index 4ffa6d6..0000000 --- a/pygost-5.13/pygost/test_gost341194.py +++ /dev/null @@ -1,200 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import skip -from unittest import TestCase -import hmac - -from pygost import gost341194 -from pygost.gost341194 import GOST341194 -from pygost.gost341194 import pbkdf2 -from pygost.utils import hexenc - - -class TestCopy(TestCase): - def runTest(self): - m = GOST341194() - c = m.copy() - m.update(b"foobar") - c.update(b"foo") - c.update(b"bar") - self.assertSequenceEqual(m.digest(), c.digest()) - - -class TestHMACPEP247(TestCase): - def runTest(self): - h = hmac.new(b"foo", digestmod=gost341194) - h.update(b"foobar") - h.digest() - - -class TestVectors(TestCase): - def test_empty(self): - self.assertSequenceEqual( - GOST341194(b"", "id-GostR3411-94-TestParamSet").hexdigest(), - "ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d", - ) - - def test_a(self): - self.assertSequenceEqual( - GOST341194(b"a", "id-GostR3411-94-TestParamSet").hexdigest(), - "d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd", - ) - - def test_abc(self): - self.assertSequenceEqual( - GOST341194(b"abc", "id-GostR3411-94-TestParamSet").hexdigest(), - "f3134348c44fb1b2a277729e2285ebb5cb5e0f29c975bc753b70497c06a4d51d", - ) - - def test_message_digest(self): - self.assertSequenceEqual( - GOST341194(b"message digest", "id-GostR3411-94-TestParamSet").hexdigest(), - "ad4434ecb18f2c99b60cbe59ec3d2469582b65273f48de72db2fde16a4889a4d", - ) - - def test_Us(self): - self.assertSequenceEqual( - GOST341194(128 * b"U", "id-GostR3411-94-TestParamSet").hexdigest(), - "53a3a3ed25180cef0c1d85a074273e551c25660a87062a52d926a9e8fe5733a4", - ) - - def test_dog(self): - self.assertSequenceEqual( - GOST341194(b"The quick brown fox jumps over the lazy dog", "id-GostR3411-94-TestParamSet",).hexdigest(), - "77b7fa410c9ac58a25f49bca7d0468c9296529315eaca76bd1a10f376d1f4294", - ) - - def test_cog(self): - self.assertSequenceEqual( - GOST341194(b"The quick brown fox jumps over the lazy cog", "id-GostR3411-94-TestParamSet",).hexdigest(), - "a3ebc4daaab78b0be131dab5737a7f67e602670d543521319150d2e14eeec445", - ) - - def test_rfc32(self): - self.assertSequenceEqual( - GOST341194(b"This is message, length=32 bytes", "id-GostR3411-94-TestParamSet",).hexdigest(), - "b1c466d37519b82e8319819ff32595e047a28cb6f83eff1c6916a815a637fffa", - ) - - def test_rfc50(self): - self.assertSequenceEqual( - GOST341194(b"Suppose the original message has length = 50 bytes", "id-GostR3411-94-TestParamSet",).hexdigest(), - "471aba57a60a770d3a76130635c1fbea4ef14de51f78b4ae57dd893b62f55208", - ) - - -class TestVectorsCryptoPro(TestCase): - """CryptoPro S-box test vectors - """ - def test_empty(self): - self.assertSequenceEqual( - GOST341194(b"", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0", - ) - - def test_a(self): - self.assertSequenceEqual( - GOST341194(b"a", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", - ) - - def test_abc(self): - self.assertSequenceEqual( - GOST341194(b"abc", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c", - ) - - def test_message_digest(self): - self.assertSequenceEqual( - GOST341194(b"message digest", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0", - ) - - def test_dog(self): - self.assertSequenceEqual( - GOST341194(b"The quick brown fox jumps over the lazy dog", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76", - ) - - def test_32(self): - self.assertSequenceEqual( - GOST341194(b"This is message, length=32 bytes", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb", - ) - - def test_50(self): - self.assertSequenceEqual( - GOST341194(b"Suppose the original message has length = 50 bytes", "id-GostR3411-94-CryptoProParamSet",).hexdigest(), - "c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011", - ) - - def test_Us(self): - self.assertSequenceEqual( - GOST341194(128 * b"U", "id-GostR3411-94-CryptoProParamSet").hexdigest(), - "1c4ac7614691bbf427fa2316216be8f10d92edfd37cd1027514c1008f649c4e8", - ) - - -class TestPBKDF2(TestCase): - """http://tc26.ru/methods/containers_v1/Addition_to_PKCS5_v1_0.pdf test vectors - """ - def test_1(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 1, 32)), - "7314e7c04fb2e662c543674253f68bd0b73445d07f241bed872882da21662d58", - ) - - def test_2(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 2, 32)), - "990dfa2bd965639ba48b07b792775df79f2db34fef25f274378872fed7ed1bb3", - ) - - def test_3(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 4096, 32)), - "1f1829a94bdff5be10d0aeb36af498e7a97467f3b31116a5a7c1afff9deadafe", - ) - - @skip("it takes too long") - def test_4(self): - self.assertSequenceEqual( - hexenc(pbkdf2(b"password", b"salt", 16777216, 32)), - "a57ae5a6088396d120850c5c09de0a525100938a59b1b5c3f7810910d05fcd97", - ) - - def test_5(self): - self.assertSequenceEqual( - hexenc(pbkdf2( - b"passwordPASSWORDpassword", - b"saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - 40, - )), - "788358c69cb2dbe251a7bb17d5f4241f265a792a35becde8d56f326b49c85047b7638acb4764b1fd", - ) - - def test_6(self): - self.assertSequenceEqual( - hexenc(pbkdf2( - b"pass\x00word", - b"sa\x00lt", - 4096, - 20, - )), - "43e06c5590b08c0225242373127edf9c8e9c3291", - ) diff --git a/pygost-5.13/pygost/test_gost3412.py b/pygost-5.13/pygost/test_gost3412.py deleted file mode 100644 index 5dbb200..0000000 --- a/pygost-5.13/pygost/test_gost3412.py +++ /dev/null @@ -1,137 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import TestCase - -from pygost.gost3412 import C -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3412 import L -from pygost.gost3412 import PI -from pygost.utils import hexdec - - -def S(blk): - return bytearray(PI[v] for v in blk) - - -def R(blk): - return L(blk, rounds=1) - - -class STest(TestCase): - def test_vec1(self): - blk = bytearray(hexdec("ffeeddccbbaa99881122334455667700")) - self.assertSequenceEqual(S(blk), hexdec("b66cd8887d38e8d77765aeea0c9a7efc")) - - def test_vec2(self): - blk = bytearray(hexdec("b66cd8887d38e8d77765aeea0c9a7efc")) - self.assertSequenceEqual(S(blk), hexdec("559d8dd7bd06cbfe7e7b262523280d39")) - - def test_vec3(self): - blk = bytearray(hexdec("559d8dd7bd06cbfe7e7b262523280d39")) - self.assertSequenceEqual(S(blk), hexdec("0c3322fed531e4630d80ef5c5a81c50b")) - - def test_vec4(self): - blk = bytearray(hexdec("0c3322fed531e4630d80ef5c5a81c50b")) - self.assertSequenceEqual(S(blk), hexdec("23ae65633f842d29c5df529c13f5acda")) - - -class RTest(TestCase): - def test_vec1(self): - blk = bytearray(hexdec("00000000000000000000000000000100")) - self.assertSequenceEqual(R(blk), hexdec("94000000000000000000000000000001")) - - def test_vec2(self): - blk = bytearray(hexdec("94000000000000000000000000000001")) - self.assertSequenceEqual(R(blk), hexdec("a5940000000000000000000000000000")) - - def test_vec3(self): - blk = bytearray(hexdec("a5940000000000000000000000000000")) - self.assertSequenceEqual(R(blk), hexdec("64a59400000000000000000000000000")) - - def test_vec4(self): - blk = bytearray(hexdec("64a59400000000000000000000000000")) - self.assertSequenceEqual(R(blk), hexdec("0d64a594000000000000000000000000")) - - -class LTest(TestCase): - def test_vec1(self): - blk = bytearray(hexdec("64a59400000000000000000000000000")) - self.assertSequenceEqual(L(blk), hexdec("d456584dd0e3e84cc3166e4b7fa2890d")) - - def test_vec2(self): - blk = bytearray(hexdec("d456584dd0e3e84cc3166e4b7fa2890d")) - self.assertSequenceEqual(L(blk), hexdec("79d26221b87b584cd42fbc4ffea5de9a")) - - def test_vec3(self): - blk = bytearray(hexdec("79d26221b87b584cd42fbc4ffea5de9a")) - self.assertSequenceEqual(L(blk), hexdec("0e93691a0cfc60408b7b68f66b513c13")) - - def test_vec4(self): - blk = bytearray(hexdec("0e93691a0cfc60408b7b68f66b513c13")) - self.assertSequenceEqual(L(blk), hexdec("e6a8094fee0aa204fd97bcb0b44b8580")) - - -class KuznechikTest(TestCase): - key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef") - plaintext = hexdec("1122334455667700ffeeddccbbaa9988") - ciphertext = hexdec("7f679d90bebc24305a468d42b9d4edcd") - - def test_c(self): - self.assertSequenceEqual(C[0], hexdec("6ea276726c487ab85d27bd10dd849401")) - self.assertSequenceEqual(C[1], hexdec("dc87ece4d890f4b3ba4eb92079cbeb02")) - self.assertSequenceEqual(C[2], hexdec("b2259a96b4d88e0be7690430a44f7f03")) - self.assertSequenceEqual(C[3], hexdec("7bcd1b0b73e32ba5b79cb140f2551504")) - self.assertSequenceEqual(C[4], hexdec("156f6d791fab511deabb0c502fd18105")) - self.assertSequenceEqual(C[5], hexdec("a74af7efab73df160dd208608b9efe06")) - self.assertSequenceEqual(C[6], hexdec("c9e8819dc73ba5ae50f5b570561a6a07")) - self.assertSequenceEqual(C[7], hexdec("f6593616e6055689adfba18027aa2a08")) - - def test_roundkeys(self): - ciph = GOST3412Kuznechik(self.key) - self.assertSequenceEqual(ciph.ks[0], hexdec("8899aabbccddeeff0011223344556677")) - self.assertSequenceEqual(ciph.ks[1], hexdec("fedcba98765432100123456789abcdef")) - self.assertSequenceEqual(ciph.ks[2], hexdec("db31485315694343228d6aef8cc78c44")) - self.assertSequenceEqual(ciph.ks[3], hexdec("3d4553d8e9cfec6815ebadc40a9ffd04")) - self.assertSequenceEqual(ciph.ks[4], hexdec("57646468c44a5e28d3e59246f429f1ac")) - self.assertSequenceEqual(ciph.ks[5], hexdec("bd079435165c6432b532e82834da581b")) - self.assertSequenceEqual(ciph.ks[6], hexdec("51e640757e8745de705727265a0098b1")) - self.assertSequenceEqual(ciph.ks[7], hexdec("5a7925017b9fdd3ed72a91a22286f984")) - self.assertSequenceEqual(ciph.ks[8], hexdec("bb44e25378c73123a5f32f73cdb6e517")) - self.assertSequenceEqual(ciph.ks[9], hexdec("72e9dd7416bcf45b755dbaa88e4a4043")) - - def test_encrypt(self): - ciph = GOST3412Kuznechik(self.key) - self.assertSequenceEqual(ciph.encrypt(self.plaintext), self.ciphertext) - - def test_decrypt(self): - ciph = GOST3412Kuznechik(self.key) - self.assertSequenceEqual(ciph.decrypt(self.ciphertext), self.plaintext) - - -class MagmaTest(TestCase): - key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") - plaintext = hexdec("fedcba9876543210") - ciphertext = hexdec("4ee901e5c2d8ca3d") - - def test_encrypt(self): - ciph = GOST3412Magma(self.key) - self.assertSequenceEqual(ciph.encrypt(self.plaintext), self.ciphertext) - - def test_decrypt(self): - ciph = GOST3412Magma(self.key) - self.assertSequenceEqual(ciph.decrypt(self.ciphertext), self.plaintext) diff --git a/pygost-5.13/pygost/test_gost3413.py b/pygost-5.13/pygost/test_gost3413.py deleted file mode 100644 index 0098513..0000000 --- a/pygost-5.13/pygost/test_gost3413.py +++ /dev/null @@ -1,766 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from random import randint -from unittest import TestCase - -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3413 import _mac_ks -from pygost.gost3413 import acpkm -from pygost.gost3413 import acpkm_master -from pygost.gost3413 import cbc_decrypt -from pygost.gost3413 import cbc_encrypt -from pygost.gost3413 import cfb_decrypt -from pygost.gost3413 import cfb_encrypt -from pygost.gost3413 import ctr -from pygost.gost3413 import ctr_acpkm -from pygost.gost3413 import ecb_decrypt -from pygost.gost3413 import ecb_encrypt -from pygost.gost3413 import KEYSIZE -from pygost.gost3413 import mac -from pygost.gost3413 import mac_acpkm_master -from pygost.gost3413 import ofb -from pygost.gost3413 import pad2 -from pygost.gost3413 import pad_iso10126 -from pygost.gost3413 import unpad2 -from pygost.gost3413 import unpad_iso10126 -from pygost.utils import hexdec -from pygost.utils import hexenc -from pygost.utils import strxor - - -class Pad2Test(TestCase): - def test_symmetric(self): - for _ in range(100): - for blocksize in (GOST3412Magma.blocksize, GOST3412Kuznechik.blocksize): - data = urandom(randint(0, blocksize * 3)) - self.assertSequenceEqual( - unpad2(pad2(data, blocksize), blocksize), - data, - ) - - -class GOST3412KuznechikModesTest(TestCase): - key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef") - ciph = GOST3412Kuznechik(key) - plaintext = "" - plaintext += "1122334455667700ffeeddccbbaa9988" - plaintext += "00112233445566778899aabbcceeff0a" - plaintext += "112233445566778899aabbcceeff0a00" - plaintext += "2233445566778899aabbcceeff0a0011" - iv = hexdec("1234567890abcef0a1b2c3d4e5f0011223344556677889901213141516171819") - - def test_ecb_vectors(self): - ciphtext = "" - ciphtext += "7f679d90bebc24305a468d42b9d4edcd" - ciphtext += "b429912c6e0032f9285452d76718d08b" - ciphtext += "f0ca33549d247ceef3f5a5313bd4b157" - ciphtext += "d0b09ccde830b9eb3a02c4c5aa8ada98" - self.assertSequenceEqual( - hexenc(ecb_encrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ecb_decrypt( - self.ciph.decrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - )), - self.plaintext, - ) - - def test_ecb_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = ecb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt) - self.assertSequenceEqual(ecb_decrypt( - ciph.decrypt, - GOST3412Kuznechik.blocksize, - ct, - ), pt) - - def test_ctr_vectors(self): - ciphtext = "" - ciphtext += "f195d8bec10ed1dbd57b5fa240bda1b8" - ciphtext += "85eee733f6a13e5df33ce4b33c45dee4" - ciphtext += "a5eae88be6356ed3d5e877f13564a3a5" - ciphtext += "cb91fab1f20cbab6d1c6d15820bdba73" - iv = self.iv[:GOST3412Kuznechik.blocksize // 2] - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_ctr_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Kuznechik.blocksize // 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = ctr(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(ctr( - ciph.encrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_ofb_vectors(self): - ciphtext = "" - ciphtext += "81800a59b1842b24ff1f795e897abd95" - ciphtext += "ed5b47a7048cfab48fb521369d9326bf" - ciphtext += "66a257ac3ca0b8b1c80fe7fc10288a13" - ciphtext += "203ebbc066138660a0292243f6903150" - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_ofb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Kuznechik.blocksize * 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(ofb( - ciph.encrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_ofb_manual(self): - iv = [urandom(GOST3412Kuznechik.blocksize) for _ in range(randint(2, 10))] - pt = [ - urandom(GOST3412Kuznechik.blocksize) - for _ in range(len(iv), len(iv) + randint(1, 10)) - ] - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - r = [ciph.encrypt(i) for i in iv] - for i in range(len(pt) - len(iv)): - r.append(ciph.encrypt(r[i])) - ct = [strxor(g, r) for g, r in zip(pt, r)] - self.assertSequenceEqual( - ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, b"".join(pt), b"".join(iv)), - b"".join(ct), - ) - - def test_cbc_vectors(self): - ciphtext = "" - ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27" - ciphtext += "2826e661b478eca6af1e8e448d5ea5ac" - ciphtext += "fe7babf1e91999e85640e8b0f49d90d0" - ciphtext += "167688065a895c631a2d9a1560b63970" - self.assertSequenceEqual( - hexenc(cbc_encrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cbc_decrypt( - self.ciph.decrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_cbc_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize) - iv = urandom(GOST3412Kuznechik.blocksize * 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = cbc_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(cbc_decrypt( - ciph.decrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_cfb_vectors(self): - ciphtext = "" - ciphtext += "81800a59b1842b24ff1f795e897abd95" - ciphtext += "ed5b47a7048cfab48fb521369d9326bf" - ciphtext += "79f2a8eb5cc68d38842d264e97a238b5" - ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1" - self.assertSequenceEqual( - hexenc(cfb_encrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cfb_decrypt( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_cfb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Kuznechik.blocksize * 2) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - ct = cfb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv) - self.assertSequenceEqual(cfb_decrypt( - ciph.encrypt, - GOST3412Kuznechik.blocksize, - ct, - iv, - ), pt) - - def test_mac_vectors(self): - k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(hexenc(k1), "297d82bc4d39e3ca0de0573298151dc7") - self.assertSequenceEqual(hexenc(k2), "52fb05789a73c7941bc0ae65302a3b8e") - self.assertSequenceEqual( - hexenc(mac( - self.ciph.encrypt, - GOST3412Kuznechik.blocksize, - hexdec(self.plaintext), - )[:8]), - "336f4d296059fbe3", - ) - - def test_mac_applies(self): - for _ in range(100): - data = urandom(randint(0, 16 * 2)) - ciph = GOST3412Kuznechik(urandom(KEYSIZE)) - mac(ciph.encrypt, GOST3412Kuznechik.blocksize, data) - - -class GOST3412MagmaModesTest(TestCase): - key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") - ciph = GOST3412Magma(key) - plaintext = "" - plaintext += "92def06b3c130a59" - plaintext += "db54c704f8189d20" - plaintext += "4a98fb2e67a8024c" - plaintext += "8912409b17b57e41" - iv = hexdec("1234567890abcdef234567890abcdef134567890abcdef12") - - def test_ecb_vectors(self): - ciphtext = "" - ciphtext += "2b073f0494f372a0" - ciphtext += "de70e715d3556e48" - ciphtext += "11d8d9e9eacfbc1e" - ciphtext += "7c68260996c67efb" - self.assertSequenceEqual( - hexenc(ecb_encrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ecb_decrypt( - self.ciph.decrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - )), - self.plaintext, - ) - - def test_ecb_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), 16) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = ecb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt) - self.assertSequenceEqual(ecb_decrypt( - ciph.decrypt, - GOST3412Magma.blocksize, - ct, - ), pt) - - def test_ctr_vectors(self): - ciphtext = "" - ciphtext += "4e98110c97b7b93c" - ciphtext += "3e250d93d6e85d69" - ciphtext += "136d868807b2dbef" - ciphtext += "568eb680ab52a12d" - iv = self.iv[:4] - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ctr( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_ctr_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Magma.blocksize // 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = ctr(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(ctr( - ciph.encrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_ofb_vectors(self): - iv = self.iv[:16] - ciphtext = "" - ciphtext += "db37e0e266903c83" - ciphtext += "0d46644c1f9a089c" - ciphtext += "a0f83062430e327e" - ciphtext += "c824efb8bd4fdb05" - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(ofb( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_ofb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Magma.blocksize * 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = ofb(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(ofb( - ciph.encrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_cbc_vectors(self): - ciphtext = "" - ciphtext += "96d1b05eea683919" - ciphtext += "aff76129abb937b9" - ciphtext += "5058b4a1c4bc0019" - ciphtext += "20b78b1a7cd7e667" - self.assertSequenceEqual( - hexenc(cbc_encrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - self.iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cbc_decrypt( - self.ciph.decrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - self.iv, - )), - self.plaintext, - ) - - def test_cbc_symmetric(self): - for _ in range(100): - pt = pad2(urandom(randint(0, 16 * 2)), 16) - iv = urandom(GOST3412Magma.blocksize * 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = cbc_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(cbc_decrypt( - ciph.decrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_cfb_vectors(self): - iv = self.iv[:16] - ciphtext = "" - ciphtext += "db37e0e266903c83" - ciphtext += "0d46644c1f9a089c" - ciphtext += "24bdd2035315d38b" - ciphtext += "bcc0321421075505" - self.assertSequenceEqual( - hexenc(cfb_encrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - iv, - )), - ciphtext, - ) - self.assertSequenceEqual( - hexenc(cfb_decrypt( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(ciphtext), - iv, - )), - self.plaintext, - ) - - def test_cfb_symmetric(self): - for _ in range(100): - pt = urandom(randint(0, 16 * 2)) - iv = urandom(GOST3412Magma.blocksize * 2) - ciph = GOST3412Magma(urandom(KEYSIZE)) - ct = cfb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv) - self.assertSequenceEqual(cfb_decrypt( - ciph.encrypt, - GOST3412Magma.blocksize, - ct, - iv, - ), pt) - - def test_mac_vectors(self): - k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(hexenc(k1), "5f459b3342521424") - self.assertSequenceEqual(hexenc(k2), "be8b366684a42848") - self.assertSequenceEqual( - hexenc(mac( - self.ciph.encrypt, - GOST3412Magma.blocksize, - hexdec(self.plaintext), - )[:4]), - "154e7210", - ) - - def test_mac_applies(self): - for _ in range(100): - data = urandom(randint(0, 16 * 2)) - ciph = GOST3412Magma(urandom(KEYSIZE)) - mac(ciph.encrypt, GOST3412Magma.blocksize, data) - - -class TestVectorACPKM(TestCase): - """Test vectors from Р 1323565.1.017-2018 - """ - key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF") - - def test_magma_ctr_acpkm(self): - key = acpkm(GOST3412Magma(self.key).encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(key, hexdec("863EA017842C3D372B18A85A28E2317D74BEFC107720DE0C9E8AB974ABD00CA0")) - key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(key, hexdec("49A5E2677DE555982B8AD5E826652D17EEC847BF5B3997A81CF7FE7F1187BD27")) - key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize) - self.assertSequenceEqual(key, hexdec("3256BF3F97B5667426A9FB1C5EAABE41893CCDD5A868F9B63B0AA90720FA43C4")) - - def test_magma_ctr(self): - encrypter = GOST3412Magma(self.key).encrypt - plaintext = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 -22 33 44 55 66 77 88 99 - """.replace("\n", "").replace(" ", "")) - iv = hexdec("12345678") - ciphertext = hexdec(""" -2A B8 1D EE EB 1E 4C AB 68 E1 04 C4 BD 6B 94 EA -C7 2C 67 AF 6C 2E 5B 6B 0E AF B6 17 70 F1 B3 2E -A1 AE 71 14 9E ED 13 82 AB D4 67 18 06 72 EC 6F -84 A2 F1 5B 3F CA 72 C1 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Magma, - encrypter, - bs=GOST3412Magma.blocksize, - section_size=GOST3412Magma.blocksize * 2, - data=plaintext, - iv=iv - ), - ciphertext, - ) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Magma, - encrypter, - bs=GOST3412Magma.blocksize, - section_size=GOST3412Magma.blocksize * 2, - data=ciphertext, - iv=iv - ), - plaintext, - ) - - def test_kuznechik_ctr_acpkm(self): - key = acpkm(GOST3412Kuznechik(self.key).encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(key, hexdec("2666ED40AE687811745CA0B448F57A7B390ADB5780307E8E9659AC403AE60C60")) - key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(key, hexdec("BB3DD5402E999B7A3DEBB0DB45448EC530F07365DFEE3ABA8415F77AC8F34CE8")) - key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize) - self.assertSequenceEqual(key, hexdec("23362FD553CAD2178299A5B5A2D4722E3BB83C730A8BF57CE2DD004017F8C565")) - - def test_kuznechik_ctr(self): - encrypter = GOST3412Kuznechik(self.key).encrypt - iv = hexdec("1234567890ABCEF0") - plaintext = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 -22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 -33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 -44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 -55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44 - """.replace("\n", "").replace(" ", "")) - ciphertext = hexdec(""" -F1 95 D8 BE C1 0E D1 DB D5 7B 5F A2 40 BD A1 B8 -85 EE E7 33 F6 A1 3E 5D F3 3C E4 B3 3C 45 DE E4 -4B CE EB 8F 64 6F 4C 55 00 17 06 27 5E 85 E8 00 -58 7C 4D F5 68 D0 94 39 3E 48 34 AF D0 80 50 46 -CF 30 F5 76 86 AE EC E1 1C FC 6C 31 6B 8A 89 6E -DF FD 07 EC 81 36 36 46 0C 4F 3B 74 34 23 16 3E -64 09 A9 C2 82 FA C8 D4 69 D2 21 E7 FB D6 DE 5D - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Kuznechik, - encrypter, - bs=GOST3412Kuznechik.blocksize, - section_size=GOST3412Kuznechik.blocksize * 2, - data=plaintext, - iv=iv, - ), - ciphertext, - ) - self.assertSequenceEqual( - ctr_acpkm( - GOST3412Kuznechik, - encrypter, - bs=GOST3412Kuznechik.blocksize, - section_size=GOST3412Kuznechik.blocksize * 2, - data=ciphertext, - iv=iv, - ), - plaintext, - ) - - def test_magma_omac_1_5_blocks(self): - encrypter = GOST3412Magma(self.key).encrypt - key_section_size = 640 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Magma, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Magma.blocksize, - keymat_len=KEYSIZE + GOST3412Magma.blocksize, - ), - hexdec("0DF2F5273DA328932AC49D81D36B2558A50DBF9BBCAC74A614B2CCB2F1CBCD8A70638E3DE8B3571E"), - ) - text = hexdec("1122334455667700FFEEDDCC") - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Magma, - encrypter, - key_section_size, - section_size=GOST3412Magma.blocksize * 2, - bs=GOST3412Magma.blocksize, - data=text, - ), - hexdec("A0540E3730ACBCF3"), - ) - - def test_magma_omac_5_blocks(self): - encrypter = GOST3412Magma(self.key).encrypt - key_section_size = 640 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Magma, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Magma.blocksize, - keymat_len=3 * (KEYSIZE + GOST3412Magma.blocksize), - ), - hexdec(""" -0D F2 F5 27 3D A3 28 93 2A C4 9D 81 D3 6B 25 58 -A5 0D BF 9B BC AC 74 A6 14 B2 CC B2 F1 CB CD 8A -70 63 8E 3D E8 B3 57 1E 8D 38 26 D5 5E 63 A1 67 -E2 40 66 40 54 7B 9F 1F 5F 2B 43 61 2A AE AF DA -18 0B AC 86 04 DF A6 FE 53 C2 CE 27 0E 9C 9F 52 -68 D0 FD BF E1 A3 BD D9 BE 5B 96 D0 A1 20 23 48 -6E F1 71 0F 92 4A E0 31 30 52 CB 5F CA 0B 79 1E -1B AB E8 57 6D 0F E3 A8 - """.replace("\n", "").replace(" ", "")), - ) - text = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Magma, - encrypter, - key_section_size, - section_size=GOST3412Magma.blocksize * 2, - bs=GOST3412Magma.blocksize, - data=text, - ), - hexdec("34008DAD5496BB8E"), - ) - - def test_kuznechik_omac_1_5_blocks(self): - encrypter = GOST3412Kuznechik(self.key).encrypt - key_section_size = 768 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Kuznechik.blocksize, - keymat_len=KEYSIZE + GOST3412Kuznechik.blocksize, - ), - hexdec(""" -0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2 -C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE -0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37 - """.replace("\n", "").replace(" ", "")) - ) - text = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size, - section_size=GOST3412Kuznechik.blocksize * 2, - bs=GOST3412Kuznechik.blocksize, - data=text, - ), - hexdec("B5367F47B62B995EEB2A648C5843145E"), - ) - - def test_kuznechik_omac_5_blocks(self): - encrypter = GOST3412Kuznechik(self.key).encrypt - key_section_size = 768 // 8 - self.assertSequenceEqual( - acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size=key_section_size, - bs=GOST3412Kuznechik.blocksize, - keymat_len=3 * (KEYSIZE + GOST3412Kuznechik.blocksize), - ), - hexdec(""" -0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2 -C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE -0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37 -C9 DD A8 9C FF A4 91 FE AD D9 B3 EA B7 03 BB 31 -BC 7E 92 7F 04 94 72 9F 51 B4 9D 3D F9 C9 46 08 -00 FB BC F5 ED EE 61 0E A0 2F 01 09 3C 7B C7 42 -D7 D6 27 15 01 B1 77 77 52 63 C2 A3 49 5A 83 18 -A8 1C 79 A0 4F 29 66 0E A3 FD A8 74 C6 30 79 9E -14 2C 57 79 14 FE A9 0D 3B C2 50 2E 83 36 85 D9 - """.replace("\n", "").replace(" ", "")), - ) - text = hexdec(""" -11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88 -00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A -11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 -22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 -33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 - """.replace("\n", "").replace(" ", "")) - self.assertSequenceEqual( - mac_acpkm_master( - GOST3412Kuznechik, - encrypter, - key_section_size, - section_size=GOST3412Kuznechik.blocksize * 2, - bs=GOST3412Kuznechik.blocksize, - data=text, - ), - hexdec("FBB8DCEE45BEA67C35F58C5700898E5D"), - ) - - -class ISO10126Test(TestCase): - def test_symmetric(self): - for _ in range(100): - for blocksize in (GOST3412Magma.blocksize, GOST3412Kuznechik.blocksize): - data = urandom(randint(0, blocksize * 3)) - padded = pad_iso10126(data, blocksize) - self.assertSequenceEqual(unpad_iso10126(padded, blocksize), data) - with self.assertRaises(ValueError): - unpad_iso10126(padded[1:], blocksize) - - def test_small(self): - with self.assertRaises(ValueError): - unpad_iso10126(b"foobar\x00\x09", 8) diff --git a/pygost-5.13/pygost/test_kdf.py b/pygost-5.13/pygost/test_kdf.py deleted file mode 100644 index 6921cfc..0000000 --- a/pygost-5.13/pygost/test_kdf.py +++ /dev/null @@ -1,58 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from unittest import TestCase - -from pygost.kdf import kdf_gostr3411_2012_256 -from pygost.kdf import kdf_tree_gostr3411_2012_256 -from pygost.utils import hexdec - - -class TestKDFGOSTR34112012256(TestCase): - def runTest(self): - self.assertEqual( - kdf_gostr3411_2012_256( - hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - hexdec("26bdb878"), - hexdec("af21434145656378"), - ), - hexdec("a1aa5f7de402d7b3d323f2991c8d4534013137010a83754fd0af6d7cd4922ed9"), - ) - - -class TestKDFTREEGOSTR34112012256(TestCase): - def runTest(self): - self.assertSequenceEqual( - kdf_tree_gostr3411_2012_256( - hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - hexdec("26bdb878"), - hexdec("af21434145656378"), - 1, - ), - (hexdec("a1aa5f7de402d7b3d323f2991c8d4534013137010a83754fd0af6d7cd4922ed9"),), - ) - self.assertSequenceEqual( - kdf_tree_gostr3411_2012_256( - hexdec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - hexdec("26bdb878"), - hexdec("af21434145656378"), - 2, - ), - ( - hexdec("22b6837845c6bef65ea71672b265831086d3c76aebe6dae91cad51d83f79d16b"), - hexdec("074c9330599d7f8d712fca54392f4ddde93751206b3584c8f43f9e6dc51531f9"), - ), - ) diff --git a/pygost-5.13/pygost/test_mgm.py b/pygost-5.13/pygost/test_mgm.py deleted file mode 100644 index e70a7f5..0000000 --- a/pygost-5.13/pygost/test_mgm.py +++ /dev/null @@ -1,75 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from random import randint -from unittest import TestCase - -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3412 import KEYSIZE -from pygost.mgm import MGM -from pygost.mgm import nonce_prepare -from pygost.utils import hexdec - - -class TestVector(TestCase): - def runTest(self): - key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF") - ad = hexdec("0202020202020202010101010101010104040404040404040303030303030303EA0505050505050505") - plaintext = hexdec("1122334455667700FFEEDDCCBBAA998800112233445566778899AABBCCEEFF0A112233445566778899AABBCCEEFF0A002233445566778899AABBCCEEFF0A0011AABBCC") - mgm = MGM(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize) - ciphertext = mgm.seal(plaintext[:16], plaintext, ad) - self.assertSequenceEqual(ciphertext[:len(plaintext)], hexdec("A9757B8147956E9055B8A33DE89F42FC8075D2212BF9FD5BD3F7069AADC16B39497AB15915A6BA85936B5D0EA9F6851CC60C14D4D3F883D0AB94420695C76DEB2C7552")) - self.assertSequenceEqual(ciphertext[len(plaintext):], hexdec("CF5D656F40C34F5C46E8BB0E29FCDB4C")) - self.assertSequenceEqual(mgm.open(plaintext[:16], ciphertext, ad), plaintext) - - -class TestSymmetric(TestCase): - def _itself(self, mgm, bs, tag_size): - for _ in range(1000): - nonce = nonce_prepare(urandom(bs)) - ad = urandom(randint(0, 20)) - pt = urandom(randint(0, 20)) - if len(ad) + len(pt) == 0: - continue - ct = mgm.seal(nonce, pt, ad) - self.assertEqual(len(ct) - tag_size, len(pt)) - self.assertSequenceEqual(mgm.open(nonce, ct, ad), pt) - - def test_magma(self): - for tag_size in ( - GOST3412Magma.blocksize, - GOST3412Magma.blocksize - 2, - ): - mgm = MGM( - GOST3412Magma(urandom(KEYSIZE)).encrypt, - GOST3412Magma.blocksize, - tag_size, - ) - self._itself(mgm, GOST3412Magma.blocksize, tag_size) - - def test_kuznechik(self): - for tag_size in ( - GOST3412Kuznechik.blocksize, - GOST3412Kuznechik.blocksize - 2, - ): - mgm = MGM( - GOST3412Kuznechik(urandom(KEYSIZE)).encrypt, - GOST3412Kuznechik.blocksize, - tag_size, - ) - self._itself(mgm, GOST3412Kuznechik.blocksize, tag_size) diff --git a/pygost-5.13/pygost/test_pfx.py b/pygost-5.13/pygost/test_pfx.py deleted file mode 100644 index a2760bf..0000000 --- a/pygost-5.13/pygost/test_pfx.py +++ /dev/null @@ -1,680 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from base64 import b64decode -from hmac import new as hmac_new -from unittest import skipIf -from unittest import TestCase - -from pygost import gost3410 -from pygost.gost28147 import cfb_decrypt -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.gost34112012512 import pbkdf2 as gost34112012_pbkdf2 -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.gost3412 import KEYSIZE -from pygost.gost3413 import ctr_acpkm -from pygost.gost3413 import mac as omac -from pygost.kdf import kdf_tree_gostr3411_2012_256 -from pygost.kdf import keg -from pygost.utils import hexdec -from pygost.wrap import kimp15 - - -try: - from pyderasn import OctetString - - from pygost.asn1schemas.cms import EncryptedData - from pygost.asn1schemas.cms import EnvelopedData - from pygost.asn1schemas.cms import SignedAttributes - from pygost.asn1schemas.cms import SignedData - from pygost.asn1schemas.oids import id_data - from pygost.asn1schemas.oids import id_envelopedData - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm - from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_wrap_kexp15 - from pygost.asn1schemas.oids import id_messageDigest - from pygost.asn1schemas.oids import id_pbes2 - from pygost.asn1schemas.oids import id_pkcs12_bagtypes_certBag - from pygost.asn1schemas.oids import id_pkcs12_bagtypes_keyBag - from pygost.asn1schemas.oids import id_pkcs12_bagtypes_pkcs8ShroudedKeyBag - from pygost.asn1schemas.oids import id_pkcs9_certTypes_x509Certificate - from pygost.asn1schemas.oids import id_signedData - from pygost.asn1schemas.oids import id_tc26_agreement_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_256 - from pygost.asn1schemas.pfx import CertBag - from pygost.asn1schemas.pfx import KeyBag - from pygost.asn1schemas.pfx import OctetStringSafeContents - from pygost.asn1schemas.pfx import PBES2Params - from pygost.asn1schemas.pfx import PFX - from pygost.asn1schemas.pfx import PKCS8ShroudedKeyBag - from pygost.asn1schemas.pfx import SafeContents - from pygost.asn1schemas.x509 import Certificate -except ImportError: - pyderasn_exists = False -else: - pyderasn_exists = True - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestPFX(TestCase): - """PFX test vectors from "Транспортный ключевой контейнер" (R50.1.112-2016.pdf) - """ - pfx_raw = b64decode(""" -MIIFqgIBAzCCBSsGCSqGSIb3DQEHAaCCBRwEggUYMIIFFDCCASIGCSqGSIb3DQEH -AaCCARMEggEPMIIBCzCCAQcGCyqGSIb3DQEMCgECoIHgMIHdMHEGCSqGSIb3DQEF -DTBkMEEGCSqGSIb3DQEFDDA0BCD5qZr0TTIsBvdgUoq/zFwOzdyJohj6/4Wiyccg -j9AK/QICB9AwDAYIKoUDBwEBBAIFADAfBgYqhQMCAhUwFQQI3Ip/Vp0IsyIGCSqF -AwcBAgUBAQRoSfLhgx9s/zn+BjnhT0ror07vS55Ys5hgvVpWDx4mXGWWyez/2sMc -aFgSr4H4UTGGwoMynGLpF1IOVo+bGJ0ePqHB+gS5OL9oV+PUmZ/ELrRENKlCDqfY -WvpSystX29CvCFrnTnDsbBYxFTATBgkqhkiG9w0BCRUxBgQEAQAAADCCA+oGCSqG -SIb3DQEHBqCCA9swggPXAgEAMIID0AYJKoZIhvcNAQcBMHEGCSqGSIb3DQEFDTBk -MEEGCSqGSIb3DQEFDDA0BCCJTJLZQRi1WIpQHzyjXbq7+Vw2+1280C45x8ff6kMS -VAICB9AwDAYIKoUDBwEBBAIFADAfBgYqhQMCAhUwFQQIxepowwvS11MGCSqFAwcB -AgUBAYCCA06n09P/o+eDEKoSWpvlpOLKs7dKmVquKzJ81nCngvLQ5fEWL1WkxwiI -rEhm53JKLD0wy4hekalEk011Bvc51XP9gkDkmaoBpnV/TyKIY35wl6ATfeGXno1M -KoA+Ktdhv4gLnz0k2SXdkUj11JwYskXue+REA0p4m2ZsoaTmvoODamh9JeY/5Qjy -Xe58CGnyXFzX3eU86qs4WfdWdS3NzYYOk9zzVl46le9u79O/LnW2j4n2of/Jpk/L -YjrRmz5oYeQOqKOKhEyhpO6e+ejr6laduEv7TwJQKRNiygogbVvkNn3VjHTSOUG4 -W+3NRPhjb0jD9obdyx6MWa6O3B9bUzFMNav8/gYn0vTDxqXMLy/92oTngNrVx6Gc -cNl128ISrDS6+RxtAMiEBRK6xNkemqX5yNXG5GrLQQFGP6mbs2nNpjKlgj3pljmX -Eky2/G78XiJrv02OgGs6CKnI9nMpa6N7PBHV34MJ6EZzWOWDRQ420xk63mnicrs0 -WDVJ0xjdu4FW3iEk02EaiRTvGBpa6GL7LBp6QlaXSSwONx725cyRsL9cTlukqXER -WHDlMpjYLbkGZRrCc1myWgEfsputfSIPNF/oLv9kJNWacP3uuDOfecg3us7eg2OA -xo5zrYfn39GcBMF1WHAYRO/+PnJb9jrDuLAE8+ONNqjNulWNK9CStEhb6Te+yE6q -oeP6hJjFLi+nFLE9ymIo0A7gLQD5vzFvl+7v1ZNVnQkwRUsWoRiEVVGnv3Z1iZU6 -xStxgoHMl62V/P5cz4dr9vJM2adEWNZcVXl6mk1H8DRc1sRGnvs2l237oKWRVntJ -hoWnZ8qtD+3ZUqsX79QhVzUQBzKuBt6jwNhaHLGl5B+Or/zA9FezsOh6+Uc+fZaV -W7fFfeUyWwGy90XD3ybTrjzep9f3nt55Z2c+fu2iEwhoyImWLuC3+CVhf9Af59j9 -8/BophMJuATDJEtgi8rt4vLnfxKu250Mv2ZpbfF69EGTgFYbwc55zRfaUG9zlyCu -1YwMJ6HC9FUVtJp9gObSrirbzTH7mVaMjQkBLotazWbegzI+be8V3yT06C+ehD+2 -GdLWAVs9hp8gPHEUShb/XrgPpDSJmFlOiyeOFBO/j4edDACKqVcwdjBOMAoGCCqF -AwcBAQIDBEAIFX0fyZe20QKKhWm6WYX+S92Gt6zaXroXOvAmayzLfZ5Sd9C2t9zZ -JSg6M8RBUYpw/8ym5ou1o2nDa09M5zF3BCCpzyCQBI+rzfISeKvPV1ROfcXiYU93 -mwcl1xQV2G5/fgICB9A= - """) - password = u"Пароль для PFX" - - def test_shrouded_key_bag(self): - private_key_info_expected = b64decode(b""" -MGYCAQAwHwYIKoUDBwEBAQEwEwYHKoUDAgIjAQYIKoUDBwEBAgIEQEYbRu86z+1JFKDcPDN9UbTG -G2ki9enTqos4KpUU0j9IDpl1UXiaA1YDIwUjlAp+81GkLmyt8Fw6Gt/X5JZySAY= - """) - - pfx, tail = PFX().decode(self.pfx_raw) - self.assertSequenceEqual(tail, b"") - _, outer_safe_contents = pfx["authSafe"]["content"].defined - safe_contents, tail = OctetStringSafeContents().decode( - bytes(outer_safe_contents[0]["bagValue"]), - ) - self.assertSequenceEqual(tail, b"") - safe_bag = safe_contents[0] - shrouded_key_bag, tail = PKCS8ShroudedKeyBag().decode( - bytes(safe_bag["bagValue"]), - ) - self.assertSequenceEqual(tail, b"") - _, pbes2_params = shrouded_key_bag["encryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - - key = gost34112012_pbkdf2( - password=self.password.encode("utf-8"), - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("309dd0354c5603739403f2335e9e2055138f8b5c98b63009de0635eea1fd7ba8") - self.assertSequenceEqual( - cfb_decrypt( - key, - bytes(shrouded_key_bag["encryptedData"]), - iv=bytes(enc_scheme_params["iv"]), - sbox="id-tc26-gost-28147-param-Z", - ), - private_key_info_expected, - ) - - def test_encrypted_data(self): - cert_bag_expected = b64decode(b""" -MIIDSjCCA0YGCyqGSIb3DQEMCgEDoIIDHjCCAxoGCiqGSIb3DQEJFgGgggMKBIIDBjCCAwIwggKt -oAMCAQICEAHQaF8xH5bAAAAACycJAAEwDAYIKoUDBwEBAwIFADBgMQswCQYDVQQGEwJSVTEVMBMG -A1UEBwwM0JzQvtGB0LrQstCwMQ8wDQYDVQQKDAbQotCaMjYxKTAnBgNVBAMMIENBIGNlcnRpZmlj -YXRlIChQS0NTIzEyIGV4YW1wbGUpMB4XDTE1MDMyNzA3MjUwMFoXDTIwMDMyNzA3MjMwMFowZDEL -MAkGA1UEBhMCUlUxFTATBgNVBAcMDNCc0L7RgdC60LLQsDEPMA0GA1UECgwG0KLQmjI2MS0wKwYD -VQQDDCRUZXN0IGNlcnRpZmljYXRlIDEgKFBLQ1MjMTIgZXhhbXBsZSkwZjAfBggqhQMHAQEBATAT -BgcqhQMCAiMBBggqhQMHAQECAgNDAARA1xzymkpvr2dYJT8WTOX3Dt96/+hGsXNytUQpkWB5ImJM -4tg9AsC4RIUwV5H41MhG0uBRFweTzN6AsAdBvhTClYEJADI3MDkwMDAxo4IBKTCCASUwKwYDVR0Q -BCQwIoAPMjAxNTAzMjcwNzI1MDBagQ8yMDE2MDMyNzA3MjUwMFowDgYDVR0PAQH/BAQDAgTwMB0G -A1UdDgQWBBQhWOsRQ68yYN2Utg/owHoWcqsVbTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH -AwQwDAYDVR0TAQH/BAIwADCBmQYDVR0jBIGRMIGOgBQmnc7Xh5ykb5t/BMwOkxA4drfEmqFkpGIw -YDELMAkGA1UEBhMCUlUxFTATBgNVBAcMDNCc0L7RgdC60LLQsDEPMA0GA1UECgwG0KLQmjI2MSkw -JwYDVQQDDCBDQSBjZXJ0aWZpY2F0ZSAoUEtDUyMxMiBleGFtcGxlKYIQAdBoXvL8TSAAAAALJwkA -ATAMBggqhQMHAQEDAgUAA0EA9oq0Vvk8kkgIwkp0x0J5eKtia4MNTiwKAm7jgnCZIx3O98BThaTX -3ZQhEo2RL9pTCPr6wFMheeJ+YdGMReXvsjEVMBMGCSqGSIb3DQEJFTEGBAQBAAAA - """) - - pfx, tail = PFX().decode(self.pfx_raw) - self.assertSequenceEqual(tail, b"") - _, outer_safe_contents = pfx["authSafe"]["content"].defined - _, encrypted_data = outer_safe_contents[1]["bagValue"].defined - _, pbes2_params = encrypted_data["encryptedContentInfo"]["contentEncryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - key = gost34112012_pbkdf2( - password=self.password.encode("utf-8"), - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("0e93d71339e7f53b79a0bc41f9109dd4fb60b30ae10736c1bb77b84c07681cfc") - self.assertSequenceEqual( - cfb_decrypt( - key, - bytes(encrypted_data["encryptedContentInfo"]["encryptedContent"]), - iv=bytes(enc_scheme_params["iv"]), - sbox="id-tc26-gost-28147-param-Z", - ), - cert_bag_expected, - ) - - def test_mac(self): - pfx, tail = PFX().decode(self.pfx_raw) - self.assertSequenceEqual(tail, b"") - _, outer_safe_contents = pfx["authSafe"]["content"].defined - mac_data = pfx["macData"] - mac_key = gost34112012_pbkdf2( - password=self.password.encode("utf-8"), - salt=bytes(mac_data["macSalt"]), - iterations=int(mac_data["iterations"]), - dklen=96, - )[-32:] - # mac_key = hexdec("cadbfbf3bceaa9b79f651508fac5abbeb4a13d0bd0e1876bd3c3efb2112128a5") - self.assertSequenceEqual( - hmac_new( - key=mac_key, - msg=SafeContents(outer_safe_contents).encode(), - digestmod=GOST34112012512, - ).digest(), - bytes(mac_data["mac"]["digest"]), - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestPFX2020(TestCase): - """PFX test vectors from newer PKCS#12 update - """ - ca_prv_raw = hexdec("092F8D059E97E22B90B1AE99F0087FC4D26620B91550CBB437C191005A290810") - ca_curve = gost3410.CURVES["id-tc26-gost-3410-12-256-paramSetA"] - ca_cert = Certificate().decod(b64decode(b""" - MIIB+TCCAaagAwIBAgIEAYy6gTAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2MS - cwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEwMTAx - MDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA4MQ0wCwYDVQQKEwRUSzI2MScwJQYDVQQDEx - 5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwXjAXBggqhQMHAQEBATALBgkq - hQMHAQIBAQEDQwAEQBpKgpyPDnhQAJyLqy8Qs0XQhgxEhby6tSypqYimgbjpcKqtU6 - 4jpDXc3h3BxGxtl2oHJ/4YLZ/ll87dto3ltMqjgZgwgZUwYwYDVR0jBFwwWoAUrGwO - TERmokKW4p8JOyVm88ukUyqhPKQ6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMTHk - NBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQUrGwO - TERmokKW4p8JOyVm88ukUyowDwYDVR0TAQH/BAUwAwEB/zAKBggqhQMHAQEDAgNBAB - Gg3nhgQ5oCKbqlEdVaRxH+1WX4wVkawGXuTYkr1AC2OWw3ZC14Vvg3nazm8UMWUZtk - vu1kJcHQ4jFKkjUeg2E= - """)) - ca_pub = gost3410.pub_unmarshal(bytes(OctetString().decod(bytes( - ca_cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - )))) - password = u"Пароль для PFX".encode("utf-8") - cert_test = Certificate().decod(b64decode(b""" - MIICLjCCAdugAwIBAgIEAYy6hDAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2MS - cwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEwMTAx - MDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYDVQQDEy - FPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDUxMi1iaXQwgaAwFwYIKoUDBwEBAQIw - CwYJKoUDBwECAQIBA4GEAASBgLSLt1q8KQ4YZVxioU+1LV9QhE7MHR9gBEh7S1yVNG - lqt7+rNG5VFqmrPM74rbUsOlhV8M+zZKprXdk35Oz8lSW/n2oIUHZxikXIH/SSHj4r - v3K/Puvz7hYTQSZl/xPdp78nUmjrEa6d5wfX8biEy2z0dgufFvAkMw1Ua4gdXqDOo4 - GHMIGEMGMGA1UdIwRcMFqAFKxsDkxEZqJCluKfCTslZvPLpFMqoTykOjA4MQ0wCwYD - VQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaX - SCBAGMuoEwHQYDVR0OBBYEFH4GVwmYDK1rCKhX7nkAWDrJ16CkMAoGCCqFAwcBAQMC - A0EACl6p8dAbpi9Hk+3mgMyI0WIh17IrlrSp/mB0F7ZzMt8XUD1Dwz3JrrnxeXnfMv - OA5BdUJ9hCyDgMVAGs/IcEEA== - """)) - prv_test_raw = b64decode(""" - MIHiAgEBMBcGCCqFAwcBAQECMAsGCSqFAwcBAgECAQRAEWkl+eblsHWs86SNgRKq - SxMOgGhbvR/uZ5/WWfdNG1axvUwVhpcXIxDZUmzQuNzqJBkseI7f5/JjXyTFRF1a - +YGBgQG0i7davCkOGGVcYqFPtS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO - +K21LDpYVfDPs2Sqa13ZN+Ts/JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0Em - Zf8T3ae/J1Jo6xGunecH1/G4hMts9HYLnxbwJDMNVGuIHV6gzg== - """) - - def test_cert_and_encrypted_key(self): - pfx_raw = b64decode(b""" - MIIFKwIBAzCCBMQGCSqGSIb3DQEHAaCCBLUEggSxMIIErTCCAswGCSqGSIb3DQEH - AaCCAr0EggK5MIICtTCCArEGCyqGSIb3DQEMCgEDoIICSjCCAkYGCiqGSIb3DQEJ - FgGgggI2BIICMjCCAi4wggHboAMCAQICBAGMuoQwCgYIKoUDBwEBAwIwODENMAsG - A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0MB4XDTAxMDEwMTAwMDAwMFoXDTQ5MTIzMTAwMDAwMFowOzENMAsGA1UEChME - VEsyNjEqMCgGA1UEAxMhT1JJR0lOQVRPUjogR09TVCAzNC4xMC0xMiA1MTItYml0 - MIGgMBcGCCqFAwcBAQECMAsGCSqFAwcBAgECAQOBhAAEgYC0i7davCkOGGVcYqFP - tS1fUIROzB0fYARIe0tclTRpare/qzRuVRapqzzO+K21LDpYVfDPs2Sqa13ZN+Ts - /JUlv59qCFB2cYpFyB/0kh4+K79yvz7r8+4WE0EmZf8T3ae/J1Jo6xGunecH1/G4 - hMts9HYLnxbwJDMNVGuIHV6gzqOBhzCBhDBjBgNVHSMEXDBagBSsbA5MRGaiQpbi - nwk7JWbzy6RTKqE8pDowODENMAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsy - NjogR09TVCAzNC4xMC0xMiAyNTYtYml0ggQBjLqBMB0GA1UdDgQWBBR+BlcJmAyt - awioV+55AFg6ydegpDAKBggqhQMHAQEDAgNBAApeqfHQG6YvR5Pt5oDMiNFiIdey - K5a0qf5gdBe2czLfF1A9Q8M9ya658Xl53zLzgOQXVCfYQsg4DFQBrPyHBBAxVDAj - BgkqhkiG9w0BCRUxFgQUeVV0+dS25MICJChpmGc/8AoUwE0wLQYJKoZIhvcNAQkU - MSAeHgBwADEAMgBGAHIAaQBlAG4AZABsAHkATgBhAG0AZTCCAdkGCSqGSIb3DQEH - AaCCAcoEggHGMIIBwjCCAb4GCyqGSIb3DQEMCgECoIIBVzCCAVMwWQYJKoZIhvcN - AQUNMEwwKQYJKoZIhvcNAQUMMBwECKf4N7NMwugqAgIIADAMBggqhQMHAQEEAgUA - MB8GCSqFAwcBAQUCAjASBBAlmt2WDfaPJlsAs0mLKglzBIH1DMvEacbbWRNDVSnX - JLWygYrKoipdOjDA/2HEnBZ34uFOLNheUqiKpCPoFpbR2GBiVYVTVK9ibiczgaca - EQYzDXtcS0QCZOxpKWfteAlbdJLC/SqPurPYyKi0MVRUPROhbisFASDT38HDH1Dh - 0dL5f6ga4aPWLrWbbgWERFOoOPyh4DotlPF37AQOwiEjsbyyRHq3HgbWiaxQRuAh - eqHOn4QVGY92/HFvJ7u3TcnQdLWhTe/lh1RHLNF3RnXtN9if9zC23laDZOiWZplU - yLrUiTCbHrtn1RppPDmLFNMt9dJ7KKgCkOi7Zm5nhqPChbywX13wcfYxVDAjBgkq - hkiG9w0BCRUxFgQUeVV0+dS25MICJChpmGc/8AoUwE0wLQYJKoZIhvcNAQkUMSAe - HgBwADEAMgBGAHIAaQBlAG4AZABsAHkATgBhAG0AZTBeME4wCgYIKoUDBwEBAgME - QAkBKw4ihn7pSIYTEhu0bcvTPZjI3WgVxCkUVlOsc80G69EKFEOTnObGJGSKJ51U - KkOsXF0a7+VBZf3BcVVQh9UECIVEtO+VpuskAgIIAA== - """) - pfx = PFX().decod(pfx_raw) - _, outer_safe_contents = pfx["authSafe"]["content"].defined - - safe_contents = OctetStringSafeContents().decod(bytes( - outer_safe_contents[0]["bagValue"] - )) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_certBag) - cert_bag = CertBag().decod(bytes(safe_bag["bagValue"])) - self.assertEqual(cert_bag["certId"], id_pkcs9_certTypes_x509Certificate) - _, cert = cert_bag["certValue"].defined - self.assertEqual(Certificate(cert), self.cert_test) - - safe_contents = OctetStringSafeContents().decod(bytes( - outer_safe_contents[1]["bagValue"] - )) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_pkcs8ShroudedKeyBag) - shrouded_key_bag = PKCS8ShroudedKeyBag().decod(bytes(safe_bag["bagValue"])) - _, pbes2_params = shrouded_key_bag["encryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - ukm = bytes(enc_scheme_params["ukm"]) - key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("4b7ae649ca31dd5fe3243a91a5188c03f1d7049bec8e0d241c0e1e8c39ea4c1f") - key_enc, key_mac = kdf_tree_gostr3411_2012_256( - key, b"kdf tree", ukm[GOST3412Kuznechik.blocksize // 2:], 2, - ) - ciphertext = bytes(shrouded_key_bag["encryptedData"]) - plaintext = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(key_enc).encrypt, - section_size=256 * 1024, - bs=GOST3412Kuznechik.blocksize, - data=ciphertext, - iv=ukm[:GOST3412Kuznechik.blocksize // 2], - ) - mac_expected = plaintext[-GOST3412Kuznechik.blocksize:] - plaintext = plaintext[:-GOST3412Kuznechik.blocksize] - mac = omac( - GOST3412Kuznechik(key_mac).encrypt, - GOST3412Kuznechik.blocksize, - plaintext, - ) - self.assertSequenceEqual(mac, mac_expected) - self.assertSequenceEqual(plaintext, self.prv_test_raw) - - mac_data = pfx["macData"] - mac_key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(mac_data["macSalt"]), - iterations=int(mac_data["iterations"]), - dklen=96, - )[-32:] - # mac_key = hexdec("a81d1bc91a4a5cf1fd7320f92dda7e5b285816c3b20826a382d7ed0cbf3a9bf4") - self.assertSequenceEqual( - hmac_new( - key=mac_key, - msg=SafeContents(outer_safe_contents).encode(), - digestmod=GOST34112012512, - ).digest(), - bytes(mac_data["mac"]["digest"]), - ) - self.assertTrue(gost3410.verify( - self.ca_curve, - self.ca_pub, - GOST34112012256(cert["tbsCertificate"].encode()).digest()[::-1], - bytes(cert["signatureValue"]), - )) - - def test_encrypted_cert_and_key(self): - pfx_raw = b64decode(b""" - MIIFjAIBAzCCBSUGCSqGSIb3DQEHAaCCBRYEggUSMIIFDjCCA0EGCSqGSIb3DQEH - BqCCAzIwggMuAgEAMIIDJwYJKoZIhvcNAQcBMFUGCSqGSIb3DQEFDTBIMCkGCSqG - SIb3DQEFDDAcBAgUuSVGsSwGjQICCAAwDAYIKoUDBwEBBAIFADAbBgkqhQMHAQEF - AQIwDgQM9Hk3dagtS48+G/x+gIICwWGPqxxN+sTrKbruRf9R5Ya9cf5AtO1frqMn - f1eULfmZmTg/BdE51QQ+Vbnh3v1kmspr6h2+e4Wli+ndEeCWG6A6X/G22h/RAHW2 - YrVmf6cCWxW+YrqzT4h/8RQL/9haunD5LmHPLVsYrEai0OwbgXayDSwARVJQLQYq - sLNmZK5ViN+fRiS5wszVJ3AtVq8EuPt41aQEKwPy2gmH4S6WmnQRC6W7aoqmIifF - PJENJNn5K2M1J6zNESs6bFtYNKMArNqtvv3rioY6eAaaLy6AV6ljsekmqodHmQjv - Y4eEioJs0xhpXhZY69PXT+ZBeHv6MSheBhwXqxAd1DqtPTafMjNK8rqKCap9TtPG - vONvo5W9dgwegxRRQzlum8dzV4m1W9Aq4W7t8/UcxDWRz3k6ijFPlGaA9+8ZMTEO - RHhBRvM6OY2/VNNxbgxWfGYuPxpSi3YnCZIPmBEe5lU/Xv7KjzFusGM38F8YR61k - 4/QNpKI1QUv714YKfaUQznshGGzILv1NGID62pl1+JI3vuawi2mDMrmkuM9QFU9v - /kRP+c2uBHDuOGEUUSNhF08p7+w3vxplatGWXH9fmIsPBdk2f3wkn+rwoqrEuijM - I/bCAylU/M0DMKhAo9j31UYSZdi4fsfRWYDJMq/8FPn96tuo+oCpbqv3NUwpZM/8 - Li4xqgTHtYw/+fRG0/P6XadNEiII/TYjenLfVHXjAHOVJsVeCu/t3EsMYHQddNCh - rFk/Ic2PdIQOyB4/enpW0qrKegSbyZNuF1WI4zl4mI89L8dTQBUkhy45yQXZlDD8 - k1ErYdtdEsPtz/4zuSpbnmwCEIRoOuSXtGuJP+tbcWEXRKM2UBgi3qBjpn7DU18M - tsrRM9pDdadl8mT/Vfh9+B8dZBZVxgQu70lMPEGexbUkYHuFCCnyi9J0V92StbIz - Elxla1VebjCCAcUGCSqGSIb3DQEHAaCCAbYEggGyMIIBrjCCAaoGCyqGSIb3DQEM - CgECoIIBQzCCAT8wVQYJKoZIhvcNAQUNMEgwKQYJKoZIhvcNAQUMMBwECP0EQk0O - 1twvAgIIADAMBggqhQMHAQEEAgUAMBsGCSqFAwcBAQUBATAOBAzwxSqgAAAAAAAA - AAAEgeUqj9mI3RDfK5hMd0EeYws7foZK/5ANr2wUhP5qnDjAZgn76lExJ+wuvlnS - 9PChfWVugvdl/9XJgQvvr9Cu4pOh4ICXplchcy0dGk/MzItHRVC5wK2nTxwQ4kKT - kG9xhLFzoD16dhtqX0+/dQg9G8pE5EzCBIYRXLm1Arcz9k7KVsTJuNMjFrr7EQuu - Tr80ATSQOtsq50zpFyrpznVPGCrOdIjpymZxNdvw48bZxqTtRVDxCYATOGqz0pwH - ClWULHD9LIajLMB2GhBKyQw6ujIlltJs0T+WNdX/AT2FLi1LFSS3+Cj9MVQwIwYJ - KoZIhvcNAQkVMRYEFHlVdPnUtuTCAiQoaZhnP/AKFMBNMC0GCSqGSIb3DQEJFDEg - Hh4AcAAxADIARgByAGkAZQBuAGQAbAB5AE4AYQBtAGUwXjBOMAoGCCqFAwcBAQID - BEDp4e22JmXdnvR0xA99yQuzQuJ8pxBeOpsLm2dZQqt3Fje5zqW1uk/7VOcfV5r2 - bKm8nsLOs2rPT8hBOoeAZvOIBAjGIUHw6IjG2QICCAA= - """) - pfx = PFX().decod(pfx_raw) - _, outer_safe_contents = pfx["authSafe"]["content"].defined - - encrypted_data = EncryptedData().decod(bytes( - outer_safe_contents[0]["bagValue"] - )) - eci = encrypted_data["encryptedContentInfo"] - self.assertEqual(eci["contentEncryptionAlgorithm"]["algorithm"], id_pbes2) - pbes2_params = PBES2Params().decod(bytes( - eci["contentEncryptionAlgorithm"]["parameters"] - )) - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - ukm = bytes(enc_scheme_params["ukm"]) - key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("d066a96fb326ba896a2352d3f40240a4ded6e7e7bd5b4db6b5241d631c8c381c") - key_enc, key_mac = kdf_tree_gostr3411_2012_256( - key, b"kdf tree", ukm[GOST3412Magma.blocksize // 2:], 2, - ) - ciphertext = bytes(eci["encryptedContent"]) - plaintext = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(key_enc).encrypt, - section_size=8 * 1024, - bs=GOST3412Magma.blocksize, - data=ciphertext, - iv=ukm[:GOST3412Magma.blocksize // 2], - ) - mac_expected = plaintext[-GOST3412Magma.blocksize:] - plaintext = plaintext[:-GOST3412Magma.blocksize] - mac = omac( - GOST3412Magma(key_mac).encrypt, - GOST3412Magma.blocksize, - plaintext, - ) - self.assertSequenceEqual(mac, mac_expected) - - safe_contents = SafeContents().decod(plaintext) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_certBag) - cert_bag = CertBag().decod(bytes(safe_bag["bagValue"])) - self.assertEqual(cert_bag["certId"], id_pkcs9_certTypes_x509Certificate) - _, cert = cert_bag["certValue"].defined - self.assertEqual(Certificate(cert), self.cert_test) - - safe_contents = OctetStringSafeContents().decod(bytes( - outer_safe_contents[1]["bagValue"] - )) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_pkcs8ShroudedKeyBag) - shrouded_key_bag = PKCS8ShroudedKeyBag().decod(bytes(safe_bag["bagValue"])) - _, pbes2_params = shrouded_key_bag["encryptionAlgorithm"]["parameters"].defined - _, pbkdf2_params = pbes2_params["keyDerivationFunc"]["parameters"].defined - _, enc_scheme_params = pbes2_params["encryptionScheme"]["parameters"].defined - ukm = bytes(enc_scheme_params["ukm"]) - key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(pbkdf2_params["salt"]["specified"]), - iterations=int(pbkdf2_params["iterationCount"]), - dklen=32, - ) - # key = hexdec("f840d001fd11441e0fb7ccf48f471915e5bf35275309dbe7ade9da4fe460ba7e") - ciphertext = bytes(shrouded_key_bag["encryptedData"]) - plaintext = ctr_acpkm( - GOST3412Magma, - GOST3412Magma(key).encrypt, - section_size=8 * 1024, - bs=GOST3412Magma.blocksize, - data=ciphertext, - iv=ukm[:GOST3412Magma.blocksize // 2], - ) - self.assertSequenceEqual(plaintext, self.prv_test_raw) - - mac_data = pfx["macData"] - mac_key = gost34112012_pbkdf2( - password=self.password, - salt=bytes(mac_data["macSalt"]), - iterations=int(mac_data["iterations"]), - dklen=96, - )[-32:] - # mac_key = hexdec("084f81782af1534ffd67e3c579c14cb45d7a6f659f46fdbb51a552e874e66fb2") - self.assertSequenceEqual( - hmac_new( - key=mac_key, - msg=SafeContents(outer_safe_contents).encode(), - digestmod=GOST34112012512, - ).digest(), - bytes(mac_data["mac"]["digest"]), - ) - - def test_dh(self): - curve = gost3410.CURVES["id-tc26-gost-3410-12-256-paramSetA"] - # sender_prv_raw = hexdec("0B20810E449978C7C3B76C6FF77A16C532421139344A058EF56310B6B6F377E8") - sender_cert = Certificate().decod(b64decode(""" - MIIB6zCCAZigAwIBAgIEAYy6gjAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 - MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw - MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA7MQ0wCwYDVQQKEwRUSzI2MSowKAYD - VQQDEyFPUklHSU5BVE9SOiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwXjAXBggqhQMH - AQEBATALBgkqhQMHAQIBAQEDQwAEQJYpDRNiWWqDgaZje0EmLLOldQ35o5X1ZuZN - SKequYQc/soI3OgDMWD7ThJJCk01IelCeb6MsBmG4lol+pnpVtOjgYcwgYQwYwYD - VR0jBFwwWoAUrGwOTERmokKW4p8JOyVm88ukUyqhPKQ6MDgxDTALBgNVBAoTBFRL - MjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdIIEAYy6 - gTAdBgNVHQ4EFgQUPx5RgcjkifhlJm4/jQdkbm30rVQwCgYIKoUDBwEBAwIDQQA6 - 8x7Vk6PvP/8xOGHhf8PuqaXAYskSyJPuBu+3Bo/PEj10devwc1J9uYWIDCGdKKPy - bSlnQHqUPBBPM30YX1YN - """)) - recipient_prv_raw = hexdec("0DC8DC1FF2BC114BABC3F1CA8C51E4F58610427E197B1C2FBDBA4AE58CBFB7CE")[::-1] - recipient_prv = gost3410.prv_unmarshal(recipient_prv_raw) - recipient_cert = Certificate().decod(b64decode(""" - MIIB6jCCAZegAwIBAgIEAYy6gzAKBggqhQMHAQEDAjA4MQ0wCwYDVQQKEwRUSzI2 - MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQwHhcNMDEw - MTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjA6MQ0wCwYDVQQKEwRUSzI2MSkwJwYD - VQQDEyBSRUNJUElFTlQ6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdDBeMBcGCCqFAwcB - AQEBMAsGCSqFAwcBAgEBAQNDAARAvyeCGXMsYwpYe5aE0w8w3m4vpKQapGInqpnF - lv7h08psFP0s1W80q3BR534F4TmR+o5+iU+AW6ycvWuc73JEQ6OBhzCBhDBjBgNV - HSMEXDBagBSsbA5MRGaiQpbinwk7JWbzy6RTKqE8pDowODENMAsGA1UEChMEVEsy - NjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0ggQBjLqB - MB0GA1UdDgQWBBQ35gHPN1bx8l2eEMTbrtIg+5MU0TAKBggqhQMHAQEDAgNBABF2 - RHDaRqQuBS2yu7yGIGFgA6c/LG4GKjSOwYsRVmXJNNkQ4TB7PB8j3q7gx2koPsVB - m90WfMWSL6SNSh3muuM= - """)) - self.assertTrue(gost3410.verify( - self.ca_curve, - self.ca_pub, - GOST34112012256(sender_cert["tbsCertificate"].encode()).digest()[::-1], - bytes(sender_cert["signatureValue"]), - )) - self.assertTrue(gost3410.verify( - self.ca_curve, - self.ca_pub, - GOST34112012256(recipient_cert["tbsCertificate"].encode()).digest()[::-1], - bytes(recipient_cert["signatureValue"]), - )) - - pfx_raw = b64decode(""" - MIIKVwIBAzCCClAGCSqGSIb3DQEHAqCCCkEwggo9AgEBMQwwCgYIKoUDBwEBAgIw - ggcjBgkqhkiG9w0BBwGgggcUBIIHEDCCBwwwggKdBgkqhkiG9w0BBwGgggKOBIIC - ijCCAoYwggKCBgsqhkiG9w0BDAoBA6CCAkowggJGBgoqhkiG9w0BCRYBoIICNgSC - AjIwggIuMIIB26ADAgECAgQBjLqEMAoGCCqFAwcBAQMCMDgxDTALBgNVBAoTBFRL - MjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1QgMzQuMTAtMTIgMjU2LWJpdDAeFw0w - MTAxMDEwMDAwMDBaFw00OTEyMzEwMDAwMDBaMDsxDTALBgNVBAoTBFRLMjYxKjAo - BgNVBAMTIU9SSUdJTkFUT1I6IEdPU1QgMzQuMTAtMTIgNTEyLWJpdDCBoDAXBggq - hQMHAQEBAjALBgkqhQMHAQIBAgEDgYQABIGAtIu3WrwpDhhlXGKhT7UtX1CETswd - H2AESHtLXJU0aWq3v6s0blUWqas8zvittSw6WFXwz7Nkqmtd2Tfk7PyVJb+faghQ - dnGKRcgf9JIePiu/cr8+6/PuFhNBJmX/E92nvydSaOsRrp3nB9fxuITLbPR2C58W - 8CQzDVRriB1eoM6jgYcwgYQwYwYDVR0jBFwwWoAUrGwOTERmokKW4p8JOyVm88uk - UyqhPKQ6MDgxDTALBgNVBAoTBFRLMjYxJzAlBgNVBAMTHkNBIFRLMjY6IEdPU1Qg - MzQuMTAtMTIgMjU2LWJpdIIEAYy6gTAdBgNVHQ4EFgQUfgZXCZgMrWsIqFfueQBY - OsnXoKQwCgYIKoUDBwEBAwIDQQAKXqnx0BumL0eT7eaAzIjRYiHXsiuWtKn+YHQX - tnMy3xdQPUPDPcmuufF5ed8y84DkF1Qn2ELIOAxUAaz8hwQQMSUwIwYJKoZIhvcN - AQkVMRYEFHlVdPnUtuTCAiQoaZhnP/AKFMBNMIIEZwYJKoZIhvcNAQcDoIIEWDCC - BFQCAQKgggHzoIIB7zCCAeswggGYoAMCAQICBAGMuoIwCgYIKoUDBwEBAwIwODEN - MAsGA1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAy - NTYtYml0MB4XDTAxMDEwMTAwMDAwMFoXDTQ5MTIzMTAwMDAwMFowOzENMAsGA1UE - ChMEVEsyNjEqMCgGA1UEAxMhT1JJR0lOQVRPUjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0MF4wFwYIKoUDBwEBAQEwCwYJKoUDBwECAQEBA0MABECWKQ0TYllqg4GmY3tB - JiyzpXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZhuJaJfqZ - 6VbTo4GHMIGEMGMGA1UdIwRcMFqAFKxsDkxEZqJCluKfCTslZvPLpFMqoTykOjA4 - MQ0wCwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEy - IDI1Ni1iaXSCBAGMuoEwHQYDVR0OBBYEFD8eUYHI5In4ZSZuP40HZG5t9K1UMAoG - CCqFAwcBAQMCA0EAOvMe1ZOj7z//MThh4X/D7qmlwGLJEsiT7gbvtwaPzxI9dHXr - 8HNSfbmFiAwhnSij8m0pZ0B6lDwQTzN9GF9WDTGB/6GB/AIBA6BCMEAwODENMAsG - A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0AgQBjLqCoSIEIBt4fjey+k8C1D3OaMca8wl6h3j3C6OAbrx8rmxXktsQMBcG - CSqFAwcBAQcCATAKBggqhQMHAQEGATB2MHQwQDA4MQ0wCwYDVQQKEwRUSzI2MScw - JQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1Ni1iaXQCBAGMuoMEMJkp - Wae6IVfaY3mP0izRY7ifc41fATXdJ2tmTl+1vitkSE2vLCKXDLl90KfHA6gNmDCC - AVQGCSqGSIb3DQEHATAfBgkqhQMHAQEFAgEwEgQQFhEshEBO2LkAAAAAAAAAAICC - ASQYvLpT/8azEXJfekyGuyvE9UkVX+Ao8sfu9My/c4WAVRNMhZkCqD+BbPwBsIzN - sXZIi9rXGAfsPz7xaO9EUFZPjNOWtF/E01oJgG+gYLFn7qAiEFcmRLptSHuanNHn - 7Yol6IHushX4UaW9hEa/L6eFQx/hoDhrNZnWTXNZtNuHuMGC9dzhHhTxfkdjZYXD - v+M7psVj58JutE3U2d4pgxKcBPdMO4vl4+27cIKxQZFZU2zuCVJLYLqmPT5pCBkM - mJqy7bZwHOJ9kBq/TGUf8iJGYSCNre3RTNLbcTTk7rZrbiMkFsG3borzenpouS5E - BcCkBt8Mj0nvsMCu9ipHTuWww7LltlkXCjlNXFUi6ZI3VyHW5CDpghujQWiZxiAc - JuGl6GwZoIIB7zCCAeswggGYoAMCAQICBAGMuoIwCgYIKoUDBwEBAwIwODENMAsG - A1UEChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYt - Yml0MB4XDTAxMDEwMTAwMDAwMFoXDTQ5MTIzMTAwMDAwMFowOzENMAsGA1UEChME - VEsyNjEqMCgGA1UEAxMhT1JJR0lOQVRPUjogR09TVCAzNC4xMC0xMiAyNTYtYml0 - MF4wFwYIKoUDBwEBAQEwCwYJKoUDBwECAQEBA0MABECWKQ0TYllqg4GmY3tBJiyz - pXUN+aOV9WbmTUinqrmEHP7KCNzoAzFg+04SSQpNNSHpQnm+jLAZhuJaJfqZ6VbT - o4GHMIGEMGMGA1UdIwRcMFqAFKxsDkxEZqJCluKfCTslZvPLpFMqoTykOjA4MQ0w - CwYDVQQKEwRUSzI2MScwJQYDVQQDEx5DQSBUSzI2OiBHT1NUIDM0LjEwLTEyIDI1 - Ni1iaXSCBAGMuoEwHQYDVR0OBBYEFD8eUYHI5In4ZSZuP40HZG5t9K1UMAoGCCqF - AwcBAQMCA0EAOvMe1ZOj7z//MThh4X/D7qmlwGLJEsiT7gbvtwaPzxI9dHXr8HNS - fbmFiAwhnSij8m0pZ0B6lDwQTzN9GF9WDTGCAQ4wggEKAgEBMEAwODENMAsGA1UE - ChMEVEsyNjEnMCUGA1UEAxMeQ0EgVEsyNjogR09TVCAzNC4xMC0xMiAyNTYtYml0 - AgQBjLqCMAoGCCqFAwcBAQICoGkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc - BgkqhkiG9w0BCQUxDxcNMjEwNDE0MTkyMTEyWjAvBgkqhkiG9w0BCQQxIgQg1XOA - zNa710QuXsn5+yIf3cNTiFOQMgTiBRJBz8Tr4I0wCgYIKoUDBwEBAQEEQALINal9 - 7wHXYiG+w0yzSkKOs0jRZew0S73r/cfk/sUoM3HKKIEbKruvlAdiOqX/HLFSEx/s - kxFG6QUFH8uuoX8= - """) - pfx = PFX().decod(pfx_raw) - self.assertEqual(pfx["authSafe"]["contentType"], id_signedData) - - sd = SignedData().decod(bytes(pfx["authSafe"]["content"])) - self.assertEqual(sd["certificates"][0]["certificate"], sender_cert) - si = sd["signerInfos"][0] - self.assertEqual( - si["digestAlgorithm"]["algorithm"], - id_tc26_gost3411_2012_256, - ) - digest = [ - bytes(attr["attrValues"][0].defined[1]) for attr in si["signedAttrs"] - if attr["attrType"] == id_messageDigest - ][0] - sender_pub = gost3410.pub_unmarshal(bytes(OctetString().decod(bytes( - sender_cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - )))) - content = bytes(sd["encapContentInfo"]["eContent"]) - self.assertSequenceEqual(digest, GOST34112012256(content).digest()) - self.assertTrue(gost3410.verify( - curve, - sender_pub, - GOST34112012256( - SignedAttributes(si["signedAttrs"]).encode() - ).digest()[::-1], - bytes(si["signature"]), - )) - - outer_safe_contents = SafeContents().decod(content) - - safe_bag = outer_safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_data) - safe_contents = OctetStringSafeContents().decod(bytes(safe_bag["bagValue"])) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_certBag) - cert_bag = CertBag().decod(bytes(safe_bag["bagValue"])) - self.assertEqual(cert_bag["certId"], id_pkcs9_certTypes_x509Certificate) - _, cert = cert_bag["certValue"].defined - self.assertEqual(Certificate(cert), self.cert_test) - - safe_bag = outer_safe_contents[1] - self.assertEqual(safe_bag["bagId"], id_envelopedData) - ed = EnvelopedData().decod(bytes(safe_bag["bagValue"])) - kari = ed["recipientInfos"][0]["kari"] - ukm = bytes(kari["ukm"]) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_wrap_kexp15, - ) - self.assertEqual( - kari["keyEncryptionAlgorithm"]["parameters"].defined[1]["algorithm"], - id_tc26_agreement_gost3410_2012_256, - ) - kexp = bytes(kari["recipientEncryptedKeys"][0]["encryptedKey"]) - keymat = keg(curve, recipient_prv, sender_pub, ukm) - kim, kek = keymat[:KEYSIZE], keymat[KEYSIZE:] - cek = kimp15( - GOST3412Kuznechik(kek).encrypt, - GOST3412Kuznechik(kim).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - ukm[24:24 + GOST3412Kuznechik.blocksize // 2], - ) - eci = ed["encryptedContentInfo"] - self.assertEqual( - eci["contentEncryptionAlgorithm"]["algorithm"], - id_gostr3412_2015_kuznyechik_ctracpkm, - ) - eci_ukm = bytes( - eci["contentEncryptionAlgorithm"]["parameters"].defined[1]["ukm"] - ) - content = ctr_acpkm( - GOST3412Kuznechik, - GOST3412Kuznechik(cek).encrypt, - 256 * 1024, - GOST3412Kuznechik.blocksize, - bytes(eci["encryptedContent"]), - eci_ukm[:GOST3412Kuznechik.blocksize // 2], - ) - - safe_contents = SafeContents().decod(content) - safe_bag = safe_contents[0] - self.assertEqual(safe_bag["bagId"], id_pkcs12_bagtypes_keyBag) - KeyBag().decod(bytes(safe_bag["bagValue"])) - self.assertSequenceEqual(bytes(safe_bag["bagValue"]), self.prv_test_raw) diff --git a/pygost-5.13/pygost/test_wrap.py b/pygost-5.13/pygost/test_wrap.py deleted file mode 100644 index 7ecf8ee..0000000 --- a/pygost-5.13/pygost/test_wrap.py +++ /dev/null @@ -1,111 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from os import urandom -from unittest import TestCase - -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost3412 import GOST3412Kuznechik -from pygost.gost3412 import GOST3412Magma -from pygost.utils import hexdec -from pygost.wrap import kexp15 -from pygost.wrap import kimp15 -from pygost.wrap import unwrap_cryptopro -from pygost.wrap import unwrap_gost -from pygost.wrap import wrap_cryptopro -from pygost.wrap import wrap_gost - - -class WrapGostTest(TestCase): - def test_symmetric(self): - for sbox in (DEFAULT_SBOX, "id-tc26-gost-28147-param-Z"): - for _ in range(1 << 8): - kek = urandom(32) - cek = urandom(32) - ukm = urandom(8) - wrapped = wrap_gost(ukm, kek, cek, sbox=sbox) - unwrapped = unwrap_gost(kek, wrapped, sbox=sbox) - self.assertSequenceEqual(unwrapped, cek) - - def test_invalid_length(self): - with self.assertRaises(ValueError): - unwrap_gost(urandom(32), urandom(41)) - with self.assertRaises(ValueError): - unwrap_gost(urandom(32), urandom(45)) - - -class WrapCryptoproTest(TestCase): - def test_symmetric(self): - for sbox in (DEFAULT_SBOX, "id-tc26-gost-28147-param-Z"): - for _ in range(1 << 8): - kek = urandom(32) - cek = urandom(32) - ukm = urandom(8) - wrapped = wrap_cryptopro(ukm, kek, cek, sbox=sbox) - unwrapped = unwrap_cryptopro(kek, wrapped, sbox=sbox) - self.assertSequenceEqual(unwrapped, cek) - - -class TestVectorKExp15(TestCase): - """Test vectors from Р 1323565.1.017-2018 - """ - key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF") - key_enc = hexdec("202122232425262728292A2B2C2D2E2F38393A3B3C3D3E3F3031323334353637") - key_mac = hexdec("08090A0B0C0D0E0F0001020304050607101112131415161718191A1B1C1D1E1F") - - def test_magma(self): - iv = hexdec("67BED654") - kexp = kexp15( - GOST3412Magma(self.key_enc).encrypt, - GOST3412Magma(self.key_mac).encrypt, - GOST3412Magma.blocksize, - self.key, - iv, - ) - self.assertSequenceEqual(kexp, hexdec(""" -CF D5 A1 2D 5B 81 B6 E1 E9 9C 91 6D 07 90 0C 6A -C1 27 03 FB 3A BD ED 55 56 7B F3 74 2C 89 9C 75 -5D AF E7 B4 2E 3A 8B D9 - """.replace("\n", "").replace(" ", ""))) - self.assertSequenceEqual(kimp15( - GOST3412Magma(self.key_enc).encrypt, - GOST3412Magma(self.key_mac).encrypt, - GOST3412Magma.blocksize, - kexp, - iv, - ), self.key) - - def test_kuznechik(self): - iv = hexdec("0909472DD9F26BE8") - kexp = kexp15( - GOST3412Kuznechik(self.key_enc).encrypt, - GOST3412Kuznechik(self.key_mac).encrypt, - GOST3412Kuznechik.blocksize, - self.key, - iv, - ) - self.assertSequenceEqual(kexp, hexdec(""" -E3 61 84 E8 4E 8D 73 6F F3 6C C2 E5 AE 06 5D C6 -56 B2 3C 20 F5 49 B0 2F DF F8 8E 1F 3F 30 D8 C2 -9A 53 F3 CA 55 4D BA D8 0D E1 52 B9 A4 62 5B 32 - """.replace("\n", "").replace(" ", ""))) - self.assertSequenceEqual(kimp15( - GOST3412Kuznechik(self.key_enc).encrypt, - GOST3412Kuznechik(self.key_mac).encrypt, - GOST3412Kuznechik.blocksize, - kexp, - iv, - ), self.key) diff --git a/pygost-5.13/pygost/test_x509.py b/pygost-5.13/pygost/test_x509.py deleted file mode 100644 index e9fccb7..0000000 --- a/pygost-5.13/pygost/test_x509.py +++ /dev/null @@ -1,433 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from base64 import b64decode -from unittest import skipIf -from unittest import TestCase - -from pygost.gost3410 import CURVES -from pygost.gost3410 import prv_unmarshal -from pygost.gost3410 import pub_marshal -from pygost.gost3410 import pub_unmarshal -from pygost.gost3410 import public_key -from pygost.gost3410 import verify -from pygost.gost34112012256 import GOST34112012256 -from pygost.gost34112012512 import GOST34112012512 -from pygost.utils import hexdec - -try: - - from pyderasn import Any - from pyderasn import BitString - from pyderasn import Boolean - from pyderasn import GeneralizedTime - from pyderasn import Integer - from pyderasn import OctetString - from pyderasn import PrintableString - from pyderasn import UTCTime - - from pygost.asn1schemas.oids import id_at_commonName - from pygost.asn1schemas.oids import id_ce_basicConstraints - from pygost.asn1schemas.oids import id_GostR3410_2001_TestParamSet - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetA - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 - from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetTest - from pygost.asn1schemas.oids import id_tc26_gost3411_2012_256 - from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_256 - from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_512 - from pygost.asn1schemas.pkcs10 import Attributes - from pygost.asn1schemas.pkcs10 import CertificationRequest - from pygost.asn1schemas.pkcs10 import CertificationRequestInfo - from pygost.asn1schemas.x509 import AlgorithmIdentifier - from pygost.asn1schemas.x509 import AttributeType - from pygost.asn1schemas.x509 import AttributeTypeAndValue - from pygost.asn1schemas.x509 import AttributeValue - from pygost.asn1schemas.x509 import BasicConstraints - from pygost.asn1schemas.x509 import Certificate - from pygost.asn1schemas.x509 import CertificateList - from pygost.asn1schemas.x509 import CertificateSerialNumber - from pygost.asn1schemas.x509 import Extension - from pygost.asn1schemas.x509 import Extensions - from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters - from pygost.asn1schemas.x509 import Name - from pygost.asn1schemas.x509 import RDNSequence - from pygost.asn1schemas.x509 import RelativeDistinguishedName - from pygost.asn1schemas.x509 import SubjectPublicKeyInfo - from pygost.asn1schemas.x509 import TBSCertificate - from pygost.asn1schemas.x509 import TBSCertList - from pygost.asn1schemas.x509 import Time - from pygost.asn1schemas.x509 import Validity - from pygost.asn1schemas.x509 import Version - -except ImportError: - pyderasn_exists = False -else: - pyderasn_exists = True - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestCertificate(TestCase): - """Certificate test vectors from "Использования алгоритмов ГОСТ Р - 34.10, ГОСТ Р 34.11 в профиле сертификата и списке отзыва - сертификатов (CRL) инфраструктуры открытых ключей X.509" - (TK26IOK.pdf) - """ - - def process_cert(self, curve_name, hasher, prv_key_raw, cert_raw): - cert, tail = Certificate().decode(cert_raw, ctx={ - "defines_by_path": ( - ( - ( - "tbsCertificate", - "subjectPublicKeyInfo", - "algorithm", - "algorithm", - ), - ( - ( - ("..", "subjectPublicKey"), - { - id_tc26_gost3410_2012_256: OctetString(), - id_tc26_gost3410_2012_512: OctetString(), - }, - ), - ), - ), - ), - }) - self.assertSequenceEqual(tail, b"") - curve = CURVES[curve_name] - prv_key = prv_unmarshal(prv_key_raw) - spk = cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"] - self.assertIsNotNone(spk.defined) - _, pub_key_raw = spk.defined - pub_key = pub_unmarshal(bytes(pub_key_raw)) - self.assertSequenceEqual(pub_key, public_key(curve, prv_key)) - self.assertTrue(verify( - curve, - pub_key, - hasher(cert["tbsCertificate"].encode()).digest()[::-1], - bytes(cert["signatureValue"]), - )) - - def test_256(self): - cert_raw = b64decode(""" -MIICYjCCAg+gAwIBAgIBATAKBggqhQMHAQEDAjBWMSkwJwYJKoZIhvcNAQkBFhpH -b3N0UjM0MTAtMjAxMkBleGFtcGxlLmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIw -MTIgKDI1NiBiaXQpIGV4YW1wbGUwHhcNMTMxMTA1MTQwMjM3WhcNMzAxMTAxMTQw -MjM3WjBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxlLmNv -bTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgKDI1NiBiaXQpIGV4YW1wbGUwZjAf -BggqhQMHAQEBATATBgcqhQMCAiQABggqhQMHAQECAgNDAARAut/Qw1MUq9KPqkdH -C2xAF3K7TugHfo9n525D2s5mFZdD5pwf90/i4vF0mFmr9nfRwMYP4o0Pg1mOn5Rl -aXNYraOBwDCBvTAdBgNVHQ4EFgQU1fIeN1HaPbw+XWUzbkJ+kHJUT0AwCwYDVR0P -BAQDAgHGMA8GA1UdEwQIMAYBAf8CAQEwfgYDVR0BBHcwdYAU1fIeN1HaPbw+XWUz -bkJ+kHJUT0ChWqRYMFYxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDEyQGV4 -YW1wbGUuY29tMSkwJwYDVQQDEyBHb3N0UjM0MTAtMjAxMiAoMjU2IGJpdCkgZXhh -bXBsZYIBATAKBggqhQMHAQEDAgNBAF5bm4BbARR6hJLEoWJkOsYV3Hd7kXQQjz3C -dqQfmHrz6TI6Xojdh/t8ckODv/587NS5/6KsM77vc6Wh90NAT2s= - """) - prv_key_raw = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1] - self.process_cert( - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - GOST34112012256, - prv_key_raw, - cert_raw, - ) - - def test_512(self): - cert_raw = b64decode(""" -MIIC6DCCAlSgAwIBAgIBATAKBggqhQMHAQEDAzBWMSkwJwYJKoZIhvcNAQkBFhpH -b3N0UjM0MTAtMjAxMkBleGFtcGxlLmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIw -MTIgKDUxMiBiaXQpIGV4YW1wbGUwHhcNMTMxMDA0MDczNjA0WhcNMzAxMDAxMDcz -NjA0WjBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxlLmNv -bTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgKDUxMiBiaXQpIGV4YW1wbGUwgaow -IQYIKoUDBwEBAQIwFQYJKoUDBwECAQICBggqhQMHAQECAwOBhAAEgYATGQ9VCiM5 -FRGCQ8MEz2F1dANqhaEuywa8CbxOnTvaGJpFQVXQwkwvLFAKh7hk542vOEtxpKtT -CXfGf84nRhMH/Q9bZeAc2eO/yhxrsQhTBufa1Fuou2oe/jUOaG6RAtUUvRzhNTpp -RGGl1+EIY2vzzUua9j9Ol/gAoy/LNKQIfqOBwDCBvTAdBgNVHQ4EFgQUPcbTRXJZ -nHtjj+eBP7b5lcTMekIwCwYDVR0PBAQDAgHGMA8GA1UdEwQIMAYBAf8CAQEwfgYD -VR0BBHcwdYAUPcbTRXJZnHtjj+eBP7b5lcTMekKhWqRYMFYxKTAnBgkqhkiG9w0B -CQEWGkdvc3RSMzQxMC0yMDEyQGV4YW1wbGUuY29tMSkwJwYDVQQDEyBHb3N0UjM0 -MTAtMjAxMiAoNTEyIGJpdCkgZXhhbXBsZYIBATAKBggqhQMHAQEDAwOBgQBObS7o -ppPTXzHyVR1DtPa8b57nudJzI4czhsfeX5HDntOq45t9B/qSs8dC6eGxbhHZ9zCO -SFtxWYdmg0au8XI9Xb8vTC1qdwWID7FFjMWDNQZb6lYh/J+8F2xKylvB5nIlRZqO -o3eUNFkNyHJwQCk2WoOlO16zwGk2tdKH4KmD5w== - """) - prv_key_raw = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1] - self.process_cert( - "id-tc26-gost-3410-12-512-paramSetB", - GOST34112012512, - prv_key_raw, - cert_raw, - ) - - -@skipIf(not pyderasn_exists, "PyDERASN dependency is required") -class TestRFC4491bis(TestCase): - """Test vectors from https://tools.ietf.org/html/draft-deremin-rfc4491-bis-02 - """ - - def _test_vector( - self, - curve_name, - hsh, - ai_spki, - ai_sign, - cert_serial, - prv_hex, - cr_sign_hex, - cr_b64, - c_sign_hex, - c_b64, - crl_sign_hex, - crl_b64, - ): - prv_raw = hexdec(prv_hex)[::-1] - prv = prv_unmarshal(prv_raw) - curve = CURVES[curve_name] - pub = public_key(curve, prv) - pub_raw = pub_marshal(pub) - subj = Name(("rdnSequence", RDNSequence([ - RelativeDistinguishedName(( - AttributeTypeAndValue(( - ("type", AttributeType(id_at_commonName)), - ("value", AttributeValue(PrintableString("Example"))), - )), - )) - ]))) - spki = SubjectPublicKeyInfo(( - ("algorithm", ai_spki), - ("subjectPublicKey", BitString(OctetString(pub_raw).encode())), - )) - - # Certification request - cri = CertificationRequestInfo(( - ("version", Integer(0)), - ("subject", subj), - ("subjectPKInfo", spki), - ("attributes", Attributes()), - )) - sign = hexdec(cr_sign_hex) - self.assertTrue(verify( - curve, - pub, - hsh(cri.encode()).digest()[::-1], - sign, - )) - cr = CertificationRequest(( - ("certificationRequestInfo", cri), - ("signatureAlgorithm", ai_sign), - ("signature", BitString(sign)), - )) - self.assertSequenceEqual(cr.encode(), b64decode(cr_b64)) - - # Certificate - tbs = TBSCertificate(( - ("version", Version("v3")), - ("serialNumber", CertificateSerialNumber(cert_serial)), - ("signature", ai_sign), - ("issuer", subj), - ("validity", Validity(( - ("notBefore", Time(("utcTime", UTCTime(b"010101000000Z")))), - ("notAfter", Time(("generalTime", GeneralizedTime(b"20501231000000Z")))), - ))), - ("subject", subj), - ("subjectPublicKeyInfo", spki), - ("extensions", Extensions(( - Extension(( - ("extnID", id_ce_basicConstraints), - ("critical", Boolean(True)), - ("extnValue", OctetString( - BasicConstraints((("cA", Boolean(True)),)).encode() - )), - )), - ))), - )) - sign = hexdec(c_sign_hex) - self.assertTrue(verify( - curve, - pub, - hsh(tbs.encode()).digest()[::-1], - sign, - )) - cert = Certificate(( - ("tbsCertificate", tbs), - ("signatureAlgorithm", ai_sign), - ("signatureValue", BitString(sign)), - )) - self.assertSequenceEqual(cert.encode(), b64decode(c_b64)) - - # CRL - tbs = TBSCertList(( - ("version", Version("v2")), - ("signature", ai_sign), - ("issuer", subj), - ("thisUpdate", Time(("utcTime", UTCTime(b"140101000000Z")))), - ("nextUpdate", Time(("utcTime", UTCTime(b"140102000000Z")))), - )) - sign = hexdec(crl_sign_hex) - self.assertTrue(verify( - curve, - pub, - hsh(tbs.encode()).digest()[::-1], - sign, - )) - crl = CertificateList(( - ("tbsCertList", tbs), - ("signatureAlgorithm", ai_sign), - ("signatureValue", BitString(sign)), - )) - self.assertSequenceEqual(crl.encode(), b64decode(crl_b64)) - - def test_256_test_paramset(self): - self._test_vector( - "id-GostR3410-2001-TestParamSet", - GOST34112012256, - AlgorithmIdentifier(( - ("algorithm", id_tc26_gost3410_2012_256), - ("parameters", Any( - GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", id_GostR3410_2001_TestParamSet), - ("digestParamSet", id_tc26_gost3411_2012_256), - )) - )), - )), - AlgorithmIdentifier(( - ("algorithm", id_tc26_signwithdigest_gost3410_2012_256), - )), - 10, - "7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28", - "6AAAB38E35D4AAA517940301799122D855484F579F4CBB96D63CDFDF3ACC432A41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493", - """ -MIHTMIGBAgEAMBIxEDAOBgNVBAMTB0V4YW1wbGUwZjAfBggqhQMHAQEBATATBgcq -hQMCAiMABggqhQMHAQECAgNDAARAC9hv5djbiWaPeJtOHbqFhcVQi0XsW1nYkG3b -cOJJK3/ad/+HGhD73ydm0pPF0WSvuzx7lzpByIXRHXDWibTxJqAAMAoGCCqFAwcB -AQMCA0EAaqqzjjXUqqUXlAMBeZEi2FVIT1efTLuW1jzf3zrMQypBqijS8asUgoDN -ntVv7aQZdAU1VKQnZ7g60EP9OdwEkw== - """, - "4D53F012FE081776507D4D9BB81F00EFDB4EEFD4AB83BAC4BACF735173CFA81C41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493", - """ -MIIBLTCB26ADAgECAgEKMAoGCCqFAwcBAQMCMBIxEDAOBgNVBAMTB0V4YW1wbGUw -IBcNMDEwMTAxMDAwMDAwWhgPMjA1MDEyMzEwMDAwMDBaMBIxEDAOBgNVBAMTB0V4 -YW1wbGUwZjAfBggqhQMHAQEBATATBgcqhQMCAiMABggqhQMHAQECAgNDAARAC9hv -5djbiWaPeJtOHbqFhcVQi0XsW1nYkG3bcOJJK3/ad/+HGhD73ydm0pPF0WSvuzx7 -lzpByIXRHXDWibTxJqMTMBEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhQMHAQEDAgNB -AE1T8BL+CBd2UH1Nm7gfAO/bTu/Uq4O6xLrPc1Fzz6gcQaoo0vGrFIKAzZ7Vb+2k -GXQFNVSkJ2e4OtBD/TncBJM= - """, - "42BF392A14D3EBE957AF3E46CB50BF5F4221A003AD3D172753C94A9C37A31D2041AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493", - """ -MIGSMEECAQEwCgYIKoUDBwEBAwIwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx -MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAgNBAEK/OSoU0+vpV68+ -RstQv19CIaADrT0XJ1PJSpw3ox0gQaoo0vGrFIKAzZ7Vb+2kGXQFNVSkJ2e4OtBD -/TncBJM= - """, - ) - - def test_256a_paramset(self): - self._test_vector( - "id-tc26-gost-3410-2012-256-paramSetA", - GOST34112012256, - AlgorithmIdentifier(( - ("algorithm", id_tc26_gost3410_2012_256), - ("parameters", Any( - GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", id_tc26_gost3410_2012_256_paramSetA), - )) - )), - )), - AlgorithmIdentifier(( - ("algorithm", id_tc26_signwithdigest_gost3410_2012_256), - )), - 10, - "7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28", - "1BDC2A1317679B66232F63EA16FF7C64CCAAB9AD855FC6E18091661DB79D48121D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769", - """ -MIHKMHkCAQAwEjEQMA4GA1UEAxMHRXhhbXBsZTBeMBcGCCqFAwcBAQEBMAsGCSqF -AwcBAgEBAQNDAARAdCeV1L7ohN3yhQ/sA+o/rxhE4B2dpgtkUJOlXibfw5l49ZbP -TU0MbPHRiUPZRJPRa57AoW1RLS4SfMRpGmMY4qAAMAoGCCqFAwcBAQMCA0EAG9wq -Exdnm2YjL2PqFv98ZMyqua2FX8bhgJFmHbedSBIdDh2lvjR8bxtSVseurCAK1krH -em9bOg4Jcxjnrm7naQ== - """, - "140B4DA9124B09CB0D5CE928EE874273A310129492EC0E29369E3B791248578C1D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769", - """ -MIIBJTCB06ADAgECAgEKMAoGCCqFAwcBAQMCMBIxEDAOBgNVBAMTB0V4YW1wbGUw -IBcNMDEwMTAxMDAwMDAwWhgPMjA1MDEyMzEwMDAwMDBaMBIxEDAOBgNVBAMTB0V4 -YW1wbGUwXjAXBggqhQMHAQEBATALBgkqhQMHAQIBAQEDQwAEQHQnldS+6ITd8oUP -7APqP68YROAdnaYLZFCTpV4m38OZePWWz01NDGzx0YlD2UST0WuewKFtUS0uEnzE -aRpjGOKjEzARMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoUDBwEBAwIDQQAUC02pEksJ -yw1c6Sjuh0JzoxASlJLsDik2njt5EkhXjB0OHaW+NHxvG1JWx66sIArWSsd6b1s6 -DglzGOeubudp - """, - "14BD68087C3B903C7AA28B07FEB2E7BD6FE0963F563267359F5CD8EAB45059AD1D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769", - """ -MIGSMEECAQEwCgYIKoUDBwEBAwIwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx -MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAgNBABS9aAh8O5A8eqKL -B/6y571v4JY/VjJnNZ9c2Oq0UFmtHQ4dpb40fG8bUlbHrqwgCtZKx3pvWzoOCXMY -565u52k= - """, - ) - - def test_512_test_paramset(self): - self._test_vector( - "id-tc26-gost-3410-2012-512-paramSetTest", - GOST34112012512, - AlgorithmIdentifier(( - ("algorithm", id_tc26_gost3410_2012_512), - ("parameters", Any( - GostR34102012PublicKeyParameters(( - ("publicKeyParamSet", id_tc26_gost3410_2012_512_paramSetTest), - )) - )), - )), - AlgorithmIdentifier(( - ("algorithm", id_tc26_signwithdigest_gost3410_2012_512), - )), - 11, - "0BA6048AADAE241BA40936D47756D7C93091A0E8514669700EE7508E508B102072E8123B2200A0563322DAD2827E2714A2636B7BFD18AADFC62967821FA18DD4", - "433B1D6CE40A51F1E5737EB16AA2C683829A405B9D9127E21260FC9D6AC05D87BF24E26C45278A5C2192A75BA94993ABD6074E7FF1BF03FD2F5397AFA1D945582F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36", - """ -MIIBTzCBvAIBADASMRAwDgYDVQQDEwdFeGFtcGxlMIGgMBcGCCqFAwcBAQECMAsG -CSqFAwcBAgECAAOBhAAEgYDh7zDVLGEz3dmdHVxBRVz3302LTJJbvGmvFDPRVlhR -Wt0hRoUMMlxbgcEzvmVaqMTUQOe5io1ZSHsMdpa8xV0R7L53NqnsNX/y/TmTH04R -TLjNo1knCsfw5/9D2UGUGeph/Sq3f12fY1I9O1CgT2PioM9Rt8E63CFWDwvUDMnH -N6AAMAoGCCqFAwcBAQMDA4GBAEM7HWzkClHx5XN+sWqixoOCmkBbnZEn4hJg/J1q -wF2HvyTibEUnilwhkqdbqUmTq9YHTn/xvwP9L1OXr6HZRVgvhvpgoIEJGiPdeV4e -PGie5RKjyC7g3MJkPHjuqPys01SSVYSGsg8cnsGXyQaZhQJgyTvLzZxcMxfhk0Th -c642 - """, - "415703D892F1A5F3F68C4353189A7EE207B80B5631EF9D49529A4D6B542C2CFA15AA2EACF11F470FDE7D954856903C35FD8F955EF300D95C77534A724A0EEE702F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36", - """ -MIIBqjCCARagAwIBAgIBCzAKBggqhQMHAQEDAzASMRAwDgYDVQQDEwdFeGFtcGxl -MCAXDTAxMDEwMTAwMDAwMFoYDzIwNTAxMjMxMDAwMDAwWjASMRAwDgYDVQQDEwdF -eGFtcGxlMIGgMBcGCCqFAwcBAQECMAsGCSqFAwcBAgECAAOBhAAEgYDh7zDVLGEz -3dmdHVxBRVz3302LTJJbvGmvFDPRVlhRWt0hRoUMMlxbgcEzvmVaqMTUQOe5io1Z -SHsMdpa8xV0R7L53NqnsNX/y/TmTH04RTLjNo1knCsfw5/9D2UGUGeph/Sq3f12f -Y1I9O1CgT2PioM9Rt8E63CFWDwvUDMnHN6MTMBEwDwYDVR0TAQH/BAUwAwEB/zAK -BggqhQMHAQEDAwOBgQBBVwPYkvGl8/aMQ1MYmn7iB7gLVjHvnUlSmk1rVCws+hWq -LqzxH0cP3n2VSFaQPDX9j5Ve8wDZXHdTSnJKDu5wL4b6YKCBCRoj3XleHjxonuUS -o8gu4NzCZDx47qj8rNNUklWEhrIPHJ7Bl8kGmYUCYMk7y82cXDMX4ZNE4XOuNg== - """, - "3A13FB7AECDB5560EEF6137CFC5DD64691732EBFB3690A1FC0C7E8A4EEEA08307D648D4DC0986C46A87B3FBE4C7AF42EA34359C795954CA39FF3ABBED9051F4D2F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36", - """ -MIHTMEECAQEwCgYIKoUDBwEBAwMwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx -MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAwOBgQA6E/t67NtVYO72 -E3z8XdZGkXMuv7NpCh/Ax+ik7uoIMH1kjU3AmGxGqHs/vkx69C6jQ1nHlZVMo5/z -q77ZBR9NL4b6YKCBCRoj3XleHjxonuUSo8gu4NzCZDx47qj8rNNUklWEhrIPHJ7B -l8kGmYUCYMk7y82cXDMX4ZNE4XOuNg== - """, - ) diff --git a/pygost-5.13/pygost/utils.py b/pygost-5.13/pygost/utils.py deleted file mode 100644 index 21c31b0..0000000 --- a/pygost-5.13/pygost/utils.py +++ /dev/null @@ -1,101 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . - -from codecs import getdecoder -from codecs import getencoder -from sys import version_info - - -xrange = range if version_info[0] == 3 else xrange - - -def strxor(a, b): - """XOR of two strings - - This function will process only shortest length of both strings, - ignoring remaining one. - """ - mlen = min(len(a), len(b)) - a, b, xor = bytearray(a), bytearray(b), bytearray(mlen) - for i in xrange(mlen): - xor[i] = a[i] ^ b[i] - return bytes(xor) - - -_hexdecoder = getdecoder("hex") -_hexencoder = getencoder("hex") - - -def hexdec(data): - """Decode hexadecimal - """ - return _hexdecoder(data)[0] - - -def hexenc(data): - """Encode hexadecimal - """ - return _hexencoder(data)[0].decode("ascii") - - -def bytes2long(raw): - """Deserialize big-endian bytes into long number - - :param bytes raw: binary string - :returns: deserialized long number - :rtype: int - """ - return int(hexenc(raw), 16) - - -def long2bytes(n, size=32): - """Serialize long number into big-endian bytestring - - :param long n: long number - :returns: serialized bytestring - :rtype: bytes - """ - res = hex(int(n))[2:].rstrip("L") - if len(res) % 2 != 0: - res = "0" + res - s = hexdec(res) - if len(s) != size: - s = (size - len(s)) * b"\x00" + s - return s - - -def modinvert(a, n): - """Modular multiplicative inverse - - :returns: inverse number. -1 if it does not exist - - Realization is taken from: - https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm - """ - if a < 0: - # k^-1 = p - (-k)^-1 mod p - return n - modinvert(-a, n) - t, newt = 0, 1 - r, newr = n, a - while newr != 0: - quotinent = r // newr - t, newt = newt, t - quotinent * newt - r, newr = newr, r - quotinent * newr - if r > 1: - return -1 - if t < 0: - t = t + n - return t diff --git a/pygost-5.13/pygost/wrap.py b/pygost-5.13/pygost/wrap.py deleted file mode 100644 index 3fa49e7..0000000 --- a/pygost-5.13/pygost/wrap.py +++ /dev/null @@ -1,152 +0,0 @@ -# coding: utf-8 -# PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2023 Sergey Matveev -# -# 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, version 3 of the License. -# -# 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 . -"""Key wrap. - -:rfc:`4357` key wrapping (28147-89 and CryptoPro). -""" - -from hmac import compare_digest -from struct import pack -from struct import unpack - -from pygost.gost28147 import cfb_encrypt -from pygost.gost28147 import DEFAULT_SBOX -from pygost.gost28147 import ecb_decrypt -from pygost.gost28147 import ecb_encrypt -from pygost.gost28147_mac import MAC -from pygost.gost3413 import ctr -from pygost.gost3413 import mac - - -def wrap_gost(ukm, kek, cek, sbox=DEFAULT_SBOX): - """28147-89 key wrapping - - :param ukm: UKM - :type ukm: bytes, 8 bytes - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param cek: content encryption key - :type cek: bytes, 32 bytes - :returns: wrapped key - :rtype: bytes, 44 bytes - """ - cek_mac = MAC(kek, data=cek, iv=ukm, sbox=sbox).digest()[:4] - cek_enc = ecb_encrypt(kek, cek, sbox=sbox) - return ukm + cek_enc + cek_mac - - -def unwrap_gost(kek, data, sbox=DEFAULT_SBOX): - """28147-89 key unwrapping - - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param data: wrapped key - :type data: bytes, 44 bytes - :returns: unwrapped CEK - :rtype: 32 bytes - """ - if len(data) != 44: - raise ValueError("Invalid data length") - ukm, cek_enc, cek_mac = data[:8], data[8:8 + 32], data[-4:] - cek = ecb_decrypt(kek, cek_enc, sbox=sbox) - if MAC(kek, data=cek, iv=ukm, sbox=sbox).digest()[:4] != cek_mac: - raise ValueError("Invalid MAC") - return cek - - -def wrap_cryptopro(ukm, kek, cek, sbox=DEFAULT_SBOX): - """CryptoPro key wrapping - - :param ukm: UKM - :type ukm: bytes, 8 bytes - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param cek: content encryption key - :type cek: bytes, 32 bytes - :returns: wrapped key - :rtype: bytes, 44 bytes - """ - return wrap_gost( - ukm, - diversify(kek, bytearray(ukm), sbox=sbox), - cek, - sbox=sbox, - ) - - -def unwrap_cryptopro(kek, data, sbox=DEFAULT_SBOX): - """CryptoPro key unwrapping - - :param kek: key encryption key - :type kek: bytes, 32 bytes - :param data: wrapped key - :type data: bytes, 44 bytes - :returns: unwrapped CEK - :rtype: 32 bytes - """ - if len(data) < 8: - raise ValueError("Invalid data length") - return unwrap_gost( - diversify(kek, bytearray(data[:8]), sbox=sbox), - data, - sbox=sbox, - ) - - -def diversify(kek, ukm, sbox=DEFAULT_SBOX): - out = kek - for i in range(8): - s1, s2 = 0, 0 - for j in range(8): - k, = unpack("> j) & 1: - s1 += k - else: - s2 += k - iv = pack("