├── .gitignore ├── LICENSE.md ├── README.md └── sidh ├── Makefile ├── sidh_elliptic_curve.c ├── sidh_elliptic_curve.h ├── sidh_elliptic_curve_dlp.c ├── sidh_elliptic_curve_dlp.h ├── sidh_isogeny.c ├── sidh_isogeny.h ├── sidh_private_key.c ├── sidh_private_key.h ├── sidh_public_key.c ├── sidh_public_key.h ├── sidh_public_key_encryption.c ├── sidh_public_key_encryption.h ├── sidh_public_key_validation.c ├── sidh_public_key_validation.h ├── sidh_public_param.c ├── sidh_public_param.h ├── sidh_quadratic_ext.c ├── sidh_quadratic_ext.h ├── sidh_shared_key.c ├── sidh_shared_key.h ├── sidh_util.c ├── sidh_util.h └── test ├── Makefile ├── public_params_263 ├── public_params_46 ├── public_params_521 ├── public_params_771 ├── test_key_exchange.c └── test_public_key_encryption.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.cproject 2 | *.project 3 | sidh/build/ 4 | sidh/nbproject/ 5 | sidh/test/test_key_exchange 6 | sidh/test/test_public_key_encryption 7 | 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SIDH C Reference 2 | 3 | A reference implementation of the Supersingular Isogeny Key Exchange System in C. 4 | 5 | Installation 6 | ---------------- 7 | You can clone this repo using 8 | 9 | git clone https://github.com/sidh-crypto/sidh-c-reference.git 10 | or [download](https://github.com/sidh-crypto/sidh-c-reference/archive/master.zip) the zip file. You will also need a recent version of the GNU [GMP](https://gmplib.org/). 11 | 12 | Demo 13 | -------- 14 | In a terminal: 15 | 16 | cd sidh/ 17 | make 18 | and in the test directory you can do 19 | 20 | ./test_key_exchange 21 | This will run a key exchange demo for a 46bit prime. There are four sample parameter sets in the test 22 | directory called `public_params_*`. For example, to run the demo for a 521bit prime you can do 23 | 24 | ./test_key_exchange public_params_521 25 | You can test your own parameter set, provided it is in the same format as the sample sets. 26 | -------------------------------------------------------------------------------- /sidh/Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = build 2 | TEST_DIR = test 3 | LIB_NAME = libsidh.a 4 | 5 | SOURCES = sidh_elliptic_curve.c\ 6 | sidh_isogeny.c\ 7 | sidh_private_key.c\ 8 | sidh_public_key.c\ 9 | sidh_public_param.c\ 10 | sidh_quadratic_ext.c\ 11 | sidh_shared_key.c\ 12 | sidh_util.c\ 13 | sidh_public_key_encryption.c\ 14 | sidh_elliptic_curve_dlp.c\ 15 | sidh_public_key_validation.c 16 | 17 | OBJECTS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(SOURCES)) 18 | 19 | GCC=gcc 20 | GCCFLAGS=-Wall -O0 -g -march=native -std=c11 21 | 22 | 23 | .PHONY: clean 24 | 25 | all: $(OBJECTS) $(LIB_NAME) gen_exec 26 | 27 | clean: 28 | rm -rf $(BUILD_DIR) 29 | cd $(TEST_DIR) && $(MAKE) clean 30 | 31 | $(BUILD_DIR)/%.o: %.c 32 | $(GCC) -c $< -o $@ $(GCCFLAGS) 33 | 34 | $(LIB_NAME): $(OBJECTS) 35 | ar rcs $(BUILD_DIR)/$@ $^ 36 | 37 | gen_exec: 38 | cd $(TEST_DIR) && $(MAKE) 39 | 40 | # make the build dir if not exist 41 | $(OBJECTS) : | $(BUILD_DIR) 42 | $(BUILD_DIR) : 43 | mkdir $(BUILD_DIR) 44 | -------------------------------------------------------------------------------- /sidh/sidh_elliptic_curve.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #include 20 | 21 | #include "sidh_elliptic_curve.h" 22 | #include "sidh_util.h" 23 | #include 24 | 25 | void sidh_elliptic_curve_init(elliptic_curve_t E) { 26 | sidh_fp2_init_set_si(E->a, 0, 1); 27 | sidh_fp2_init_set_si(E->b, 0, 1); 28 | } 29 | 30 | void sidh_elliptic_curve_set(elliptic_curve_t E, 31 | const elliptic_curve_t T) { 32 | sidh_fp2_set(E->a, T->a); 33 | sidh_fp2_set(E->b, T->b); 34 | } 35 | 36 | void sidh_elliptic_curve_set_coeffs(elliptic_curve_t E, 37 | const fp2_element_t a, 38 | const fp2_element_t b) { 39 | sidh_fp2_set(E->a, a); 40 | sidh_fp2_set(E->b, b); 41 | } 42 | 43 | void sidh_point_init(point_t P) { 44 | sidh_fp2_init(P->x); 45 | sidh_fp2_init(P->y); 46 | sidh_point_zero(P); 47 | } 48 | 49 | void sidh_point_set_coordinates(point_t P, 50 | const fp2_element_t x, 51 | const fp2_element_t y, 52 | int z) { 53 | sidh_fp2_set(P->x, x); 54 | sidh_fp2_set(P->y, y); 55 | P->z = z; 56 | } 57 | 58 | void sidh_point_set(point_t P, 59 | const point_t Q) { 60 | sidh_point_set_coordinates(P, Q->x, Q->y, Q->z); 61 | } 62 | 63 | void sidh_point_zero(point_t P) { 64 | sidh_fp2_zero(P->x); 65 | sidh_fp2_one(P->y); 66 | P->z = 0; 67 | } 68 | 69 | int sidh_point_is_zero(const point_t P) { 70 | return P->z == 0; 71 | } 72 | 73 | void sidh_point_negate(point_t P, 74 | const point_t Q) { 75 | sidh_point_set(P, Q); 76 | sidh_fp2_negate(P->y, P->y); 77 | } 78 | 79 | int sidh_point_has_order_2(const point_t P) { 80 | return sidh_fp2_is_zero(P->y); 81 | } 82 | 83 | void sidh_elliptic_curve_clear(elliptic_curve_t E) { 84 | sidh_fp2_clear(E->a); 85 | sidh_fp2_clear(E->b); 86 | } 87 | 88 | void sidh_point_clear(point_t P) { 89 | sidh_fp2_clear(P->x); 90 | sidh_fp2_clear(P->y); 91 | } 92 | 93 | int sidh_point_equals(const point_t P, 94 | const point_t Q) { 95 | return sidh_fp2_equals(P->x, Q->x) && 96 | sidh_fp2_equals(P->y, Q->y) && 97 | (P->z == Q->z); 98 | } 99 | 100 | char *sidh_elliptic_curve_get_str(const elliptic_curve_t E) { 101 | char *result = ""; 102 | result = sidh_concat(result, "y^2 = x^3"); 103 | if (!sidh_fp2_is_zero(E->a)) { 104 | result = sidh_concat(result, " + ("); 105 | result = sidh_concat(result, sidh_fp2_get_str(E->a)); 106 | result = sidh_concat(result, ")"); 107 | result = sidh_concat(result, " * x"); 108 | } 109 | 110 | if (!sidh_fp2_is_zero(E->b)) { 111 | result = sidh_concat(result, " + ("); 112 | result = sidh_concat(result, sidh_fp2_get_str(E->b)); 113 | result = sidh_concat(result, ")"); 114 | } 115 | 116 | return result; 117 | } 118 | 119 | char *sidh_point_get_str(const point_t P) { 120 | char *result = ""; 121 | result = sidh_concat(result, "("); 122 | result = sidh_concat(result, sidh_fp2_get_str(P->x)); 123 | result = sidh_concat(result, " : "); 124 | result = sidh_concat(result, sidh_fp2_get_str(P->y)); 125 | result = sidh_concat(result, " : "); 126 | result = sidh_concat(result, (P->z == 1 ? "1" : "0")); 127 | result = sidh_concat(result, ")"); 128 | 129 | return result; 130 | } 131 | 132 | void sidh_point_add_with_lambda(point_t R, 133 | const point_t P, 134 | const point_t Q, 135 | const fp2_element_t lambda) { 136 | point_t result; 137 | sidh_point_init(result); 138 | result->z = 1; 139 | 140 | // x_R = lambda^2 - x_P - x_Q 141 | sidh_fp2_square(result->x, lambda); 142 | sidh_fp2_sub(result->x, result->x, P->x); 143 | sidh_fp2_sub(result->x, result->x, Q->x); 144 | 145 | // y_R = lambda * (x_P - x_R) - y_P 146 | sidh_fp2_sub(result->y, P->x, result->x); 147 | sidh_fp2_mul(result->y, result->y, lambda); 148 | sidh_fp2_sub(result->y, result->y, P->y); 149 | sidh_point_set(R, result); 150 | 151 | sidh_point_clear(result); 152 | } 153 | 154 | void sidh_point_double(point_t R, 155 | const point_t P, 156 | const elliptic_curve_t E) { 157 | if (sidh_point_is_zero(P)) { 158 | sidh_point_zero(R); 159 | return; 160 | } 161 | 162 | // check if the point is of order 2 163 | if (sidh_point_has_order_2(P)) { 164 | sidh_point_zero(R); 165 | return; 166 | } 167 | 168 | fp2_element_t temp; 169 | fp2_element_t lambda; 170 | 171 | sidh_fp2_init(temp); 172 | sidh_fp2_init(lambda); 173 | 174 | // lambda = (3(x_P)^2 + a) / (2y_p) 175 | sidh_fp2_square(lambda, P->x); 176 | sidh_fp2_mul_scaler_si(lambda, lambda, 3); 177 | sidh_fp2_add(lambda, lambda, E->a); 178 | sidh_fp2_mul_scaler_si(temp, P->y, 2); 179 | sidh_fp2_div(lambda, lambda, temp); 180 | 181 | sidh_point_add_with_lambda(R, P, P, lambda); 182 | 183 | sidh_fp2_clear(temp); 184 | sidh_fp2_clear(lambda); 185 | } 186 | 187 | void sidh_point_add(point_t R, 188 | const point_t P, 189 | const point_t Q, 190 | const elliptic_curve_t E) { 191 | if (sidh_point_is_zero(P)) { 192 | sidh_point_set(R, Q); 193 | return; 194 | } 195 | 196 | if (sidh_point_is_zero(Q)) { 197 | sidh_point_set(R, P); 198 | return; 199 | } 200 | 201 | if (sidh_fp2_equals(P->x, Q->x)) { 202 | if (sidh_fp2_equals(P->y, Q->y)) { 203 | sidh_point_double(R, P, E); 204 | return; 205 | } 206 | 207 | sidh_point_zero(R); 208 | return; 209 | } 210 | 211 | fp2_element_t temp; 212 | fp2_element_t lambda; 213 | 214 | sidh_fp2_init(temp); 215 | sidh_fp2_init(lambda); 216 | 217 | // lambda = (y_Q - y_P) / (x_Q - x_P) 218 | sidh_fp2_sub(lambda, Q->y, P->y); 219 | sidh_fp2_sub(temp, Q->x, P->x); 220 | sidh_fp2_div(lambda, lambda, temp); 221 | 222 | sidh_point_add_with_lambda(R, P, Q, lambda); 223 | 224 | sidh_fp2_clear(temp); 225 | sidh_fp2_clear(lambda); 226 | } 227 | 228 | void sidh_point_sub(point_t R, 229 | const point_t P, 230 | const point_t Q, 231 | const elliptic_curve_t E) { 232 | point_t temp; 233 | sidh_point_init(temp); 234 | sidh_point_negate(temp, Q); 235 | sidh_point_add(R, P, temp, E); 236 | sidh_point_clear(temp); 237 | } 238 | 239 | void sidh_point_mul_scaler(point_t R, 240 | const point_t P, 241 | const mpz_t scaler, 242 | const elliptic_curve_t E) { 243 | if (mpz_cmp_ui(scaler, 0) == 0) { 244 | sidh_point_zero(R); 245 | return; 246 | } 247 | 248 | if (mpz_cmp_ui(scaler, 1) == 0) { 249 | sidh_point_set(R, P); 250 | return; 251 | } 252 | 253 | point_t R0; 254 | point_t R1; 255 | 256 | sidh_point_init(R0); 257 | sidh_point_init(R1); 258 | sidh_point_set(R1, P); 259 | 260 | long num_bits = mpz_sizeinbase(scaler, 2); 261 | for (long i = 0; i < num_bits; i++) { 262 | if (mpz_tstbit(scaler, i) == 1) 263 | sidh_point_add(R0, R0, R1, E); 264 | sidh_point_double(R1, R1, E); 265 | } 266 | 267 | if (mpz_sgn(scaler) < 0) 268 | sidh_point_negate(R0, R0); 269 | 270 | sidh_point_set(R, R0); 271 | sidh_point_clear(R0); 272 | sidh_point_clear(R1); 273 | } 274 | 275 | void sidh_point_mul_scaler_si(point_t R, 276 | const point_t P, 277 | long scaler, 278 | const elliptic_curve_t E) { 279 | mpz_t temp; 280 | mpz_init_set_si(temp, scaler); 281 | sidh_point_mul_scaler(R, P, temp, E); 282 | mpz_clear(temp); 283 | } 284 | 285 | void sidh_elliptic_curve_compute_j_inv(fp2_element_t j_inv, 286 | const elliptic_curve_t E) { 287 | fp2_element_t result; 288 | fp2_element_t temp; 289 | sidh_fp2_init(result); 290 | sidh_fp2_init(temp); 291 | 292 | sidh_fp2_pow_ui(temp, E->a, 3); 293 | sidh_fp2_mul_scaler_si(temp, temp, 4); 294 | sidh_fp2_square(result, E->b); 295 | sidh_fp2_mul_scaler_si(result, result, 27); 296 | sidh_fp2_add(result, result, temp); 297 | sidh_fp2_inv(result, result); 298 | sidh_fp2_mul(result, result, temp); 299 | sidh_fp2_mul_scaler_si(result, result, 1728); 300 | sidh_fp2_set(j_inv, result); 301 | 302 | sidh_fp2_clear(result); 303 | sidh_fp2_clear(temp); 304 | } 305 | 306 | int sidh_point_is_on_curve(const point_t P, 307 | const elliptic_curve_t E) { 308 | 309 | if (sidh_point_is_zero(P)) 310 | return 1; 311 | 312 | fp2_element_t temp_x; 313 | sidh_fp2_init(temp_x); 314 | 315 | // compute x^3 + a * x + b = x * (x^2 + a) + b 316 | sidh_fp2_square(temp_x, P->x); 317 | sidh_fp2_add(temp_x, temp_x, E->a); 318 | sidh_fp2_mul(temp_x, temp_x, P->x); 319 | sidh_fp2_add(temp_x, temp_x, E->b); 320 | 321 | fp2_element_t temp_y; 322 | sidh_fp2_init(temp_y); 323 | sidh_fp2_square(temp_y, P->y); 324 | 325 | int result = sidh_fp2_equals(temp_y, temp_x); 326 | 327 | sidh_fp2_clear(temp_x); 328 | sidh_fp2_clear(temp_y); 329 | 330 | return result; 331 | } 332 | 333 | void sidh_elliptic_curve_random_point(point_t P, 334 | const elliptic_curve_t E) { 335 | point_t result; 336 | sidh_point_init(result); 337 | result->z = 1; 338 | 339 | fp2_element_t temp_x; 340 | sidh_fp2_init(temp_x); 341 | 342 | fp2_element_t temp_y; 343 | sidh_fp2_init(temp_y); 344 | 345 | gmp_randstate_t randstate; 346 | gmp_randinit_default(randstate); 347 | 348 | while (1) { 349 | sidh_fp2_random(result->x, randstate); 350 | 351 | // compute x^3 + a * x + b = x * (x^2 + a) + b 352 | sidh_fp2_square(temp_x, result->x); 353 | sidh_fp2_add(temp_x, temp_x, E->a); 354 | sidh_fp2_mul(temp_x, temp_x, result->x); 355 | sidh_fp2_add(temp_x, temp_x, E->b); 356 | 357 | if (sidh_fp2_is_square(temp_x)) { 358 | sidh_fp2_sqrt(result->y, temp_x); 359 | break; 360 | } 361 | } 362 | 363 | sidh_point_set(P, result); 364 | 365 | sidh_point_clear(result); 366 | sidh_fp2_clear(temp_x); 367 | sidh_fp2_clear(temp_y); 368 | gmp_randclear(randstate); 369 | } 370 | -------------------------------------------------------------------------------- /sidh/sidh_elliptic_curve.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #ifndef CURVE_H 20 | #define CURVE_H 21 | 22 | #include "sidh_quadratic_ext.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /** 29 | * Representation of the elliptic curve y^2 = x^3 + a * x^2 + b * x 30 | */ 31 | typedef struct { 32 | fp2_element_t a; 33 | fp2_element_t b; 34 | } elliptic_curve_struct; 35 | 36 | typedef elliptic_curve_struct elliptic_curve_t[1]; 37 | 38 | /** 39 | * Representation of a point in the standard affine D+(z) of the 40 | * plain projective projective space 41 | */ 42 | typedef struct { 43 | fp2_element_t x; 44 | fp2_element_t y; 45 | int z; 46 | } point_struct; 47 | 48 | typedef point_struct point_t[1]; 49 | 50 | /** 51 | * Initializes the input curve to y^2 = x^3 + x + 1. 52 | * @param E 53 | */ 54 | void sidh_elliptic_curve_init(elliptic_curve_t E); 55 | 56 | /** 57 | * Copies T into E 58 | * @param E 59 | * @param T 60 | */ 61 | void sidh_elliptic_curve_set(elliptic_curve_t E, 62 | const elliptic_curve_t T); 63 | 64 | /** 65 | * Sets the coefficients of E: y^2 = x^3 + a * x^2 + b * x. 66 | * @param E 67 | * @param a 68 | * @param b 69 | */ 70 | void sidh_elliptic_curve_set_coeffs(elliptic_curve_t E, 71 | const fp2_element_t a, 72 | const fp2_element_t b); 73 | 74 | /** 75 | * Initializes the point {@code P} to the zero point (0 : 1 : 0). 76 | * @param P 77 | */ 78 | void sidh_point_init(point_t P); 79 | 80 | /** 81 | * Sets the coordinates of the point {@code P}. 82 | * @param P 83 | * @param x 84 | * @param y 85 | * @param z 86 | */ 87 | void sidh_point_set_coordinates(point_t P, 88 | const fp2_element_t x, 89 | const fp2_element_t y, 90 | int z); 91 | 92 | /** 93 | * Copies {@code Q} into {@code P} 94 | * @param P 95 | * @param Q 96 | */ 97 | void sidh_point_set(point_t P, 98 | const point_t Q); 99 | 100 | /** 101 | * Sets the given point to zero. 102 | * @param P 103 | */ 104 | void sidh_point_zero(point_t P); 105 | 106 | /** 107 | * Checks if a given point is zero. 108 | * @param P 109 | * @return 110 | */ 111 | int sidh_point_is_zero(const point_t P); 112 | 113 | /** 114 | * Sets {@code P} to {@code -Q} as a group element. 115 | * @param P 116 | * @param Q 117 | */ 118 | void sidh_point_negate(point_t P, 119 | const point_t Q); 120 | 121 | /** 122 | * Checks if 2 * {@code P} = 0. 123 | * @param P 124 | * @return 125 | */ 126 | int sidh_point_has_order_2(const point_t P); 127 | 128 | /** 129 | * Frees the memory allocated to {@code E}. 130 | * @param E 131 | */ 132 | void sidh_elliptic_curve_clear(elliptic_curve_t E); 133 | 134 | /** 135 | * Frees the memory allocated to {@code P}. 136 | * @param P 137 | */ 138 | void sidh_point_clear(point_t P); 139 | 140 | /** 141 | * Checks if {@code P = Q}. 142 | * @param P 143 | * @param Q 144 | * @return 1 if the points are equal, 0 otherwise 145 | */ 146 | int sidh_point_equals(const point_t P, 147 | const point_t Q); 148 | 149 | /** 150 | * @param E 151 | * @return A string representation of {@code E} 152 | */ 153 | char *sidh_elliptic_curve_get_str(const elliptic_curve_t E); 154 | 155 | /** 156 | * @param P 157 | * @return A string representation of {@code P} 158 | */ 159 | char *sidh_point_get_str(const point_t P); 160 | 161 | /** 162 | * Sets {@code R = P + Q} on {@code E}. 163 | * @param R 164 | * @param P 165 | * @param Q 166 | * @param E 167 | */ 168 | void sidh_point_add(point_t R, 169 | const point_t P, 170 | const point_t Q, 171 | const elliptic_curve_t E); 172 | 173 | /** 174 | * Sets {@code R = P - Q}. 175 | * @param R 176 | * @param P 177 | * @param Q 178 | * @param E 179 | */ 180 | void sidh_point_sub(point_t R, 181 | const point_t P, 182 | const point_t Q, 183 | const elliptic_curve_t E); 184 | 185 | /** 186 | * Sets {@code R = P + Q} on {@code E}. 187 | * @param R 188 | * @param P 189 | * @param Q 190 | * @param lambda The slope of the line passing through {@code P, Q} 191 | */ 192 | void sidh_point_add_with_lambda(point_t R, 193 | const point_t P, 194 | const point_t Q, 195 | const fp2_element_t lambda); 196 | 197 | /** 198 | * Sets {@code R = 2 * P} on {@code E}. 199 | * @param R 200 | * @param P 201 | * @param E 202 | */ 203 | void sidh_point_double(point_t R, 204 | const point_t P, 205 | const elliptic_curve_t E); 206 | 207 | /** 208 | * Sets {@code R = scaler * P} on {@code E}. 209 | * @param R 210 | * @param P 211 | * @param scaler 212 | * @param E 213 | */ 214 | void sidh_point_mul_scaler(point_t R, 215 | const point_t P, 216 | const mpz_t scaler, 217 | const elliptic_curve_t E); 218 | 219 | /** 220 | * {@link sidh_point_mul_scaler} 221 | * @param R 222 | * @param P 223 | * @param scaler 224 | * @param E 225 | */ 226 | void sidh_point_mul_scaler_si(point_t R, 227 | const point_t P, 228 | long scaler, 229 | const elliptic_curve_t E); 230 | 231 | /** 232 | * Computes the j-invariant of {@code E}. 233 | * @param j_inv 234 | * @param E 235 | */ 236 | void sidh_elliptic_curve_compute_j_inv(fp2_element_t j_inv, 237 | const elliptic_curve_t E); 238 | 239 | /** 240 | * Checks if the point {@code P} is on the curve {@code E}. 241 | * @param P 242 | * @param E 243 | * @return 1 if the point is on the curve, 0 otherwise 244 | */ 245 | int sidh_point_is_on_curve(const point_t P, 246 | const elliptic_curve_t E); 247 | 248 | /** 249 | * Generates a random point on the curve {@code E}. 250 | * @param P the generated random point. 251 | * @param E 252 | */ 253 | void sidh_elliptic_curve_random_point(point_t P, 254 | const elliptic_curve_t E); 255 | 256 | #ifdef __cplusplus 257 | } 258 | #endif 259 | 260 | #endif /* CURVE_H */ 261 | 262 | -------------------------------------------------------------------------------- /sidh/sidh_elliptic_curve_dlp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "sidh_elliptic_curve_dlp.h" 19 | #include 20 | 21 | void sidh_elliptic_curve_prime_power_dlp(mpz_t x, 22 | const point_t P, 23 | const point_t Q, 24 | const elliptic_curve_t E, 25 | long l, 26 | long e) { 27 | mpz_t exponent1; 28 | mpz_t exponent2; 29 | point_t temp_P; 30 | point_t temp_Q; 31 | point_t temp_R; 32 | point_t PP; 33 | 34 | mpz_init(exponent1); 35 | mpz_init(exponent2); 36 | sidh_point_init(temp_P); 37 | sidh_point_init(temp_Q); 38 | sidh_point_init(temp_R); 39 | sidh_point_init(PP); 40 | 41 | int ladic_rep[e]; 42 | mpz_ui_pow_ui(exponent1, l, e - 1); 43 | 44 | // PP = l^(e - 1) * P once and for all 45 | sidh_point_mul_scaler(PP, P, exponent1, E); 46 | 47 | // compute the first ladic coefficient 48 | sidh_point_mul_scaler(temp_Q, Q, exponent1, E); 49 | long ladic_coeff = sidh_elliptic_curve_prime_dlp(PP, temp_Q, E, l); 50 | 51 | for (int j = 1; j < e; j++) { 52 | if (ladic_coeff >= 0) { 53 | ladic_rep[j - 1] = ladic_coeff; 54 | } else { 55 | break; 56 | } 57 | 58 | mpz_ui_pow_ui(exponent2, l, j - 1); 59 | mpz_mul_ui(exponent2, exponent2, ladic_rep[j - 1]); 60 | mpz_divexact_ui(exponent1, exponent1, l); 61 | sidh_point_mul_scaler(temp_P, P, exponent2, E); 62 | sidh_point_add(temp_R, temp_R, temp_P, E); 63 | sidh_point_sub(temp_Q, Q, temp_R, E); 64 | sidh_point_mul_scaler(temp_Q, temp_Q, exponent1, E); 65 | ladic_coeff = sidh_elliptic_curve_prime_dlp(PP, temp_Q, E, l); 66 | } 67 | 68 | if (ladic_coeff >= 0) { 69 | ladic_rep[e - 1] = ladic_coeff; 70 | 71 | // set x = l_{e - 1}l^{e - 1} + ... + l_1l + l_0 72 | mpz_set_ui(x, ladic_rep[e - 1]); 73 | for (long i = e - 2; i >= 0; i--) { 74 | mpz_mul_ui(x, x, l); 75 | mpz_add_ui(x, x, ladic_rep[i]); 76 | } 77 | } else { 78 | mpz_set_si(x, -1); 79 | } 80 | 81 | mpz_clear(exponent1); 82 | mpz_clear(exponent2); 83 | sidh_point_clear(temp_P); 84 | sidh_point_clear(temp_Q); 85 | sidh_point_clear(temp_R); 86 | sidh_point_clear(PP); 87 | } 88 | 89 | long sidh_elliptic_curve_prime_dlp(const point_t P, 90 | const point_t Q, 91 | const elliptic_curve_t E, 92 | long l) { 93 | if (sidh_point_is_zero(Q)) 94 | return 0; 95 | 96 | if (sidh_point_equals(P, Q)) 97 | return 1; 98 | 99 | point_t temp; 100 | sidh_point_init(temp); 101 | sidh_point_set(temp, P); 102 | 103 | long result = -1; 104 | for (long i = 2; i < l; i++) { 105 | sidh_point_add(temp, temp, P, E); 106 | if (sidh_point_equals(temp, Q)) { 107 | result = i; 108 | break; 109 | } 110 | } 111 | 112 | sidh_point_clear(temp); 113 | return result; 114 | } -------------------------------------------------------------------------------- /sidh/sidh_elliptic_curve_dlp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #ifndef ELLIPTIC_CURVE_DLP_H 20 | #define ELLIPTIC_CURVE_DLP_H 21 | 22 | #include "sidh_elliptic_curve.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | 29 | /** 30 | * Computes the discrete logarithm {@code P = x * Q} in a group of order 31 | * {@code l^e} generated by {@code P}. The Pohlig–Hellman algorithm is used. 32 | * @param x the discrete logarithm if it exists, or -1 otherwise 33 | * @param P the generator of the cyclic group 34 | * @param Q an element in the the group generated by {@code P} 35 | * @param E 36 | * @param l a prime number 37 | * @param e a positive integer 38 | */ 39 | void sidh_elliptic_curve_prime_power_dlp(mpz_t x, 40 | const point_t P, 41 | const point_t Q, 42 | const elliptic_curve_t E, 43 | long l, 44 | long e); 45 | 46 | /** 47 | * Computes the discrete logarithm {@code P = x * Q} in a group of order 48 | * {@code l} generated by {@code P}. 49 | * @param P the generator of the cyclic group 50 | * @param Q an element in the the group generated by {@code P} 51 | * @param E 52 | * @param l a prime number 53 | * @return the discrete logarithm if it exists, or -1 otherwise 54 | */ 55 | long sidh_elliptic_curve_prime_dlp(const point_t P, 56 | const point_t Q, 57 | const elliptic_curve_t E, 58 | long l); 59 | 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif /* ELLIPTIC_CURVE_DLP_H */ 66 | 67 | -------------------------------------------------------------------------------- /sidh/sidh_isogeny.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include "sidh_isogeny.h" 21 | #include 22 | 23 | void sidh_isogeny_init(isogeny_t isogeny, 24 | long kernel_size) { 25 | isogeny->kernel_size = 0; 26 | isogeny->partition_size = 0; 27 | sidh_isogeny_set_kernel_size(isogeny, kernel_size); 28 | long size = isogeny->partition_size; 29 | isogeny->partition = (point_t *) malloc(size * sizeof (point_t)); 30 | isogeny->gx = (fp2_element_t *) malloc(size * sizeof (fp2_element_t)); 31 | isogeny->gy = (fp2_element_t *) malloc(size * sizeof (fp2_element_t)); 32 | isogeny->u = (fp2_element_t *) malloc(size * sizeof (fp2_element_t)); 33 | isogeny->v = (fp2_element_t *) malloc(size * sizeof (fp2_element_t)); 34 | 35 | sidh_elliptic_curve_init(isogeny->domain); 36 | sidh_elliptic_curve_init(isogeny->codomain); 37 | 38 | for (long i = 0; i < size; i++) { 39 | sidh_point_init(isogeny->partition[i]); 40 | sidh_fp2_init(isogeny->gx[i]); 41 | sidh_fp2_init(isogeny->gy[i]); 42 | sidh_fp2_init(isogeny->u[i]); 43 | sidh_fp2_init(isogeny->v[i]); 44 | } 45 | } 46 | 47 | void sidh_isogeny_clear(isogeny_t isogeny) { 48 | sidh_elliptic_curve_clear(isogeny->domain); 49 | sidh_elliptic_curve_clear(isogeny->codomain); 50 | 51 | for (long i = 0; i < isogeny->partition_size; i++) { 52 | sidh_point_clear(isogeny->partition[i]); 53 | sidh_fp2_clear(isogeny->gx[i]); 54 | sidh_fp2_clear(isogeny->gy[i]); 55 | sidh_fp2_clear(isogeny->u[i]); 56 | sidh_fp2_clear(isogeny->v[i]); 57 | } 58 | 59 | free(isogeny->partition); 60 | free(isogeny->gx); 61 | free(isogeny->gy); 62 | free(isogeny->u); 63 | free(isogeny->v); 64 | } 65 | 66 | void sidh_isogeny_compute(isogeny_t isogeny, 67 | const point_t kernel_gen) { 68 | sidh_isogeny_partition_kernel(isogeny->partition, 69 | isogeny->partition_size, 70 | kernel_gen, 71 | isogeny->domain); 72 | long size = isogeny->partition_size; 73 | 74 | // compute gx_P = 3 * x_P^2 + a 75 | for (long i = 0; i < size; i++) { 76 | sidh_fp2_square(isogeny->gx[i], isogeny->partition[i]->x); 77 | sidh_fp2_mul_scaler_si(isogeny->gx[i], isogeny->gx[i], 3); 78 | sidh_fp2_add(isogeny->gx[i], isogeny->gx[i], isogeny->domain->a); 79 | } 80 | 81 | // compute gy_P = -2y_P 82 | for (long i = 0; i < size; i++) { 83 | sidh_fp2_mul_scaler_si(isogeny->gy[i], isogeny->partition[i]->y, -2); 84 | } 85 | 86 | // compute v_P = gx_P or 2gx_P 87 | for (long i = 0; i < size; i++) { 88 | if (sidh_point_has_order_2(isogeny->partition[i])) 89 | sidh_fp2_set(isogeny->v[i], isogeny->gx[i]); 90 | else 91 | sidh_fp2_mul_scaler_si(isogeny->v[i], isogeny->gx[i], 2); 92 | } 93 | 94 | // compute u_P = gy_P^2 95 | for (long i = 0; i < size; i++) { 96 | sidh_fp2_square(isogeny->u[i], isogeny->gy[i]); 97 | } 98 | 99 | // compute the codomain curve 100 | fp2_element_t v; 101 | fp2_element_t w; 102 | fp2_element_t temp; 103 | sidh_fp2_init(v); 104 | sidh_fp2_init(w); 105 | sidh_fp2_init(temp); 106 | 107 | for (long i = 0; i < size; i++) { 108 | sidh_fp2_add(v, v, isogeny->v[i]); 109 | sidh_fp2_mul(temp, isogeny->v[i], isogeny->partition[i]->x); 110 | sidh_fp2_add(temp, isogeny->u[i], temp); 111 | sidh_fp2_add(w, w, temp); 112 | } 113 | 114 | sidh_fp2_mul_scaler_si(v, v, 5); 115 | sidh_fp2_sub(v, isogeny->domain->a, v); 116 | sidh_fp2_mul_scaler_si(w, w, 7); 117 | sidh_fp2_sub(w, isogeny->domain->b, w); 118 | sidh_elliptic_curve_set_coeffs(isogeny->codomain, v, w); 119 | 120 | sidh_fp2_clear(v); 121 | sidh_fp2_clear(w); 122 | sidh_fp2_clear(temp); 123 | } 124 | 125 | void sidh_isogeny_partition_kernel(point_t *partition, 126 | long partition_size, 127 | const point_t kernel_gen, 128 | const elliptic_curve_t E) { 129 | sidh_point_set(partition[0], kernel_gen); 130 | for (long i = 1; i < partition_size; i++){ 131 | sidh_point_add(partition[i], partition[i - 1], kernel_gen, E); 132 | } 133 | } 134 | 135 | void sidh_isogeny_set_kernel_size(isogeny_t isogeny, 136 | long kernel_size) { 137 | long current_size = isogeny->kernel_size; 138 | if (current_size != 0 && current_size <= kernel_size) 139 | return; 140 | 141 | current_size = isogeny->partition_size; 142 | isogeny->kernel_size = kernel_size; 143 | 144 | if (kernel_size % 2 == 0) 145 | isogeny->partition_size = kernel_size / 2; 146 | else 147 | isogeny->partition_size = (kernel_size - 1) / 2; 148 | 149 | // clear the the unused memory after shrinking 150 | for (long i = isogeny->partition_size; i < current_size; i++) { 151 | sidh_point_clear(isogeny->partition[i]); 152 | sidh_fp2_clear(isogeny->gx[i]); 153 | sidh_fp2_clear(isogeny->gy[i]); 154 | sidh_fp2_clear(isogeny->u[i]); 155 | sidh_fp2_clear(isogeny->v[i]); 156 | } 157 | } 158 | 159 | void sidh_isogeny_evaluate_velu(point_t Q, 160 | const isogeny_t isogeny, 161 | const point_t P) { 162 | 163 | if (sidh_point_is_zero(P)) { 164 | sidh_point_zero(Q); 165 | return; 166 | } 167 | 168 | long size = isogeny->partition_size; 169 | 170 | fp2_element_t temp1; 171 | fp2_element_t temp2; 172 | fp2_element_t temp3; 173 | sidh_fp2_init(temp1); 174 | sidh_fp2_init(temp2); 175 | sidh_fp2_init(temp3); 176 | 177 | point_t result; 178 | sidh_point_init(result); 179 | sidh_point_set(result, P); 180 | 181 | for (long i = 0; i < size; i++) { 182 | sidh_fp2_sub(temp1, P->x, isogeny->partition[i]->x); 183 | 184 | // check if the point is in the kernel 185 | if (sidh_fp2_is_zero(temp1)) { 186 | sidh_point_zero(result); 187 | break; 188 | } 189 | 190 | // 1 / (x - x_P) 191 | sidh_fp2_inv(temp1, temp1); 192 | 193 | // add 1 / (x - x_P) * (v_P + u_P / (x - x_P)) to x 194 | sidh_fp2_mul(temp2, isogeny->u[i], temp1); 195 | sidh_fp2_add(temp2, temp2, isogeny->v[i]); 196 | sidh_fp2_mul(temp2, temp2, temp1); 197 | sidh_fp2_add(result->x, result->x, temp2); 198 | 199 | // v_P * (y - y_P) - gx_P * gy_P 200 | sidh_fp2_sub(temp2, P->y, isogeny->partition[i]->y); 201 | sidh_fp2_mul(temp2, temp2, isogeny->v[i]); 202 | sidh_fp2_mul(temp3, isogeny->gx[i], isogeny->gy[i]); 203 | sidh_fp2_sub(temp2, temp2, temp3); 204 | 205 | // 2 * u_P * y / (x - x_P) 206 | sidh_fp2_mul(temp3, isogeny->u[i], P->y); 207 | sidh_fp2_mul_scaler_si(temp3, temp3, 2); 208 | sidh_fp2_mul(temp3, temp3, temp1); 209 | 210 | sidh_fp2_add(temp3, temp3, temp2); 211 | sidh_fp2_square(temp1, temp1); 212 | sidh_fp2_mul(temp3, temp3, temp1); 213 | sidh_fp2_sub(result->y, result->y, temp3); 214 | } 215 | 216 | sidh_point_set(Q, result); 217 | 218 | sidh_point_clear(result); 219 | sidh_fp2_clear(temp1); 220 | sidh_fp2_clear(temp2); 221 | sidh_fp2_clear(temp3); 222 | } 223 | 224 | void sidh_isogeny_evaluate_kohel(point_t Q, 225 | const isogeny_t isogeny, 226 | const point_t P) { 227 | fp2_element_t ix1; 228 | fp2_element_t ix2; 229 | fp2_element_t ix3; 230 | fp2_element_t temp1; 231 | fp2_element_t temp2; 232 | fp2_element_t temp3; 233 | fp2_element_t sigma1; 234 | 235 | sidh_fp2_init(ix1); 236 | sidh_fp2_init(ix2); 237 | sidh_fp2_init(ix3); 238 | sidh_fp2_init(temp1); 239 | sidh_fp2_init(temp2); 240 | sidh_fp2_init(temp3); 241 | sidh_fp2_init(sigma1); 242 | 243 | point_t result; 244 | sidh_point_init(result); 245 | sidh_point_set(result, P); 246 | 247 | long size = isogeny->partition_size; 248 | 249 | for (long i = 0; i < size; i++) { 250 | sidh_fp2_add(sigma1, sigma1, isogeny->partition[i]->x); 251 | sidh_fp2_sub(temp1, P->x, isogeny->partition[i]->x); 252 | 253 | // check if the point is in the kernel 254 | if (sidh_fp2_is_zero(temp1)) { 255 | sidh_point_zero(result); 256 | break; 257 | } 258 | 259 | // 1 / (x - x_P) 260 | sidh_fp2_inv(temp1, temp1); 261 | 262 | // 1 / (x - x_P)^2 263 | sidh_fp2_square(temp2, temp1); 264 | 265 | // 1 / (x - x_P)^3 266 | sidh_fp2_mul(temp3, temp2, temp1); 267 | 268 | if (!sidh_point_has_order_2(isogeny->partition[i])) { 269 | sidh_fp2_add(temp1, temp1, temp1); 270 | sidh_fp2_add(temp2, temp2, temp2); 271 | sidh_fp2_add(temp3, temp3, temp3); 272 | sidh_fp2_add(sigma1, sigma1, isogeny->partition[i]->x); 273 | } 274 | 275 | sidh_fp2_add(ix1, ix1, temp1); 276 | sidh_fp2_add(ix2, ix2, temp2); 277 | sidh_fp2_add(ix3, ix3, temp3); 278 | } 279 | 280 | if (!sidh_point_is_zero(result)) { 281 | fp2_element_t u1; 282 | fp2_element_t u2; 283 | 284 | sidh_fp2_init(u1); 285 | sidh_fp2_init(u2); 286 | 287 | // 3 * x^2 + a 288 | sidh_fp2_square(u1, P->x); 289 | sidh_fp2_mul_scaler_si(u1, u1, 3); 290 | sidh_fp2_add(u1, u1, isogeny->domain->a); 291 | 292 | // 2 * y^2 293 | sidh_fp2_square(u2, P->y); 294 | sidh_fp2_mul_scaler_si(u2, u2, 2); 295 | 296 | // compute the first coordinate 297 | sidh_fp2_mul_scaler_si(result->x, P->x, isogeny->kernel_size); 298 | sidh_fp2_sub(result->x, result->x, sigma1); 299 | sidh_fp2_mul(temp1, u1, ix1); 300 | sidh_fp2_sub(result->x, result->x, temp1); 301 | sidh_fp2_mul(temp1, u2, ix2); 302 | sidh_fp2_add(result->x, result->x, temp1); 303 | 304 | // compute the second coordinate 305 | sidh_fp2_mul_scaler_si(temp1, P->x, -6); 306 | sidh_fp2_mul(result->y, temp1, ix1); 307 | sidh_fp2_add_ui(result->y, result->y, isogeny->kernel_size); 308 | sidh_fp2_mul_scaler_si(temp1, u1, 3); 309 | sidh_fp2_mul(temp1, temp1, ix2); 310 | sidh_fp2_add(result->y, result->y, temp1); 311 | sidh_fp2_mul_scaler_si(temp1, u2, -2); 312 | sidh_fp2_mul(temp1, temp1, ix3); 313 | sidh_fp2_add(result->y, result->y, temp1); 314 | sidh_fp2_mul(result->y, result->y, P->y); 315 | 316 | sidh_fp2_clear(u1); 317 | sidh_fp2_clear(u2); 318 | } 319 | 320 | sidh_point_set(Q, result); 321 | 322 | sidh_point_clear(result); 323 | sidh_fp2_clear(ix1); 324 | sidh_fp2_clear(ix2); 325 | sidh_fp2_clear(ix3); 326 | sidh_fp2_clear(temp1); 327 | sidh_fp2_clear(temp2); 328 | sidh_fp2_clear(temp3); 329 | sidh_fp2_clear(sigma1); 330 | } 331 | 332 | void sidh_isogeny_evaluate_naive(elliptic_curve_t E, 333 | point_t *points, 334 | long num_points, 335 | const point_t kernel_gen, 336 | long l, 337 | long e, 338 | long isogeny_jump) { 339 | 340 | point_t temp_gen; 341 | sidh_point_init(temp_gen); 342 | sidh_point_set(temp_gen, kernel_gen); 343 | 344 | mpz_t le; 345 | mpz_init(le); 346 | mpz_ui_pow_ui(le, l, e); 347 | 348 | long kernel_size = 0; 349 | if (e <= isogeny_jump) 350 | kernel_size = mpz_get_si(le); 351 | else 352 | kernel_size = (long) pow(l, isogeny_jump); 353 | 354 | isogeny_t isogeny; 355 | sidh_isogeny_init(isogeny, kernel_size); 356 | sidh_elliptic_curve_set(isogeny->domain, E); 357 | 358 | long i = 0; 359 | while (i < e) { 360 | mpz_divexact_ui(le, le, kernel_size); 361 | sidh_isogeny_evaluate_naive_helper(isogeny, 362 | E, 363 | points, 364 | num_points, 365 | temp_gen, 366 | le); 367 | i += isogeny_jump; 368 | 369 | if ((e - i > 0) && (e - i) < isogeny_jump) { 370 | kernel_size = (long) pow(l, e - i); 371 | sidh_isogeny_set_kernel_size(isogeny, kernel_size); 372 | } 373 | } 374 | 375 | sidh_point_clear(temp_gen); 376 | mpz_clear(le); 377 | sidh_isogeny_clear(isogeny); 378 | } 379 | 380 | void sidh_isogeny_evaluate_naive_curve(elliptic_curve_t E, 381 | const point_t kernel_gen, 382 | long l, 383 | long e, 384 | long isogeny_jump) { 385 | sidh_isogeny_evaluate_naive(E, NULL, 0, kernel_gen, l, e, isogeny_jump); 386 | } 387 | 388 | void sidh_isogeny_evaluate_naive_helper(isogeny_t isogeny, 389 | elliptic_curve_t E, 390 | point_t *points, 391 | long num_points, 392 | point_t kernel_gen, 393 | const mpz_t le) { 394 | point_t K; 395 | sidh_point_init(K); 396 | 397 | sidh_point_mul_scaler(K, kernel_gen, le, E); 398 | sidh_isogeny_compute(isogeny, K); 399 | sidh_isogeny_evaluate_kohel(kernel_gen, isogeny, kernel_gen); 400 | 401 | for (long i = 0; i < num_points; i++) { 402 | sidh_isogeny_evaluate_kohel(points[i], isogeny, points[i]); 403 | } 404 | 405 | sidh_elliptic_curve_set(E, isogeny->codomain); 406 | sidh_elliptic_curve_set(isogeny->domain, isogeny->codomain); 407 | 408 | sidh_point_clear(K); 409 | } 410 | 411 | void sidh_isogeny_evaluate_strategy_rec(elliptic_curve_t E, 412 | point_t *points, 413 | long num_points, 414 | point_t *kernel_gens, 415 | long num_gens, 416 | long l, 417 | long e, 418 | float ratio) { 419 | 420 | if (e == 1) { 421 | isogeny_t isogeny; 422 | 423 | long kernel_size = (long) pow(l, e); 424 | sidh_isogeny_init(isogeny, kernel_size); 425 | sidh_elliptic_curve_set(isogeny->domain, E); 426 | sidh_isogeny_compute(isogeny, kernel_gens[num_gens - 1]); 427 | sidh_elliptic_curve_set(E, isogeny->codomain); 428 | 429 | for (long i = 0; i < num_points; i++) { 430 | sidh_isogeny_evaluate_velu(points[i], isogeny, points[i]); 431 | } 432 | 433 | for (long i = 0; i < num_gens - 1; i++) { 434 | sidh_isogeny_evaluate_velu(kernel_gens[i], 435 | isogeny, 436 | kernel_gens[i]); 437 | } 438 | 439 | sidh_isogeny_clear(isogeny); 440 | return; 441 | } 442 | 443 | long r = (long) (ratio * e); 444 | 445 | mpz_t exponent; 446 | mpz_init(exponent); 447 | mpz_ui_pow_ui(exponent, l, r); 448 | 449 | sidh_point_mul_scaler(kernel_gens[num_gens], 450 | kernel_gens[num_gens - 1], 451 | exponent, E); 452 | 453 | sidh_isogeny_evaluate_strategy_rec(E, points, num_points, kernel_gens, 454 | num_gens + 1, l, e - r, ratio); 455 | sidh_isogeny_evaluate_strategy_rec(E, points, num_points, kernel_gens, 456 | num_gens, l, r, ratio); 457 | mpz_clear(exponent); 458 | } 459 | 460 | void sidh_isogeny_evaluate_strategy(elliptic_curve_t E, 461 | point_t *points, 462 | long num_points, 463 | const point_t kernel_gen, 464 | long l, 465 | long e, 466 | float ratio) { 467 | 468 | point_t *kernel_gens = (point_t *) malloc(e * sizeof (point_t)); 469 | for (long i = 0; i < e; i++) 470 | sidh_point_init(kernel_gens[i]); 471 | sidh_point_set(kernel_gens[0], kernel_gen); 472 | 473 | sidh_isogeny_evaluate_strategy_rec(E, points, num_points, 474 | kernel_gens, 1, l, e, ratio); 475 | 476 | for (long i = 0; i < e; i++) 477 | sidh_point_clear(kernel_gens[i]); 478 | free(kernel_gens); 479 | } 480 | 481 | void sidh_isogeny_evaluate_strategy_curve(elliptic_curve_t E, 482 | const point_t kernel_gen, 483 | long l, 484 | long e, 485 | float ratio) { 486 | sidh_isogeny_evaluate_strategy(E, NULL, 0, kernel_gen, l, e, ratio); 487 | } 488 | 489 | -------------------------------------------------------------------------------- /sidh/sidh_isogeny.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef ISOGENY_H 19 | #define ISOGENY_H 20 | 21 | #include "sidh_elliptic_curve.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /** 28 | * Representation of an isogeny between two elliptic curve 29 | */ 30 | typedef struct { 31 | // Let the kernel K of the isogeny (excluding the zero point) be the union 32 | // of F and G such that R \in F if and only if -R \in G for all points 33 | // R \in K. Then the partition is F. 34 | point_t *partition; 35 | fp2_element_t *gx; 36 | fp2_element_t *gy; 37 | fp2_element_t *u; 38 | fp2_element_t *v; 39 | elliptic_curve_t domain; 40 | elliptic_curve_t codomain; 41 | long partition_size; 42 | long kernel_size; 43 | } isogeny_struct; 44 | 45 | typedef isogeny_struct isogeny_t[1]; 46 | 47 | /** 48 | * Initializes the isogeny {@code isogeny}. 49 | * @param isogeny 50 | * @param kernel_size 51 | */ 52 | void sidh_isogeny_init(isogeny_t isogeny, 53 | long kernel_size); 54 | 55 | /** 56 | * Frees the memory allocated to {@code isogeny}. 57 | * @param isogeny 58 | */ 59 | void sidh_isogeny_clear(isogeny_t isogeny); 60 | 61 | /** 62 | * Computes the isogeny from the kernel generated by {@code kernel_gen}. 63 | * @param isogeny 64 | * @param kernel_gen 65 | */ 66 | void sidh_isogeny_compute(isogeny_t isogeny, 67 | const point_t kernel_gen); 68 | 69 | /** 70 | * Evaluates {@code isogeny} at the point {@code P}, using Velu's formulas. 71 | * @param Q The result of the evaluation {@code isogeny(P)} 72 | * @param isogeny 73 | * @param P 74 | */ 75 | void sidh_isogeny_evaluate_velu(point_t Q, 76 | const isogeny_t isogeny, 77 | const point_t P); 78 | 79 | /** 80 | * Evaluates {@code isogeny} at the point {@code P}, using Kohel's formulas. 81 | * @param Q The result of the evaluation {@code isogeny(P)} 82 | * @param isogeny 83 | * @param P 84 | */ 85 | void sidh_isogeny_evaluate_kohel(point_t Q, 86 | const isogeny_t isogeny, 87 | const point_t P); 88 | 89 | /** 90 | * Computes the partition for the isogeny generated by {@code kernel_gen}. 91 | * @see isogeny_struct. 92 | * @param partition 93 | * @param partition_size 94 | * @param kernel_gen 95 | * @param E 96 | */ 97 | void sidh_isogeny_partition_kernel(point_t *partition, 98 | long partition_size, 99 | const point_t kernel_gen, 100 | const elliptic_curve_t E); 101 | 102 | /** 103 | * Sets the kernel size for {@code isogeny}. The new kernel size is assumed 104 | * to be smaller than the current kernel size. 105 | * @param isogeny 106 | * @param kernel_size 107 | */ 108 | void sidh_isogeny_set_kernel_size(isogeny_t isogeny, 109 | long kernel_size); 110 | 111 | /** 112 | * Computes the images of the elliptic curve {@code E} and the points 113 | * {@code points} through the isogeny with kernel generated by the point 114 | * {@code kernel_gen}. The size of the kernel is {@code l^e}. 115 | * @param E 116 | * @param points 117 | * @param num_points 118 | * @param kernel_gen 119 | * @param l 120 | * @param e the length of the chain of l-isogenies 121 | * @param isogeny_jump the number of successive l-isogenies that should 122 | * be computed at once. For example, if {@code isogeny_jump = 2} then a 123 | * chain of l-isogenies of length e is computed by doing e / 2 {l^2-isogenies}. 124 | */ 125 | void sidh_isogeny_evaluate_naive(elliptic_curve_t E, 126 | point_t *points, 127 | long num_points, 128 | const point_t kernel_gen, 129 | long l, 130 | long e, 131 | long isogeny_jump); 132 | 133 | /** 134 | * Computes the images of the elliptic curve {@code E} through the isogeny 135 | * with kernel generated by the point {@code kernel_gen}. 136 | * {@link sidh_isogeny_evaluate_naive} 137 | * @param E 138 | * @param kernel_gen 139 | * @param l 140 | * @param e 141 | * @param isogeny_jump 142 | */ 143 | void sidh_isogeny_evaluate_naive_curve(elliptic_curve_t E, 144 | const point_t kernel_gen, 145 | long l, 146 | long e, 147 | long isogeny_jump); 148 | 149 | /** 150 | * A helper method for {@link sidh_isogeny_evaluate_naive}. All the arguments except 151 | * {@code num_points, le} will be pushed through the isogeny. For example 152 | * {@code E} will be the codomain of the isogeny. This method should not be 153 | * called directly. 154 | * @param isogeny 155 | * @param E 156 | * @param points 157 | * @param num_points 158 | * @param kernel_gen 159 | * @param le 160 | */ 161 | void sidh_isogeny_evaluate_naive_helper(isogeny_t isogeny, 162 | elliptic_curve_t E, 163 | point_t *points, 164 | long num_points, 165 | point_t kernel_gen, 166 | const mpz_t le); 167 | 168 | 169 | /** 170 | * The recursion for {@link sidh_isogeny_evaluate_strategy}. 171 | * @param E 172 | * @param points see {@link sidh_isogeny_evaluate_strategy} 173 | * @param num_points see {@link sidh_isogeny_evaluate_strategy} 174 | * @param kernel_gens contains the previous kernels computed while going down 175 | * the recursion tree. 176 | * @param num_gens number of elements in {@code kernel_gens} 177 | * @param l 178 | * @param e 179 | * @param ratio see {@link sidh_isogeny_evaluate_strategy} 180 | */ 181 | void sidh_isogeny_evaluate_strategy_rec(elliptic_curve_t E, 182 | point_t *points, 183 | long num_points, 184 | point_t *kernel_gens, 185 | long num_gens, 186 | long l, 187 | long e, 188 | float ratio); 189 | 190 | 191 | /** 192 | * This method implements the optimal strategy approach proposed in the paper 193 | * De Feo, Luca, David Jao, and Jérôme Plût. "Towards quantum-resistant 194 | * cryptosystems from supersingular elliptic curve isogenies". 195 | * @param E 196 | * @param points the points to be evaluated through the isogeny 197 | * @param num_points number of points in {@code points} 198 | * @param kernel_gen the generator of the kernel of the isogeny 199 | * @param l 200 | * @param e 201 | * @param ratio a float in the range (0, 1). This indicates the portions of 202 | * the computation that is done through point multiplication and isogeny 203 | * evaluation. The larger values of {@code ratio} means more multiplication 204 | * and less isogeny evaluation. 205 | */ 206 | void sidh_isogeny_evaluate_strategy(elliptic_curve_t E, 207 | point_t *points, 208 | long num_points, 209 | const point_t kernel_gen, 210 | long l, 211 | long e, 212 | float ratio); 213 | 214 | /** 215 | * The same as {@link sidh_isogeny_evaluate_strategy} except there is no point 216 | * to evaluate through the isogeny. This method simply calls 217 | * {@link sidh_isogeny_evaluate_strategy} with {@code points = NULL, num_points = 0}. 218 | * @param E 219 | * @param kernel_gen 220 | * @param l 221 | * @param e 222 | * @param ratio 223 | */ 224 | void sidh_isogeny_evaluate_strategy_curve(elliptic_curve_t E, 225 | const point_t kernel_gen, 226 | long l, 227 | long e, 228 | float ratio); 229 | 230 | #ifdef __cplusplus 231 | } 232 | #endif 233 | 234 | #endif /* ISOGENY_H */ 235 | -------------------------------------------------------------------------------- /sidh/sidh_private_key.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "sidh_private_key.h" 19 | #include "sidh_util.h" 20 | #include "sidh_public_param.h" 21 | #include 22 | 23 | void sidh_private_key_init(private_key_t private_key) { 24 | mpz_inits(private_key->m, private_key->n, NULL); 25 | } 26 | 27 | void sidh_private_key_clear(private_key_t private_key) { 28 | mpz_clears(private_key->m, private_key->n, NULL); 29 | } 30 | 31 | void sidh_private_key_generate(private_key_t private_key, 32 | const public_params_t params) { 33 | gmp_randstate_t randstate; 34 | gmp_randinit_default(randstate); 35 | mpz_t seed; 36 | mpz_init(seed); 37 | sidh_get_random_mpz(seed); 38 | gmp_randseed(randstate, seed); 39 | 40 | while (1) { 41 | mpz_urandomm(private_key->m, randstate, params->le); 42 | mpz_urandomm(private_key->n, randstate, params->le); 43 | 44 | if (!mpz_divisible_ui_p(private_key->m, params->l)) 45 | break; 46 | 47 | if (!mpz_divisible_ui_p(private_key->n, params->l)) { 48 | mpz_swap(private_key->m, private_key->n); 49 | break; 50 | } 51 | } 52 | 53 | gmp_randclear(randstate); 54 | mpz_clear(seed); 55 | } 56 | 57 | void sidh_private_key_compute_kernel_gen(point_t gen, 58 | const private_key_t private_key, 59 | const point_t P, 60 | const point_t Q, 61 | const mpz_t le, 62 | const elliptic_curve_t E) { 63 | mpz_t temp_m; 64 | mpz_t temp_n; 65 | mpz_init_set(temp_m, private_key->m); 66 | mpz_init_set(temp_n, private_key->n); 67 | 68 | point_t result; 69 | sidh_point_init(result); 70 | 71 | mpz_invert(temp_m, temp_m, le); 72 | mpz_mul(temp_n, temp_m, temp_n); 73 | mpz_mod(temp_n, temp_n, le); 74 | 75 | sidh_point_mul_scaler(result, Q, temp_n, E); 76 | sidh_point_add(result, result, P, E); 77 | sidh_point_set(gen, result); 78 | 79 | mpz_clears(temp_m, temp_n, NULL); 80 | sidh_point_clear(result); 81 | } 82 | 83 | void sidh_private_key_to_bytes(uint8_t *bytes, 84 | const private_key_t private_key, 85 | long prime_size) { 86 | for (long i = 0; i < 2 * prime_size; i++) 87 | bytes[i] = 0; 88 | 89 | mpz_export(bytes, NULL, -1, 1, 0, 0, private_key->m); 90 | mpz_export(bytes + prime_size, NULL, -1, 1, 0, 0, private_key->n); 91 | } 92 | 93 | void sidh_bytes_to_private_key(private_key_t private_key, 94 | const uint8_t *bytes, 95 | long prime_size) { 96 | mpz_set_ui(private_key->m, 0); 97 | mpz_set_ui(private_key->n, 0); 98 | mpz_import(private_key->m, prime_size, -1, 1, 0, 0, bytes); 99 | mpz_import(private_key->n, prime_size, -1, 1, 0, 0, bytes + prime_size); 100 | } 101 | 102 | void sidh_private_key_print(const private_key_t private_key) { 103 | printf("m: %s\n", mpz_get_str(NULL, 10, private_key->m)); 104 | printf("n: %s\n", mpz_get_str(NULL, 10, private_key->n)); 105 | } 106 | 107 | -------------------------------------------------------------------------------- /sidh/sidh_private_key.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef PRIVATE_KEY_H 19 | #define PRIVATE_KEY_H 20 | 21 | #include "sidh_elliptic_curve.h" 22 | #include "sidh_public_param.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /** 29 | * Representation of the private key in sidh 30 | */ 31 | typedef struct { 32 | mpz_t m; 33 | mpz_t n; 34 | } private_key_struct; 35 | 36 | typedef private_key_struct private_key_t[1]; 37 | 38 | /** 39 | * Initializes the private-key. 40 | * @param private_key 41 | */ 42 | void sidh_private_key_init(private_key_t private_key); 43 | 44 | /** 45 | * Frees the memory allocated to the private-key. 46 | * @param private_key 47 | */ 48 | void sidh_private_key_clear(private_key_t private_key); 49 | 50 | /** 51 | * Generates the private-key. It is guaranteed that {@code private_key->m} 52 | * is comprime to {@code params->l}. 53 | * @param private_key 54 | * @param params 55 | */ 56 | void sidh_private_key_generate(private_key_t private_key, 57 | const public_params_t params); 58 | 59 | /** 60 | * Computes a generator for th kernel generated by {@code gen = m * P + n * Q}. 61 | * It is assumed that {@code m} is invertible modulo {@code le}. 62 | * @param gen 63 | * @param P one of the generators of the l^e torsion. 64 | * @param Q one of the generators of the l^e torsion. 65 | * @param private_key 66 | * @param le 67 | * @param E 68 | */ 69 | void sidh_private_key_compute_kernel_gen(point_t gen, 70 | const private_key_t private_key, 71 | const point_t P, 72 | const point_t Q, 73 | const mpz_t le, 74 | const elliptic_curve_t E); 75 | 76 | /** 77 | * Converts a private-key to an array of bytes. 78 | * @param bytes 79 | * @param private_key 80 | * @param prime_size 81 | */ 82 | void sidh_private_key_to_bytes(uint8_t *bytes, 83 | const private_key_t private_key, 84 | long prime_size); 85 | 86 | /** 87 | * Converts an array of bytes to a private-key. 88 | * @param private_key 89 | * @param bytes 90 | * @param prime_size 91 | */ 92 | void sidh_bytes_to_private_key(private_key_t private_key, 93 | const uint8_t *bytes, 94 | long prime_size); 95 | 96 | /** 97 | * Prints {@code private_key} to the standard output. 98 | * @param private_key 99 | */ 100 | void sidh_private_key_print(const private_key_t private_key); 101 | 102 | #ifdef __cplusplus 103 | } 104 | #endif 105 | 106 | #endif /* PRIVATE_KEY_H */ 107 | 108 | -------------------------------------------------------------------------------- /sidh/sidh_public_key.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "sidh_public_key.h" 19 | #include "sidh_isogeny.h" 20 | #include "sidh_private_key.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | void sidh_public_key_init(public_key_t public_key) { 27 | sidh_elliptic_curve_init(public_key->E); 28 | sidh_point_init(public_key->P); 29 | sidh_point_init(public_key->Q); 30 | } 31 | 32 | void sidh_public_key_clear(public_key_t public_key) { 33 | sidh_elliptic_curve_clear(public_key->E); 34 | sidh_point_clear(public_key->P); 35 | sidh_point_clear(public_key->Q); 36 | } 37 | 38 | void sidh_public_key_generate(public_key_t public_key, 39 | const point_t kernel_gen, 40 | const public_params_t paramsA, 41 | const public_params_t paramsB) { 42 | 43 | point_t points[2]; 44 | sidh_point_init(points[0]); 45 | sidh_point_init(points[1]); 46 | 47 | sidh_elliptic_curve_set(public_key->E, paramsA->E); 48 | sidh_point_set(points[0], paramsB->P); 49 | sidh_point_set(points[1], paramsB->Q); 50 | 51 | sidh_isogeny_evaluate_strategy(public_key->E, 52 | points, 53 | 2, 54 | kernel_gen, 55 | paramsA->l, 56 | paramsA->e, 57 | 0.5); 58 | 59 | // sidh_isogeny_evaluate_naive(public_key->E, 60 | // points, 61 | // 2, 62 | // kernel_gen, 63 | // paramsA->l, 64 | // paramsA->e, 65 | // 10); 66 | 67 | sidh_point_set(public_key->P, points[0]); 68 | sidh_point_set(public_key->Q, points[1]); 69 | 70 | sidh_point_clear(points[0]); 71 | sidh_point_clear(points[1]); 72 | } 73 | 74 | void sidh_public_key_to_bytes(uint8_t *bytes, 75 | const public_key_t public_key, 76 | long prime_size) { 77 | long index = 0; 78 | sidh_fp2_to_bytes(bytes + index, public_key->E->a, prime_size); 79 | index += 2 * prime_size; 80 | sidh_fp2_to_bytes(bytes + index, public_key->E->b, prime_size); 81 | index += 2 * prime_size; 82 | sidh_fp2_to_bytes(bytes + index, public_key->P->x, prime_size); 83 | index += 2 * prime_size; 84 | sidh_fp2_to_bytes(bytes + index, public_key->P->y, prime_size); 85 | index += 2 * prime_size; 86 | sidh_fp2_to_bytes(bytes + index, public_key->Q->x, prime_size); 87 | index += 2 * prime_size; 88 | sidh_fp2_to_bytes(bytes + index, public_key->Q->y, prime_size); 89 | } 90 | 91 | void sidh_bytes_to_public_key(public_key_t public_key, 92 | const uint8_t *bytes, 93 | long prime_size) { 94 | long index = 0; 95 | sidh_bytes_to_fp2(public_key->E->a, bytes + index, prime_size); 96 | index += 2 * prime_size; 97 | sidh_bytes_to_fp2(public_key->E->b, bytes + index, prime_size); 98 | index += 2 * prime_size; 99 | sidh_bytes_to_fp2(public_key->P->x, bytes + index, prime_size); 100 | index += 2 * prime_size; 101 | sidh_bytes_to_fp2(public_key->P->y, bytes + index, prime_size); 102 | index += 2 * prime_size; 103 | sidh_bytes_to_fp2(public_key->Q->x, bytes + index, prime_size); 104 | index += 2 * prime_size; 105 | sidh_bytes_to_fp2(public_key->Q->y, bytes + index, prime_size); 106 | 107 | public_key->P->z = 1; 108 | public_key->Q->z = 1; 109 | } 110 | 111 | void sidh_public_key_print(const public_key_t public_key) { 112 | printf("E: %s\n", sidh_elliptic_curve_get_str(public_key->E)); 113 | printf("P: %s\n", sidh_point_get_str(public_key->P)); 114 | printf("Q: %s\n", sidh_point_get_str(public_key->Q)); 115 | } -------------------------------------------------------------------------------- /sidh/sidh_public_key.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef PUBLIC_KEY_H 19 | #define PUBLIC_KEY_H 20 | 21 | #include "sidh_public_param.h" 22 | #include "sidh_private_key.h" 23 | #include "sidh_isogeny.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /** 30 | * Representation of the public key in sidh 31 | */ 32 | typedef struct { 33 | elliptic_curve_t E; 34 | point_t P; 35 | point_t Q; 36 | } public_key_struct; 37 | 38 | typedef public_key_struct public_key_t[1]; 39 | 40 | /** 41 | * Initializes the public-key. 42 | * @param public_key 43 | */ 44 | void sidh_public_key_init(public_key_t public_key); 45 | 46 | /** 47 | * Frees the memory allocated to the public-key. 48 | * @param public_key 49 | */ 50 | void sidh_public_key_clear(public_key_t public_key); 51 | 52 | /** 53 | * Generates the public-key 54 | * @param public_key 55 | * @param kernel_gen a generator for the kernel of the isogeny 56 | * @param paramsA own params 57 | * @param paramsB other's params 58 | */ 59 | void sidh_public_key_generate(public_key_t public_key, 60 | const point_t kernel_gen, 61 | const public_params_t paramsA, 62 | const public_params_t paramsB); 63 | 64 | 65 | /** 66 | * Converts a public-key to a byte array. 67 | * @param bytes 68 | * @param public_key 69 | * @param prime_size 70 | */ 71 | void sidh_public_key_to_bytes(uint8_t *bytes, 72 | const public_key_t public_key, 73 | long prime_size); 74 | 75 | 76 | /** 77 | * Converts a byte array to a public-key. 78 | * @param public_key 79 | * @param bytes 80 | * @param prime_size 81 | */ 82 | void sidh_bytes_to_public_key(public_key_t public_key, 83 | const uint8_t *bytes, 84 | long prime_size); 85 | 86 | 87 | /** 88 | * Prints {@code public_key} to the standard output. 89 | * @param public_key 90 | */ 91 | void sidh_public_key_print(const public_key_t public_key); 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif /* PUBLIC_KEY_H */ 98 | -------------------------------------------------------------------------------- /sidh/sidh_public_key_encryption.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "sidh_public_key_encryption.h" 19 | #include "sidh_public_key.h" 20 | #include "sidh_util.h" 21 | #include "sidh_shared_key.h" 22 | #include 23 | #include 24 | #include 25 | 26 | void sidh_public_key_ciphertext_init(ciphertext_t ciphertext) { 27 | sidh_elliptic_curve_init(ciphertext->E); 28 | sidh_point_init(ciphertext->P); 29 | sidh_point_init(ciphertext->Q); 30 | ciphertext->size = 0; 31 | } 32 | 33 | void sidh_public_key_ciphertext_clear(ciphertext_t ciphertext) { 34 | sidh_elliptic_curve_clear(ciphertext->E); 35 | sidh_point_clear(ciphertext->P); 36 | sidh_point_clear(ciphertext->Q); 37 | free(ciphertext->content); 38 | ciphertext->size = 0; 39 | } 40 | 41 | void sidh_public_key_plaintext_init(plaintext_t plaintext) { 42 | plaintext->size = 0; 43 | } 44 | 45 | void sidh_public_key_plaintext_clear(plaintext_t plaintext) { 46 | plaintext->size = 0; 47 | } 48 | 49 | int sidh_public_key_pad_plaintext(plaintext_t result, 50 | const plaintext_t raw) { 51 | long key_size = public_key_get_key_size(); 52 | long max_msg_size = key_size - 1; 53 | 54 | if (raw->size > key_size) { 55 | printf("\nMessage too large. It should be less than %ld bytes.\n", 56 | max_msg_size); 57 | return -1; 58 | } 59 | 60 | // pad the message 61 | char *new_content = (char *) malloc(max_msg_size); 62 | memset(new_content, 0, max_msg_size); 63 | memcpy(new_content, raw->content, raw->size); 64 | 65 | result->content = new_content; 66 | result->size = max_msg_size; 67 | 68 | return 1; 69 | } 70 | 71 | void sidh_public_key_encrypt(ciphertext_t ciphertext, 72 | const plaintext_t plaintext, 73 | const public_key_t public_keyA, 74 | const public_params_t paramsA, 75 | const public_params_t paramsB) { 76 | 77 | private_key_t private_key_temp; 78 | sidh_private_key_init(private_key_temp); 79 | sidh_private_key_generate(private_key_temp, paramsB); 80 | 81 | point_t kernel_gen; 82 | sidh_point_init(kernel_gen); 83 | sidh_private_key_compute_kernel_gen(kernel_gen, 84 | private_key_temp, 85 | paramsB->P, 86 | paramsB->Q, 87 | paramsB->le, 88 | paramsB->E); 89 | 90 | public_key_t public_key_temp; 91 | sidh_public_key_init(public_key_temp); 92 | sidh_public_key_generate(public_key_temp, kernel_gen, paramsB, paramsA); 93 | 94 | fp2_element_t shared_key; 95 | sidh_fp2_init(shared_key); 96 | sidh_shared_key_generate(shared_key, public_keyA, private_key_temp, paramsB); 97 | char *hash = sidh_public_key_encryption_hash(shared_key, plaintext->size); 98 | 99 | ciphertext->content = sidh_array_xor(plaintext->content, 100 | hash, plaintext->size); 101 | ciphertext->size = plaintext->size; 102 | sidh_elliptic_curve_set(ciphertext->E, public_key_temp->E); 103 | sidh_point_set(ciphertext->P, public_key_temp->P); 104 | sidh_point_set(ciphertext->Q, public_key_temp->Q); 105 | 106 | sidh_private_key_clear(private_key_temp); 107 | sidh_point_clear(kernel_gen); 108 | sidh_public_key_clear(public_key_temp); 109 | sidh_fp2_clear(shared_key); 110 | free(hash); 111 | } 112 | 113 | void sidh_public_key_decrypt(plaintext_t plaintext, 114 | const ciphertext_t ciphertext, 115 | const private_key_t private_keyA, 116 | const public_params_t paramsA) { 117 | 118 | public_key_t public_key_temp; 119 | sidh_public_key_init(public_key_temp); 120 | sidh_elliptic_curve_set(public_key_temp->E, ciphertext->E); 121 | sidh_point_set(public_key_temp->P, ciphertext->P); 122 | sidh_point_set(public_key_temp->Q, ciphertext->Q); 123 | 124 | fp2_element_t shared_key; 125 | sidh_fp2_init(shared_key); 126 | sidh_shared_key_generate(shared_key, public_key_temp, private_keyA, paramsA); 127 | char *hash = sidh_public_key_encryption_hash(shared_key, ciphertext->size); 128 | 129 | plaintext->content = sidh_array_xor(ciphertext->content, hash, 130 | ciphertext->size); 131 | plaintext->size = ciphertext->size; 132 | 133 | sidh_public_key_clear(public_key_temp); 134 | sidh_fp2_clear(shared_key); 135 | free(hash); 136 | } 137 | 138 | char *sidh_public_key_encryption_hash(const fp2_element_t value, 139 | long size) { 140 | // compute the size of value in chars 141 | long size_a = labs(mpz_size(value->a)) * sizeof (mp_limb_t); 142 | long size_b = labs(mpz_size(value->b)) * sizeof (mp_limb_t); 143 | 144 | char *hash = (char *) malloc(size); 145 | 146 | memcpy(hash, (char *) mpz_limbs_read(value->a), size_a); 147 | memcpy(hash + size_a, (char *) mpz_limbs_read(value->b), size_b); 148 | 149 | return hash; 150 | } 151 | 152 | long public_key_get_key_size() { 153 | // the key size is twice as large as the base prime. 154 | long key_size = 2 * labs(mpz_size(characteristic)) * sizeof (mp_limb_t); 155 | return key_size; 156 | } -------------------------------------------------------------------------------- /sidh/sidh_public_key_encryption.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #ifndef PUBLIC_KEY_ENCRYPTION_H 20 | #define PUBLIC_KEY_ENCRYPTION_H 21 | 22 | #include "sidh_elliptic_curve.h" 23 | #include "sidh_public_key.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /** 30 | * Representation of ciphertext in sidh 31 | */ 32 | typedef struct { 33 | elliptic_curve_t E; 34 | point_t P; 35 | point_t Q; 36 | char *content; 37 | 38 | // size of the content field 39 | long size; 40 | } ciphertext_struct; 41 | 42 | /** 43 | * Representation of plaintext in sidh 44 | */ 45 | typedef struct { 46 | char *content; 47 | 48 | // size of the content field 49 | long size; 50 | } plaintext_struct; 51 | 52 | typedef ciphertext_struct ciphertext_t[1]; 53 | typedef plaintext_struct plaintext_t[1]; 54 | 55 | /** 56 | * Initializes the ciphertext. 57 | * @param ciphertext 58 | */ 59 | void sidh_public_key_ciphertext_init(ciphertext_t ciphertext); 60 | 61 | /** 62 | * Frees the memory allocated to {@code ciphertext}. 63 | * @param ciphertext 64 | */ 65 | void sidh_public_key_ciphertext_clear(ciphertext_t ciphertext); 66 | 67 | /** 68 | * Initializes the plaintext. 69 | * @param plaintext 70 | */ 71 | void sidh_public_key_plaintext_init(plaintext_t plaintext); 72 | 73 | /** 74 | * Frees the memory allocated to {@code plaintext}. 75 | * @param plaintext 76 | */ 77 | void sidh_public_key_plaintext_clear(plaintext_t plaintext); 78 | 79 | /** 80 | * Pads a given plain text for encryption. 81 | * @param result the prepared plaintext 82 | * @param raw the given plaintext 83 | * @return 1 if successful, and -1 otherwise 84 | */ 85 | int sidh_public_key_pad_plaintext(plaintext_t result, 86 | const plaintext_t raw); 87 | 88 | /** 89 | * Encrypts the {@code plaintext} using {@code public_key}. 90 | * @param ciphertext the generated cipher 91 | * @param plaintext 92 | * @param public_keyA other's public-key 93 | * @param paramsA other's public params 94 | * @param paramsB own pubic params 95 | */ 96 | void sidh_public_key_encrypt(ciphertext_t ciphertext, 97 | const plaintext_t plaintext, 98 | const public_key_t public_keyA, 99 | const public_params_t paramsA, 100 | const public_params_t paramsB); 101 | 102 | /** 103 | * Decrypts the {@code ciphertext} using {@code private_key}. 104 | * @param plaintext the result 105 | * @param ciphertext the given ciphertext 106 | * @param private_keyA 107 | * @param paramsA the public parameters associated to the owner of 108 | * the private-key 109 | */ 110 | void sidh_public_key_decrypt(plaintext_t plaintext, 111 | const ciphertext_t ciphertext, 112 | const private_key_t private_keyA, 113 | const public_params_t paramsA); 114 | 115 | /** 116 | * Computes the hash of {@code value} 117 | * @param value 118 | * @param size size of the output hash 119 | * @return the hash 120 | */ 121 | char *sidh_public_key_encryption_hash(const fp2_element_t value, 122 | long size); 123 | 124 | /** 125 | * @return the key-size in bytes 126 | */ 127 | long public_key_get_key_size(); 128 | 129 | #ifdef __cplusplus 130 | } 131 | #endif 132 | 133 | #endif /* PUBLIC_KEY_ENCRYPTION_H */ 134 | 135 | -------------------------------------------------------------------------------- /sidh/sidh_public_key_validation.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #include "sidh_public_key_validation.h" 20 | #include "sidh_elliptic_curve_dlp.h" 21 | #include 22 | 23 | int sidh_public_key_is_valid(const public_key_t public_key, 24 | const public_params_t params) { 25 | if (!sidh_public_key_check_order(public_key->P, public_key->E, params)) 26 | return 0; 27 | 28 | if (!sidh_public_key_check_order(public_key->Q, public_key->E, params)) 29 | return 0; 30 | 31 | if (!sidh_public_key_check_dependency(public_key, params)) 32 | return 0; 33 | 34 | if (!sidh_public_key_check_curve(public_key->E)) 35 | return 0; 36 | 37 | return 1; 38 | } 39 | 40 | int sidh_public_key_check_order(const point_t P, 41 | const elliptic_curve_t E, 42 | const public_params_t params) { 43 | mpz_t order; 44 | point_t temp; 45 | 46 | mpz_init_set(order, params->le); 47 | sidh_point_init(temp); 48 | 49 | int result = 0; 50 | mpz_divexact_ui(order, order, params->l); 51 | sidh_point_mul_scaler(temp, P, order, E); 52 | if (!sidh_point_is_zero(temp)) { 53 | sidh_point_mul_scaler_si(temp, temp, params->l, E); 54 | if (sidh_point_is_zero(temp)) 55 | result = 1; 56 | } 57 | 58 | mpz_clear(order); 59 | sidh_point_clear(temp); 60 | return result; 61 | } 62 | 63 | int sidh_public_key_check_dependency(const public_key_t public_key, 64 | const public_params_t params) { 65 | mpz_t x; 66 | mpz_init(x); 67 | 68 | int result = 0; 69 | sidh_elliptic_curve_prime_power_dlp(x, 70 | public_key->P, 71 | public_key->Q, 72 | public_key->E, 73 | params->l, 74 | params->e); 75 | 76 | if (mpz_cmp_si(x, -1) == 0) { 77 | sidh_elliptic_curve_prime_power_dlp(x, 78 | public_key->Q, 79 | public_key->P, 80 | public_key->E, 81 | params->l, 82 | params->e); 83 | if (mpz_cmp_si(x, -1) == 0) 84 | result = 1; 85 | } 86 | 87 | mpz_clear(x); 88 | return result; 89 | } 90 | 91 | int sidh_public_key_check_curve(const elliptic_curve_t E) { 92 | point_t temp; 93 | mpz_t exponent; 94 | 95 | sidh_point_init(temp); 96 | mpz_init_set(exponent, characteristic); 97 | mpz_add_ui(exponent, exponent, 1); 98 | 99 | sidh_elliptic_curve_random_point(temp, E); 100 | sidh_point_mul_scaler(temp, temp, exponent, E); 101 | int result = sidh_point_is_zero(temp); 102 | 103 | sidh_point_clear(temp); 104 | mpz_clear(exponent); 105 | 106 | return result; 107 | } -------------------------------------------------------------------------------- /sidh/sidh_public_key_validation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #ifndef PUBLIC_KEY_VALIDATION_H 20 | #define PUBLIC_KEY_VALIDATION_H 21 | 22 | #include "sidh_elliptic_curve.h" 23 | #include "sidh_public_key.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /** 30 | * Check if a given public-key is valid. 31 | * @param public_key 32 | * @param params the other party's public parameters from which 33 | * the public-key is generated. 34 | * @return 1 if the public-key is valid, 0 otherwise 35 | */ 36 | int sidh_public_key_is_valid(const public_key_t public_key, 37 | const public_params_t params); 38 | 39 | /** 40 | * Checks if {@code P} has the exact order l^e where l, e are given in 41 | * {@code params}. 42 | * @param P 43 | * @param E 44 | * @param params 45 | * @return 1 if {@code P} has order l^e, 0 otherwise 46 | */ 47 | int sidh_public_key_check_order(const point_t P, 48 | const elliptic_curve_t E, 49 | const public_params_t params); 50 | 51 | /** 52 | * Checks if the two point in {@code public-key} are linearly independent. 53 | * @param public_key 54 | * @param params 55 | * @return 1 if the points are linearly independent, 0 otherwise 56 | */ 57 | int sidh_public_key_check_dependency(const public_key_t public_key, 58 | const public_params_t params); 59 | 60 | /** 61 | * Checks if a given is valid supersingular curve. A curve is considered 62 | * valid if it has order (p + 1)^2 where p is the characteristic. The test 63 | * is done probabilistically. 64 | * @param E 65 | * @return 1 if the curve is valid, 0 otherwise. 66 | */ 67 | int sidh_public_key_check_curve(const elliptic_curve_t E); 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* PUBLIC_KEY_VALIDATION_H */ 74 | 75 | -------------------------------------------------------------------------------- /sidh/sidh_public_param.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #include 20 | #include "sidh_public_param.h" 21 | 22 | void sidh_public_params_init(public_params_t params) { 23 | mpz_init(params->characteristic); 24 | sidh_elliptic_curve_init(params->E); 25 | sidh_point_init(params->P); 26 | sidh_point_init(params->Q); 27 | mpz_init(params->le); 28 | } 29 | 30 | int sidh_public_params_read(public_params_t paramsA, 31 | public_params_t paramsB, 32 | const char *file_name) { 33 | FILE *input; 34 | input = fopen(file_name, "r"); 35 | if (!input) { 36 | printf("No such file!\n"); 37 | return 0; 38 | } 39 | 40 | fp2_element_t a; 41 | fp2_element_t b; 42 | sidh_fp2_init(a); 43 | sidh_fp2_init(b); 44 | 45 | gmp_fscanf(input, "p : %Zd \n", paramsA->characteristic); 46 | mpz_set(paramsB->characteristic, paramsA->characteristic); 47 | gmp_fscanf(input, 48 | "E : y^2 = x^3 + (%Zd * i + %Zd) * x + (%Zd * i + %Zd) \n", 49 | a->a, a->b, b->a, b->b); 50 | sidh_elliptic_curve_set_coeffs(paramsA->E, a, b); 51 | sidh_elliptic_curve_set(paramsB->E, paramsA->E); 52 | gmp_fscanf(input, "lA: %ld \n", ¶msA->l); 53 | gmp_fscanf(input, "eA: %ld \n", ¶msA->e); 54 | mpz_ui_pow_ui(paramsA->le, paramsA->l, paramsA->e); 55 | gmp_fscanf(input, 56 | "PA: (%Zd * i + %Zd, %Zd * i + %Zd) \n", 57 | a->a, a->b, b->a, b->b); 58 | sidh_point_set_coordinates(paramsA->P, a, b, 1); 59 | gmp_fscanf(input, 60 | "QA: (%Zd * i + %Zd, %Zd * i + %Zd) \n", 61 | a->a, a->b, b->a, b->b); 62 | sidh_point_set_coordinates(paramsA->Q, a, b, 1); 63 | gmp_fscanf(input, "lB: %ld \n", ¶msB->l); 64 | gmp_fscanf(input, "eB: %ld \n", ¶msB->e); 65 | mpz_ui_pow_ui(paramsB->le, paramsB->l, paramsB->e); 66 | gmp_fscanf(input, 67 | "PB: (%Zd * i + %Zd, %Zd * i + %Zd) \n", 68 | a->a, a->b, b->a, b->b); 69 | sidh_point_set_coordinates(paramsB->P, a, b, 1); 70 | gmp_fscanf(input, 71 | "QB: (%Zd * i + %Zd, %Zd * i + %Zd) \n", 72 | a->a, a->b, b->a, b->b); 73 | sidh_point_set_coordinates(paramsB->Q, a, b, 1); 74 | 75 | fclose(input); 76 | sidh_fp2_clear(a); 77 | sidh_fp2_clear(b); 78 | 79 | return 1; 80 | } 81 | 82 | void sidh_public_params_print(const public_params_t params, 83 | int print_torsion) { 84 | if (print_torsion != 1) { 85 | printf("p : %s\n", mpz_get_str(NULL, 10, params->characteristic)); 86 | printf("E : %s\n", sidh_elliptic_curve_get_str(params->E)); 87 | } 88 | 89 | printf("lA: %ld\n", params->l); 90 | printf("eA: %ld\n", params->e); 91 | printf("PA: %s\n", sidh_point_get_str(params->P)); 92 | printf("QA: %s\n", sidh_point_get_str(params->Q)); 93 | } 94 | 95 | void sidh_public_params_clear(public_params_t params) { 96 | mpz_clear(params->characteristic); 97 | sidh_elliptic_curve_clear(params->E); 98 | sidh_point_clear(params->P); 99 | sidh_point_clear(params->Q); 100 | mpz_clear(params->le); 101 | } -------------------------------------------------------------------------------- /sidh/sidh_public_param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #ifndef PUBLIC_PARAM_H 20 | #define PUBLIC_PARAM_H 21 | 22 | #include "sidh_elliptic_curve.h" 23 | #include "sidh_quadratic_ext.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /** 30 | * Representation of the public parameters in sidh 31 | */ 32 | typedef struct { 33 | // the characteristic 34 | mpz_t characteristic; 35 | 36 | elliptic_curve_t E; 37 | unsigned long l; 38 | unsigned long e; 39 | 40 | // a generator for the l^e torsion subgroup of E 41 | point_t P; 42 | point_t Q; 43 | 44 | // l^e, precomputed 45 | mpz_t le; 46 | 47 | } public_params_struct; 48 | 49 | typedef public_params_struct public_params_t[1]; 50 | 51 | /** 52 | * Initializes the public parameters. 53 | * @param params 54 | */ 55 | void sidh_public_params_init(public_params_t params); 56 | 57 | /** 58 | * Reads the public parameters from file named {@code file_name}. 59 | * @param paramsA 60 | * @param paramsB 61 | * @param file_name 62 | * @return 1 if the parameters are read successfully, and 0 otherwise. 63 | */ 64 | int sidh_public_params_read(public_params_t paramsA, 65 | public_params_t paramsB, 66 | const char *file_name); 67 | 68 | /** 69 | * Prints the public parameters to the standard output. 70 | * @param params 71 | * @param torsion if it is 1 only the torsion parameters are printed 72 | */ 73 | void sidh_public_params_print(const public_params_t params, 74 | int print_torsion); 75 | 76 | /** 77 | * Frees the memory allocated to {@code params}. 78 | * @param params 79 | */ 80 | void sidh_public_params_clear(public_params_t params); 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif /* PUBLIC_PARAM_H */ 87 | 88 | -------------------------------------------------------------------------------- /sidh/sidh_quadratic_ext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "sidh_quadratic_ext.h" 19 | #include "sidh_util.h" 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | void sidh_fp_init_chararacteristic_ui(long p) { 26 | mpz_init_set_ui(characteristic, p); 27 | } 28 | 29 | void sidh_fp_init_chararacteristic_str(const char *value) { 30 | mpz_init_set_str(characteristic, value, 10); 31 | } 32 | 33 | void sidh_fp_init_chararacteristic(const mpz_t p) { 34 | mpz_init_set(characteristic, p); 35 | } 36 | 37 | void sidh_fp_set(mpz_t x, 38 | const mpz_t a) { 39 | mpz_mod(x, a, characteristic); 40 | } 41 | 42 | void sidh_fp_add(mpz_t x, 43 | const mpz_t a, 44 | const mpz_t b) { 45 | mpz_add(x, a, b); 46 | mpz_mod(x, x, characteristic); 47 | } 48 | 49 | void sidh_fp_add_ui(mpz_t x, 50 | const mpz_t a, 51 | unsigned long b) { 52 | mpz_add_ui(x, a, b); 53 | mpz_mod(x, x, characteristic); 54 | } 55 | 56 | void sidh_fp_sub(mpz_t x, 57 | const mpz_t a, 58 | const mpz_t b) { 59 | mpz_sub(x, a, b); 60 | mpz_mod(x, x, characteristic); 61 | } 62 | 63 | void sidh_fp_sub_ui(mpz_t x, 64 | const mpz_t a, 65 | unsigned long b) { 66 | mpz_sub_ui(x, a, b); 67 | mpz_mod(x, x, characteristic); 68 | } 69 | 70 | void sidh_fp_mul(mpz_t x, 71 | const mpz_t a, 72 | const mpz_t b) { 73 | mpz_mul(x, a, b); 74 | mpz_mod(x, x, characteristic); 75 | } 76 | 77 | void sidh_fp_mul_si(mpz_t x, 78 | const mpz_t a, 79 | long b) { 80 | mpz_mul_si(x, a, b); 81 | mpz_mod(x, x, characteristic); 82 | } 83 | 84 | void sidh_fp_inv(mpz_t x, 85 | const mpz_t a) { 86 | mpz_invert(x, a, characteristic); 87 | } 88 | 89 | void sidh_fp_div(mpz_t x, 90 | const mpz_t a, 91 | const mpz_t b) { 92 | sidh_fp_inv(x, b); 93 | sidh_fp_mul(x, a, x); 94 | } 95 | 96 | void sidh_fp_neg(mpz_t x, 97 | const mpz_t a) { 98 | sidh_fp_sub(x, characteristic, a); 99 | } 100 | 101 | void sidh_fp_sqrt(mpz_t x, 102 | const mpz_t a) { 103 | mpz_t exponent; 104 | mpz_init(exponent); 105 | 106 | // compute (p + 1) / 4 107 | mpz_add_ui(exponent, characteristic, 1); 108 | mpz_divexact_ui(exponent, exponent, 4); 109 | 110 | mpz_powm(x, a, exponent, characteristic); 111 | mpz_clear(exponent); 112 | } 113 | 114 | //////////////// fp2 methods ////////////////////////// 115 | 116 | void sidh_fp2_init(fp2_element_t x) { 117 | mpz_inits(x->a, x->b, NULL); 118 | } 119 | 120 | void sidh_fp2_init_set_si(fp2_element_t x, 121 | long a, 122 | long b) { 123 | mpz_init_set_si(x->a, a); 124 | mpz_init_set_si(x->b, b); 125 | } 126 | 127 | void sidh_fp2_init_set_str(fp2_element_t x, 128 | const char *a, 129 | const char *b) { 130 | mpz_init_set_str(x->a, a, 10); 131 | mpz_init_set_str(x->b, b, 10); 132 | } 133 | 134 | void sidh_fp2_init_set(fp2_element_t x, 135 | const fp2_element_t a) { 136 | mpz_init_set(x->a, a->a); 137 | mpz_init_set(x->b, a->b); 138 | } 139 | 140 | void sidh_fp2_clear(fp2_element_t x) { 141 | mpz_clears(x->a, x->b, NULL); 142 | } 143 | 144 | void sidh_fp2_set(fp2_element_t x, 145 | const fp2_element_t b) { 146 | mpz_set(x->a, b->a); 147 | mpz_set(x->b, b->b); 148 | } 149 | 150 | void sidh_fp2_zero(fp2_element_t x) { 151 | mpz_set_si(x->a, 0); 152 | mpz_set_si(x->b, 0); 153 | } 154 | 155 | void sidh_fp2_one(fp2_element_t x) { 156 | mpz_set_si(x->a, 0); 157 | mpz_set_si(x->b, 1); 158 | } 159 | 160 | char *sidh_fp2_get_str(const fp2_element_t a) { 161 | 162 | if (mpz_cmp_si(a->a, 0) == 0 && mpz_cmp_si(a->b, 0) == 0) { 163 | return "0"; 164 | } 165 | 166 | if (mpz_cmp_si(a->a, 0) == 0) { 167 | return mpz_get_str(NULL, 10, a->b); 168 | } 169 | 170 | char *result = ""; 171 | 172 | if (mpz_cmp_si(a->b, 0) == 0) { 173 | result = sidh_concat(result, mpz_get_str(NULL, 10, a->a)); 174 | result = sidh_concat(result, " * i"); 175 | return result; 176 | } 177 | 178 | result = sidh_concat(result, mpz_get_str(NULL, 10, a->a)); 179 | result = sidh_concat(result, " * i + "); 180 | result = sidh_concat(result, mpz_get_str(NULL, 10, a->b)); 181 | 182 | return result; 183 | } 184 | 185 | void sidh_fp2_add(fp2_element_t x, 186 | const fp2_element_t a, 187 | const fp2_element_t b) { 188 | sidh_fp_add(x->a, a->a, b->a); 189 | sidh_fp_add(x->b, a->b, b->b); 190 | } 191 | 192 | void sidh_fp2_add_ui(fp2_element_t x, 193 | const fp2_element_t a, 194 | unsigned long b) { 195 | sidh_fp_add_ui(x->b, a->b, b); 196 | sidh_fp_set(x->a, a->a); 197 | } 198 | 199 | void sidh_fp2_sub(fp2_element_t x, 200 | const fp2_element_t a, 201 | const fp2_element_t b) { 202 | sidh_fp_sub(x->a, a->a, b->a); 203 | sidh_fp_sub(x->b, a->b, b->b); 204 | } 205 | 206 | void sidh_fp2_sub_ui(fp2_element_t x, 207 | const fp2_element_t a, 208 | unsigned long b) { 209 | sidh_fp_sub_ui(x->b, a->b, b); 210 | sidh_fp_set(x->a, a->a); 211 | } 212 | 213 | void sidh_fp2_mul(fp2_element_t x, 214 | const fp2_element_t a, 215 | const fp2_element_t b) { 216 | mpz_t temp1; 217 | mpz_t temp2; 218 | 219 | mpz_init(temp1); 220 | mpz_init(temp2); 221 | 222 | fp2_element_t result; 223 | sidh_fp2_init(result); 224 | 225 | // (a + b) * (c + d) 226 | sidh_fp_add(temp1, a->a, a->b); 227 | sidh_fp_add(temp2, b->a, b->b); 228 | sidh_fp_mul(result->a, temp1, temp2); 229 | 230 | // a * c 231 | sidh_fp_mul(temp1, a->a, b->a); 232 | // b * d 233 | sidh_fp_mul(temp2, a->b, b->b); 234 | 235 | sidh_fp_sub(result->a, result->a, temp1); 236 | sidh_fp_sub(result->a, result->a, temp2); 237 | sidh_fp_sub(result->b, temp2, temp1); 238 | sidh_fp2_set(x, result); 239 | 240 | mpz_clear(temp1); 241 | mpz_clear(temp2); 242 | sidh_fp2_clear(result); 243 | } 244 | 245 | void sidh_fp2_square(fp2_element_t x, 246 | const fp2_element_t a) { 247 | mpz_t temp1; 248 | mpz_t temp2; 249 | 250 | mpz_init(temp1); 251 | mpz_init(temp2); 252 | 253 | fp2_element_t result; 254 | sidh_fp2_init(result); 255 | 256 | // (b + a) * (b - a) 257 | sidh_fp_add(temp1, a->a, a->b); 258 | sidh_fp_sub(temp2, a->b, a->a); 259 | sidh_fp_mul(result->b, temp1, temp2); 260 | 261 | // 2 * a * b 262 | sidh_fp_mul(result->a, a->a, a->b); 263 | sidh_fp_mul_si(result->a, result->a, 2); 264 | 265 | sidh_fp2_set(x, result); 266 | 267 | mpz_clear(temp1); 268 | mpz_clear(temp2); 269 | sidh_fp2_clear(result); 270 | } 271 | 272 | void sidh_fp2_pow_ui(fp2_element_t x, 273 | const fp2_element_t a, 274 | unsigned long n) { 275 | mpz_t temp_n; 276 | mpz_init_set_ui(temp_n, n); 277 | sidh_fp2_pow(x, a, temp_n); 278 | mpz_clear(temp_n); 279 | } 280 | 281 | void sidh_fp2_pow(fp2_element_t x, 282 | const fp2_element_t a, 283 | const mpz_t n) { 284 | if (mpz_cmp_ui(n, 0) == 0) { 285 | sidh_fp2_one(x); 286 | return; 287 | } 288 | 289 | fp2_element_t temp1; 290 | fp2_element_t temp2; 291 | sidh_fp2_init_set_si(temp1, 0, 1); 292 | sidh_fp2_init_set(temp2, a); 293 | 294 | long num_bits = mpz_sizeinbase(n, 2); 295 | for (long i = 0; i < num_bits; i++) { 296 | if (mpz_tstbit(n, i) == 1) 297 | sidh_fp2_mul(temp1, temp1, temp2); 298 | sidh_fp2_square(temp2, temp2); 299 | } 300 | 301 | sidh_fp2_set(x, temp1); 302 | 303 | sidh_fp2_clear(temp1); 304 | sidh_fp2_clear(temp2); 305 | } 306 | 307 | void sidh_fp2_conjugate(fp2_element_t x, 308 | const fp2_element_t a) { 309 | sidh_fp2_set(x, a); 310 | sidh_fp_neg(x->a, x->a); 311 | } 312 | 313 | void sidh_fp2_negate(fp2_element_t x, 314 | const fp2_element_t a) { 315 | sidh_fp2_set(x, a); 316 | sidh_fp_neg(x->a, x->a); 317 | sidh_fp_neg(x->b, x->b); 318 | } 319 | 320 | void sidh_fp2_mul_scaler(fp2_element_t x, 321 | const fp2_element_t a, 322 | const mpz_t scaler) { 323 | sidh_fp_mul(x->a, a->a, scaler); 324 | sidh_fp_mul(x->b, a->b, scaler); 325 | } 326 | 327 | void sidh_fp2_mul_scaler_si(fp2_element_t x, 328 | const fp2_element_t a, 329 | long scaler) { 330 | sidh_fp_mul_si(x->a, a->a, scaler); 331 | sidh_fp_mul_si(x->b, a->b, scaler); 332 | } 333 | 334 | void sidh_fp2_inv(fp2_element_t x, 335 | const fp2_element_t a) { 336 | mpz_t temp; 337 | fp2_element_t result; 338 | 339 | mpz_init(temp); 340 | sidh_fp2_init(result); 341 | 342 | sidh_fp2_conjugate(result, a); 343 | sidh_fp2_norm(temp, a); 344 | sidh_fp_inv(temp, temp); 345 | sidh_fp2_mul_scaler(result, result, temp); 346 | sidh_fp2_set(x, result); 347 | 348 | mpz_clear(temp); 349 | sidh_fp2_clear(result); 350 | } 351 | 352 | void sidh_fp2_div(fp2_element_t x, 353 | const fp2_element_t a, 354 | const fp2_element_t b) { 355 | fp2_element_t result; 356 | sidh_fp2_init(result); 357 | 358 | sidh_fp2_inv(result, b); 359 | sidh_fp2_mul(result, a, result); 360 | sidh_fp2_set(x, result); 361 | 362 | sidh_fp2_clear(result); 363 | } 364 | 365 | int sidh_fp2_is_zero(const fp2_element_t a) { 366 | return !mpz_cmp_si(a->a, 0) && !mpz_cmp_si(a->b, 0); 367 | } 368 | 369 | int sidh_fp2_is_one(const fp2_element_t a) { 370 | return !mpz_cmp_si(a->a, 0) && !mpz_cmp_si(a->b, 1); 371 | } 372 | 373 | int sidh_fp2_equals(const fp2_element_t a, 374 | const fp2_element_t b) { 375 | return (mpz_cmp(a->a, b->a) == 0) && (mpz_cmp(a->b, b->b) == 0); 376 | } 377 | 378 | void sidh_fp2_random(fp2_element_t x, 379 | gmp_randstate_t randstate) { 380 | mpz_urandomm(x->a, randstate, characteristic); 381 | mpz_urandomm(x->b, randstate, characteristic); 382 | } 383 | 384 | void sidh_fp2_sqrt(fp2_element_t x, 385 | const fp2_element_t a) { 386 | mpz_t exponent; 387 | fp2_element_t temp_a; 388 | fp2_element_t b; 389 | fp2_element_t c; 390 | fp2_element_t beta; 391 | mpz_t base_root; 392 | gmp_randstate_t randstate; 393 | 394 | mpz_init(exponent); 395 | sidh_fp2_init(temp_a); 396 | sidh_fp2_init(b); 397 | sidh_fp2_init(c); 398 | sidh_fp2_init(beta); 399 | mpz_init(base_root); 400 | gmp_randinit_default(randstate); 401 | 402 | // compute (p - 1) / 2 403 | mpz_sub_ui(exponent, characteristic, 1); 404 | mpz_divexact_ui(exponent, exponent, 2); 405 | 406 | while (sidh_fp2_is_zero(b)) { 407 | sidh_fp2_random(c, randstate); 408 | sidh_fp2_square(temp_a, c); 409 | sidh_fp2_mul(temp_a, temp_a, a); 410 | 411 | // compute 1 + temp_a^((p - 1) / 2) 412 | sidh_fp2_pow(b, temp_a, exponent); 413 | sidh_fp2_add_ui(b, b, 1); 414 | } 415 | 416 | // compute temp_a * b^2 417 | sidh_fp2_square(beta, b); 418 | sidh_fp2_mul(beta, beta, temp_a); 419 | 420 | // beta is now in the prime field 421 | sidh_fp_sqrt(base_root, beta->b); 422 | sidh_fp2_inv(b, b); 423 | sidh_fp2_mul_scaler(b, b, base_root); 424 | sidh_fp2_div(x, b, c); 425 | 426 | 427 | mpz_clear(exponent); 428 | sidh_fp2_clear(temp_a); 429 | sidh_fp2_clear(b); 430 | sidh_fp2_clear(c); 431 | sidh_fp2_clear(beta); 432 | mpz_clear(base_root); 433 | gmp_randclear(randstate); 434 | } 435 | 436 | int sidh_fp2_is_square(const fp2_element_t a) { 437 | mpz_t exponent; 438 | mpz_t norm; 439 | fp2_element_t temp; 440 | 441 | mpz_init(exponent); 442 | mpz_init(norm); 443 | sidh_fp2_init(temp); 444 | 445 | // a^((p - 1) / 2) 446 | mpz_sub_ui(exponent, characteristic, 1); 447 | mpz_divexact_ui(exponent, exponent, 2); 448 | sidh_fp2_pow(temp, a, exponent); 449 | 450 | sidh_fp2_norm(norm, temp); 451 | int result = (mpz_cmp_si(norm, 1) == 0); 452 | 453 | mpz_clear(exponent); 454 | mpz_clear(norm); 455 | sidh_fp2_clear(temp); 456 | 457 | return result; 458 | } 459 | 460 | void sidh_fp2_norm(mpz_t x, 461 | const fp2_element_t a) { 462 | mpz_t temp1; 463 | mpz_t temp2; 464 | mpz_inits(temp1, temp2, NULL); 465 | 466 | sidh_fp_mul(temp1, a->a, a->a); 467 | sidh_fp_mul(temp2, a->b, a->b); 468 | sidh_fp_add(temp1, temp1, temp2); 469 | 470 | mpz_set(x, temp1); 471 | mpz_clears(temp1, temp2, NULL); 472 | } 473 | 474 | void sidh_fp2_to_bytes(uint8_t *bytes, 475 | const fp2_element_t a, 476 | long prime_size) { 477 | for (long i = 0; i < 2 * prime_size; i++) 478 | bytes[i] = 0; 479 | 480 | mpz_export(bytes, NULL, -1, 1, 0, 0, a->a); 481 | mpz_export(bytes + prime_size, NULL, -1, 1, 0, 0, a->b); 482 | } 483 | 484 | void sidh_bytes_to_fp2(fp2_element_t a, 485 | const uint8_t *bytes, 486 | long prime_size) { 487 | sidh_fp2_zero(a); 488 | mpz_import(a->a, prime_size, -1, 1, 0, 0, bytes); 489 | mpz_import(a->b, prime_size, -1, 1, 0, 0, bytes + prime_size); 490 | } 491 | -------------------------------------------------------------------------------- /sidh/sidh_quadratic_ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef FP2_H 19 | #define FP2_H 20 | 21 | #include 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | mpz_t characteristic; 29 | 30 | /** 31 | * Representation of elements of the quadratic extension F_(p^2) 32 | * of F_p. We assume F_(p^2) is represented by the quotient 33 | * F_p[X] / (X^2 + 1) which requires X^2 + 1 to be irreducible over F_p. 34 | * The elements are therefore of the form a * i + b where i^2 = -1. 35 | */ 36 | typedef struct { 37 | mpz_t a; 38 | mpz_t b; 39 | } fp2_element_struct; 40 | 41 | typedef fp2_element_struct fp2_element_t[1]; 42 | 43 | //////////////// fp methods ////////////////////////// 44 | 45 | /** 46 | * {@link sidh_init_chararacteristic} 47 | * @param p 48 | */ 49 | void sidh_fp_init_chararacteristic_ui(long p); 50 | 51 | /** 52 | * {@link sidh_init_chararacteristic} 53 | * @param value 54 | */ 55 | void sidh_fp_init_chararacteristic_str(const char *value); 56 | 57 | /** 58 | * Initializes the characteristic to {@code p}. 59 | * @param p 60 | */ 61 | void sidh_fp_init_chararacteristic(const mpz_t p); 62 | 63 | /** 64 | * Sets {@code x = a}. 65 | * @param x 66 | * @param a 67 | */ 68 | void sidh_fp_set(mpz_t x, const mpz_t a); 69 | 70 | /** 71 | * Sets {@code x = a + b}. 72 | * @param x 73 | * @param a 74 | * @param b 75 | */ 76 | void sidh_fp_add(mpz_t x, 77 | const mpz_t a, 78 | const mpz_t b); 79 | 80 | /** 81 | * {@link sidh_fp_add}. 82 | * @param x 83 | * @param a 84 | * @param b 85 | */ 86 | void sidh_fp_add_ui(mpz_t x, 87 | const mpz_t a, 88 | unsigned long b); 89 | 90 | /** 91 | * Sets {@code x = a - b}. 92 | * @param x 93 | * @param a 94 | * @param b 95 | */ 96 | void sidh_fp_sub(mpz_t x, 97 | const mpz_t a, 98 | const mpz_t b); 99 | 100 | /** 101 | * {@link sidh_fp_sub} 102 | * @param x 103 | * @param a 104 | * @param b 105 | */ 106 | void sidh_fp_sub_ui(mpz_t x, 107 | const mpz_t a, 108 | unsigned long b); 109 | 110 | /** 111 | * Sets {@code x = a * b}. 112 | * @param x 113 | * @param a 114 | * @param b 115 | */ 116 | void sidh_fp_mul(mpz_t x, 117 | const mpz_t a, 118 | const mpz_t b); 119 | 120 | /** 121 | * {@link sidh_fp_mul} 122 | * @param x 123 | * @param a 124 | * @param b 125 | */ 126 | void sidh_fp_mul_si(mpz_t x, 127 | const mpz_t a, 128 | long b); 129 | 130 | /** 131 | * Sets {@code x = 1 / a}. This is possible only if {@code a} is 132 | * prime to the characteristic. 133 | * @param x 134 | * @param a 135 | */ 136 | void sidh_fp_inv(mpz_t x, 137 | const mpz_t a); 138 | 139 | /** 140 | * Sets {x = a / b}. @see fp_inv. 141 | * @param x 142 | * @param a 143 | * @param b 144 | */ 145 | void sidh_fp_div(mpz_t x, 146 | const mpz_t a, 147 | const mpz_t b); 148 | 149 | /** 150 | * Sets {@code x = -a}. 151 | * @param x 152 | * @param a 153 | */ 154 | void sidh_fp_neg(mpz_t x, 155 | const mpz_t a); 156 | 157 | /** 158 | * Computes the square root of {@code a}. 159 | * This method works only for p = 3 mod 4. 160 | * @param x the square root 161 | * @param a 162 | */ 163 | void sidh_fp_sqrt(mpz_t x, 164 | const mpz_t a); 165 | 166 | //////////////// fp2 methods ////////////////////////// 167 | 168 | /** 169 | * Initializes {@code x} to zero. 170 | * @param x 171 | */ 172 | void sidh_fp2_init(fp2_element_t x); 173 | 174 | /** 175 | * Initializes {@code x} to {@code a * i + b}. 176 | * @param x 177 | * @param a 178 | * @param b 179 | */ 180 | void sidh_fp2_init_set_si(fp2_element_t x, 181 | long a, 182 | long b); 183 | 184 | /** 185 | * {@link sidh_fp2_init_set_si}. 186 | * @param x 187 | * @param a 188 | * @param b 189 | */ 190 | void sidh_fp2_init_set_str(fp2_element_t x, 191 | const char *a, 192 | const char *b); 193 | 194 | /** 195 | * Initializes {@code x} to {@code a}. 196 | * @param x 197 | * @param a 198 | */ 199 | void sidh_fp2_init_set(fp2_element_t x, 200 | const fp2_element_t a); 201 | 202 | /** 203 | * Frees the memory allocated to {@code x}. 204 | * @param x 205 | */ 206 | void sidh_fp2_clear(fp2_element_t x); 207 | 208 | /** 209 | * Copies {@code a} into {@code x}. 210 | * @param x 211 | * @param b 212 | */ 213 | void sidh_fp2_set(fp2_element_t x, 214 | const fp2_element_t b); 215 | 216 | /** 217 | * Sets {@code a = 0} 218 | * @param x 219 | */ 220 | void sidh_fp2_zero(fp2_element_t x); 221 | 222 | /** 223 | * Sets {@code x = 1}. 224 | * @param x 225 | */ 226 | void sidh_fp2_one(fp2_element_t x); 227 | 228 | /** 229 | * @param a 230 | * @return the string representation of {@code a} 231 | */ 232 | char *sidh_fp2_get_str(const fp2_element_t a); 233 | 234 | /** 235 | * Sets {@code x = a + b}. 236 | * @param x 237 | * @param a 238 | * @param b 239 | */ 240 | void sidh_fp2_add(fp2_element_t x, 241 | const fp2_element_t a, 242 | const fp2_element_t b); 243 | 244 | /** 245 | * {@link sidh_fp2_add} 246 | * @param x 247 | * @param a 248 | * @param b 249 | */ 250 | void sidh_fp2_add_ui(fp2_element_t x, 251 | const fp2_element_t a, 252 | unsigned long b); 253 | 254 | /** 255 | * Sets {@code x = a - b}. 256 | * @param x 257 | * @param a 258 | * @param b 259 | */ 260 | void sidh_fp2_sub(fp2_element_t x, 261 | const fp2_element_t a, 262 | const fp2_element_t b); 263 | 264 | /** 265 | * {@link sidh_fp2_sub} 266 | * @param x 267 | * @param a 268 | * @param b 269 | */ 270 | void sidh_fp2_sub_ui(fp2_element_t x, 271 | const fp2_element_t a, 272 | unsigned long b); 273 | 274 | /** 275 | * Sets {@code x = a * b}. 276 | * @param x 277 | * @param a 278 | * @param b 279 | */ 280 | void sidh_fp2_mul(fp2_element_t x, 281 | const fp2_element_t a, 282 | const fp2_element_t b); 283 | 284 | /** 285 | * Sets {@code x = a^2}. 286 | * @param x 287 | * @param a 288 | */ 289 | void sidh_fp2_square(fp2_element_t x, 290 | const fp2_element_t a); 291 | 292 | /** 293 | * {@link sidh_fp2_pow} 294 | */ 295 | void sidh_fp2_pow_ui(fp2_element_t x, 296 | const fp2_element_t a, 297 | unsigned long n); 298 | 299 | /** 300 | * Sets {@code x = a^n}. 301 | * @param x 302 | * @param a 303 | * @param n 304 | */ 305 | void sidh_fp2_pow(fp2_element_t x, 306 | const fp2_element_t a, 307 | const mpz_t n); 308 | 309 | /** 310 | * Sets {@code x = 1 / a}. 311 | * @param x 312 | * @param a 313 | */ 314 | void sidh_fp2_inv(fp2_element_t x, 315 | const fp2_element_t a); 316 | 317 | /** 318 | * Sets {@code x = a / b}. 319 | * @param x 320 | * @param a 321 | * @param b 322 | */ 323 | void sidh_fp2_div(fp2_element_t x, 324 | const fp2_element_t a, 325 | const fp2_element_t b); 326 | 327 | /** 328 | * Sets {@code x = -u * i + v} where {@code a = u * i + v}. 329 | * @param x 330 | * @param a 331 | */ 332 | void sidh_fp2_conjugate(fp2_element_t x, 333 | const fp2_element_t a); 334 | 335 | /** 336 | * Sets {@code x = -a}. 337 | * @param x 338 | * @param a 339 | */ 340 | void sidh_fp2_negate(fp2_element_t x, 341 | const fp2_element_t a); 342 | 343 | /** 344 | * Sets {@code x = a * scaler}. 345 | * @param x 346 | * @param a 347 | * @param scaler 348 | */ 349 | void sidh_fp2_mul_scaler(fp2_element_t x, 350 | const fp2_element_t a, 351 | const mpz_t scaler); 352 | 353 | /** 354 | * {@link sidh_fp2_mul_scaler} 355 | * @param x 356 | * @param a 357 | * @param scaler 358 | */ 359 | void sidh_fp2_mul_scaler_si(fp2_element_t x, 360 | const fp2_element_t a, 361 | long scaler); 362 | 363 | /** 364 | * Checks if {@code a} is zero. 365 | * @param a 366 | * @return 1 if {@code a == 0}, and 0 otherwise 367 | */ 368 | int sidh_fp2_is_zero(const fp2_element_t a); 369 | 370 | /** 371 | * Checks if {@code a} is one. 372 | * @param a 373 | * @return 1 if {@code a == 1}, and 0 otherwise 374 | */ 375 | int sidh_fp2_is_one(const fp2_element_t a); 376 | 377 | /** 378 | * Checks if {@code a == b}. 379 | * @param a 380 | * @param b 381 | * @return 1 if {@code a == b}, and 0 otherwise. 382 | */ 383 | int sidh_fp2_equals(const fp2_element_t a, 384 | const fp2_element_t b); 385 | 386 | /** 387 | * Generates a random element in the quadratic extension. 388 | * @param x the generated random element 389 | * @param randstate 390 | */ 391 | void sidh_fp2_random(fp2_element_t x, 392 | gmp_randstate_t randstate); 393 | 394 | /** 395 | * Computes the square root of {@code a}. 396 | * The algorithm is based on 397 | * Doliskani & Schost, Taking Roots over High Extensions of Finite Fields, 2011. 398 | * It works for any characteristic, but since it uses {@link sidh_fp_sqrt} for 399 | * base-case square root, it is limited to p = 3 mod 4. 400 | * @param x the square root 401 | * @param a 402 | */ 403 | void sidh_fp2_sqrt(fp2_element_t x, 404 | const fp2_element_t a); 405 | 406 | /** 407 | * Checks if {@code a} is a square. 408 | * @param a 409 | * @return 1 if {@code a} is a square, 0 otherwise 410 | */ 411 | int sidh_fp2_is_square(const fp2_element_t a); 412 | 413 | /** 414 | * Computes the norm of {@code x = b * i + c} which is b^2 + c^2. 415 | * @param x the computed norm 416 | * @param a 417 | */ 418 | void sidh_fp2_norm(mpz_t x, 419 | const fp2_element_t a); 420 | 421 | 422 | /** 423 | * Converts bytes an fp2 element to a byte array. 424 | * @param bytes 425 | * @param a 426 | * @param prime_size 427 | */ 428 | void sidh_fp2_to_bytes(uint8_t *bytes, 429 | const fp2_element_t a, 430 | long prime_size); 431 | 432 | 433 | /** 434 | * Converts a byte array to an fp2 element. 435 | * @param a 436 | * @param bytes 437 | * @param prime_size 438 | */ 439 | void sidh_bytes_to_fp2(fp2_element_t a, 440 | const uint8_t *bytes, 441 | long prime_size); 442 | 443 | #ifdef __cplusplus 444 | } 445 | #endif 446 | 447 | #endif /* FP2_H */ 448 | 449 | -------------------------------------------------------------------------------- /sidh/sidh_shared_key.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #include "sidh_shared_key.h" 20 | #include "sidh_isogeny.h" 21 | 22 | void sidh_shared_key_generate(fp2_element_t shared_key, 23 | const public_key_t public_key, 24 | const private_key_t private_key, 25 | const public_params_t params) { 26 | 27 | point_t kernel_gen; 28 | sidh_point_init(kernel_gen); 29 | 30 | // compute a generator for the kernel of the isogeny 31 | sidh_private_key_compute_kernel_gen(kernel_gen, 32 | private_key, 33 | public_key->P, 34 | public_key->Q, 35 | params->le, 36 | public_key->E); 37 | elliptic_curve_t E; 38 | sidh_elliptic_curve_init(E); 39 | sidh_elliptic_curve_set(E, public_key->E); 40 | 41 | sidh_isogeny_evaluate_strategy_curve(E, kernel_gen, params->l, params->e, 0.5); 42 | // sidh_isogeny_evaluate_naive_curve(E, kernel_gen, params->l, params->e, 3); 43 | 44 | sidh_elliptic_curve_compute_j_inv(shared_key, E); 45 | 46 | sidh_point_clear(kernel_gen); 47 | sidh_elliptic_curve_clear(E); 48 | } -------------------------------------------------------------------------------- /sidh/sidh_shared_key.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SHARED_KEY_H 19 | #define SHARED_KEY_H 20 | 21 | #include "sidh_private_key.h" 22 | #include "sidh_public_key.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /** 29 | * Generates the shared-key. 30 | * @param shared_key the generated shared-key 31 | * @param public_key other's public-key 32 | * @param private_key own private-key 33 | * @param params own parameters 34 | */ 35 | void sidh_shared_key_generate(fp2_element_t shared_key, 36 | const public_key_t public_key, 37 | const private_key_t private_key, 38 | const public_params_t params); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif /* SHARED_KEY_H */ 45 | 46 | -------------------------------------------------------------------------------- /sidh/sidh_util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "sidh_util.h" 24 | 25 | char *sidh_concat(char *str1, 26 | const char *str2) { 27 | char *temp = (char *) malloc(strlen(str1) + strlen(str2) + 1); 28 | strcpy(temp, str1); 29 | strcat(temp, str2); 30 | return temp; 31 | } 32 | 33 | char *sidh_get_random_str(int num_bytes) { 34 | char *rand_value = (char *) malloc(num_bytes * sizeof (char)); 35 | FILE *random_dev; 36 | 37 | random_dev = fopen("/dev/urandom", "r"); 38 | if (random_dev) { 39 | size_t size = fread(rand_value, 40 | 1, 41 | num_bytes * sizeof (char), 42 | random_dev); 43 | fclose(random_dev); 44 | if (size != 0) { 45 | return rand_value; 46 | } 47 | } 48 | 49 | srand(time(NULL)); 50 | for (int i = 0; i < num_bytes; i++) 51 | rand_value[i] = (char) rand(); 52 | 53 | return rand_value; 54 | } 55 | 56 | void sidh_get_random_mpz(mpz_t x) { 57 | int num_bytes = 20; 58 | char *a = sidh_get_random_str(num_bytes); 59 | mpz_import(x, num_bytes, 1, sizeof (char), 0, 0, a); 60 | } 61 | 62 | char *sidh_array_xor(const char *array1, 63 | const char *array2, 64 | long lenght) { 65 | char *result = (char *) malloc(lenght); 66 | for (long i = 0; i < lenght; i++) 67 | result[i] = array1[i] ^ array2[i]; 68 | 69 | return result; 70 | } -------------------------------------------------------------------------------- /sidh/sidh_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef UTIL_H 19 | #define UTIL_H 20 | 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /** 28 | * Concatenates two strings. 29 | * @param str1 30 | * @param str2 31 | * @return the concatenation of {@code str1, str2} 32 | */ 33 | char *sidh_concat(char *str1, 34 | const char *str2); 35 | 36 | /** 37 | * Generates a random char array of length {@code num_bytes}. 38 | * @param num_bytes 39 | * @return a random char array of length {@code num_bytes} 40 | */ 41 | char *sidh_get_random_str(int num_bytes); 42 | 43 | /** 44 | * @param x a randomly generated 160bit integer 45 | */ 46 | void sidh_get_random_mpz(mpz_t x); 47 | 48 | 49 | /** 50 | * @param array1 51 | * @param array2 52 | * @param lenght 53 | * @return the bitwise xor of the two arrays 54 | */ 55 | char *sidh_array_xor(const char *array1, 56 | const char *array2, 57 | long lenght); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif /* UTIL_H */ 64 | 65 | -------------------------------------------------------------------------------- /sidh/test/Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = ../build 2 | OBJECTS = $(wildcard $(BUILD_DIR)/*) 3 | SOURCES = $(wildcard test*.c) 4 | TESTS = $(patsubst %.c, %, $(SOURCES)) 5 | INCLUDE_DIRS = -I.. -I/usr/local/include 6 | LIB_DIRS = -L$(BUILD_DIR) -L/usr/local/lib 7 | EXECS = $(patsubst %.c, %, $(SOURCES)) 8 | 9 | GCC = gcc 10 | GCCFLAGS = -Wall -O0 -g -march=native -std=c11 -static 11 | LIBS = $(LIB_DIRS) -lsidh -lgmp -lm 12 | 13 | .PHONY: clean 14 | 15 | all: $(TESTS) 16 | 17 | clean: 18 | rm -f $(EXECS) 19 | 20 | test_%: 21 | $(GCC) -o test_$* test_$*.c $(GCCFLAGS) $(INCLUDE_DIRS) $(LIBS) 22 | -------------------------------------------------------------------------------- /sidh/test/public_params_263: -------------------------------------------------------------------------------- 1 | p : 13278338917780691403163453935679248163066204141424819568321422575495838416502783 2 | E : y^2 = x^3 + (10146232096640085910917654383121220722483913358884738813297160334128811466415525*i+12561065565697579851239386918801659303795666601356542822684985096240783059294353)*x + (5173097881985929355869345579251684505584624561073144550698251610858120795396524*i+7107679418274528586696192790945059679329002947961173384005281572895084003568218) 3 | lA: 2 4 | eA: 130 5 | PA: (1195124728519659060317276132092013999345554256425666367370465963951595701748339*i + 12098972036709468461769702810131237350914726908853501736574286596252384974205652, 9783772475920257416467468866150378267376245694752823265285613818169901942309758*i + 11347159712348451494564706572599934965946403356550033502368700150470499448870987) 6 | QA: (13205817885805264818436305084890835188490919868599289846511015770901764583677253*i + 5747572646648472262100078852868099320898697620053049578554081522615552834142382, 11801682343040573989191884352262922625922977024975963745404870899756844108073781*i + 995065035530346107238957276796927946979246210950956147759509023538740100220494) 7 | lB: 3 8 | eB: 81 9 | PB: (5344800255669587458309912385997503623935901519546261901204157001079956379346933*i + 4377688844822469620769951245537289173274736372423169606270308984109645753298367, 6652276474756696057821879367411351758786745790244544252917780253177388224676512*i + 6708409928090950067466623637647088247028372838873736207829979327577754417492323) 10 | QB: (5394161621076087291764603321428338049084294313968048256313378341079709241759382*i + 11839282739753708776384780179031575074752559110018400195581350405443930573103478, 13250321748367194013481592159238890438519376028036613608154243555537109237538486*i + 5018156126061581597984382235576466750307112019427938373002833669914648135622879) 11 | -------------------------------------------------------------------------------- /sidh/test/public_params_46: -------------------------------------------------------------------------------- 1 | p : 60183678025727 2 | E : y^2 = x^3 + (33377407586757 * i + 44218433491776) * x + (14267804413813 * i + 34113052821919) 3 | lA: 2 4 | eA: 22 5 | PA: (3621292231555 * i + 37993208494088, 7444041801194 * i + 49342879615307) 6 | QA: (42474562877393 * i + 53371276514445, 2096833973245 * i + 34935006825293) 7 | lB: 3 8 | eB: 15 9 | PB: (15834791163149 * i + 48632673242917, 26787723276578 * i + 2080970701160) 10 | QB: (41347477823487 * i + 16893996428645, 16353006256863 * i + 58871308637793) 11 | -------------------------------------------------------------------------------- /sidh/test/public_params_521: -------------------------------------------------------------------------------- 1 | p : 5646428529833603710854376801719732121889771686125102421349898409102848702003905102057129871853579459735758942656769724874115169484320460874488881525976727551 2 | E : y^2 = x^3 + (749284552715987846148963973296050195126229569341142224654666772427960869882697237787535113296933915107646826510805251959952317725821624926383192023779227916*i+4450862168665197219135947325665108840719206715065697554561201799074300990784248608236935291171911258967881216685164820345027022153809546719817771293646383402)*x + (2090701186560231235295975659537182225064154823783034367876346818451609525370628921026656891712603865222854303410638520367213822274197422708317359681412801686*i+928331116130151780314451251635374082476545231185861659046556547242876069870814548070746611568992085667981514874929668958586384832118048434225604407758374282) 3 | lA: 2 4 | eA: 258 5 | PA: (4099566244205693793351119863629118684504739011975746402268940060566068632610815266810397027797757094816929218567651253950072216325440815687610023993835084896*i + 1558017772998619899443036875935946235185689333987633624537644882488763783158554538347022310514300405167644627965823931934377803788161014061154800653636626931, 4309963503463625615680726988334053841208952164733703323705989592325431854359074218382917880219717866947948218257035199142577782828393068620191995480863080814*i + 371139087724151319343471759858355552237686119972572871121509307705868621618190178855645217401101942092226237837619601742237974591506374361483536984282167861) 6 | QA: (1068668697541208179714192612921089347931894414290359842562082470165052062241629674686530102495737378212525479245784252461983051355518227298502808569246918728*i + 3439758296201500299118396242846510199830393172149382335887091564620130903972985332523718369650346601985540123834734249105539074407495456634862920938577617312, 1377114633894100174167466575056453645918713530999472681191914854993325497527119824352424425031078252594689770391880104513192317018010057467691025379460070671*i + 4932622986840321005380766859714312144000718130204073302754586852541324804616229501269099878044960212632820224170853684078869359092914886360672352750928115581) 7 | lB: 3 8 | eB: 161 9 | PB: (1873601143875829767876930991819826178988629054425671567488176037109831662817961473686026144306947256312476316751547084289880741326649856082832561714610850944*i + 1560175318533519875886314144935322002014985257654221707041583923868859979591849198401249634353361077499233198751747045058302746944304448268907689086502178616, 4982994975025169124121736752171094366264972439763192439008272414941290947933013927951198144521578535758162978083130741822789277050594650669549067865269480720*i + 5276260709601376725929198456951440724276715138987805447686932240717621617089316893818094566900580557346731678327745302440662762271627385800896501795127323769) 10 | QB: (697646709404910236660735870475422491121726200391885074740251760174191839071888445718446637282034941836922171390196797602747505117748596104805560163856490804*i + 3625576702015594834652275264908614642470435266304155762812699923280767886451566560460365242828862442624975825786369269113406701427398318872227046324990780609, 4066773540363717441440268891591433184568174886592697891244632377954091519594774358483000191238791345767299029423088482812653880802118173619454377886226640626*i + 4190003034380720563592676434553383980850520959077934081654167677748426947392920518786394581045699661017779519240551462796264093681413592624709890262004623150) 11 | -------------------------------------------------------------------------------- /sidh/test/public_params_771: -------------------------------------------------------------------------------- 1 | p : 9161191555982008052298538759697325872858383005444503030763917191888120427263653604739574602371851919945332710234806205297475768266460658683484318356498713773944703702864057467786913144364234277796785269800198817400814717913480036351 2 | E : y^2 = x^3 + (834414288954992257633455994192711449929625512434805347027412475310171948875352369017186937444645005409828817983476510572586689796723205608064400704385270116308944492168385499542550868452776212626111499661118550170888024552876875729*i+6422246000772528873002015578224375300444670334298744905928223359513938843110113655634334268879522218663819121887750824098836054966064056104287198717041277477329053582144813207672147369924203318339728355843554541603191165928512397074)*x + (6952862402661321818296934608460489441319492072429008834217170925899505712694617760090534612163651714423387662001257443691685988562319647888954263195545834510820670121276853179853453135161349568882745925527747286264586000816122662211*i+1801461307959256058754493292728237821856779795303869606357346421878164668617118529630863155614277813374785952465141324739461376333648338471745996274618770379494305097783365807731152848487472399799827998470890201827624741461111844749) 3 | lA: 2 4 | eA: 386 5 | PA: (8104593598414300086705087098908311675030394399959710332294184564762361863835814307651327024806690095568546280563692186849608460564606528773115207348687739021740029922619947714003573784888374548470687911506820492526985145356335776446*i + 632723349492681895135768435670357424582748082370711990704098097526814363254991414123449305576539513413267774301605548017161074510859073483979044361740779150098452314120335316096416597425252882878881588818896781804191220848731008911, 6034454472695438020325443031188950458345445112930585331722482288319997086142640364760979210290700670085317874428427766978327706213014073448960161802245001428613528860063394247112544226096847944993689243523414240839321526974724280084*i + 3376800547075148066131970733541260743185153743453912100162319249600572606491084521062090319658073231669236186390422247468127880255567740549554667385892315318084299520660699776774656198376921140804260118165199828142540405774846853362) 6 | QA: (2765053530820933445180998871832795313413946616218824127593215418859013295660994609348273546952174346166291903038023352135058779784133949653750586420316372475215070348272866065120539728715859798970386824706592072979142529191135265323*i + 4732630024306258879927225136904171174931421517225731042645253305380470569884989406374249571295113204909266761424593068942210539695621294791558555039840356194123377363470161894673618251481432584334320864233790205509164494505329331140, 4708584843807409676003733183136845288008597122413250473476957203240325041335536376819164132204831789648003763063194049792870695914267484368767687682889171445457695974399304884657394666807097601382128550039198416659937221320896980595*i + 6104437072476030203734870744361913380396342850775889826642334399814339224961644051070388756974954400647041041004040997989961961816982978689836414675142946310418861822777207486737128660492374354598010889893873060781304652392500710082) 7 | lB: 3 8 | eB: 242 9 | PB: (3723895349260758944309889666952259909100424286764560948312844268916772080039091215194337476636106420561414206591006321840112505108525982835492286766266110460566937541551059011352798312867785900902951383836578444811900436603779674156*i + 8743733696371247709279217014221258693400652288884395784267041686740452975091187425123471886102340505926375682973850553993788314479705338557349284829716634286210825839825870379330100097103593148671390855900137936801780665161878467993, 8424241650394632026078421716292833598872223719053431149109783663376931645995151278886785513466077121063748132909299925706619410172763350254899661370368971798311266097772796416940961537063436478392108549760549489321636110323643921123*i + 5374610701506876802640722880318277643810083668249556787469960695884056089879250039154916755196748541850985290281804798435130927222521567170894905772855374873224510597225929994186728464447646660504589278345473514974074045904197344273) 10 | QB: (7981195513789185488304157075392399068225052449489399943063249773724560281912789833792310612686835775356813196319643714519912123781500389027567621573946130157326769787082613646934296091151487953874493791717298439146548339580934348575*i + 6959299245778867305112554827985507377113662771316265280990751282080086185858550157506531552361757479904416443825479048359163719118671413144273420888615839877660288012435298448942304481059091585291706567711227879486375625133765783910, 4336888647745442057861067196613721067586889048321014506728806821392030059558638097842307835657146159647787621123250859783441147632121339894258934458102109985684014691372520469809743302874968486912740925764328254939284436994206821845*i + 219245698132319235934495637714582743670714862281024333766283207034829039474459867538486706426384326703893620364910932534607493596118208826082598798090838576408297983032654112984263431060439529497966028364279027386883785406090014775) 11 | 12 | -------------------------------------------------------------------------------- /sidh/test/test_key_exchange.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include "sidh_elliptic_curve.h" 22 | #include "sidh_public_param.h" 23 | #include "sidh_isogeny.h" 24 | #include "sidh_private_key.h" 25 | #include "sidh_public_key.h" 26 | #include "sidh_shared_key.h" 27 | #include "sidh_util.h" 28 | #include "sidh_public_key_validation.h" 29 | #include 30 | #include 31 | #include 32 | 33 | void test_key_exchange(const public_params_t paramsA, 34 | const public_params_t paramsB) { 35 | sidh_fp_init_chararacteristic(paramsA->characteristic); 36 | 37 | private_key_t Alice_private_key; 38 | sidh_private_key_init(Alice_private_key); 39 | sidh_private_key_generate(Alice_private_key, paramsA); 40 | printf("Alice's private key: \n"); 41 | sidh_private_key_print(Alice_private_key); 42 | printf("\n--------------------------------------------\n\n"); 43 | 44 | public_key_t Alice_public_key; 45 | sidh_public_key_init(Alice_public_key); 46 | point_t kernel_gen; 47 | sidh_point_init(kernel_gen); 48 | sidh_private_key_compute_kernel_gen(kernel_gen, 49 | Alice_private_key, 50 | paramsA->P, 51 | paramsA->Q, 52 | paramsA->le, 53 | paramsA->E); 54 | sidh_public_key_generate(Alice_public_key, kernel_gen, paramsA, paramsB); 55 | printf("Alice's public key: \n"); 56 | sidh_public_key_print(Alice_public_key); 57 | printf("\n--------------------------------------------\n\n"); 58 | 59 | private_key_t Bob_private_key; 60 | sidh_private_key_init(Bob_private_key); 61 | sidh_private_key_generate(Bob_private_key, paramsB); 62 | printf("Bob's private key: \n"); 63 | sidh_private_key_print(Bob_private_key); 64 | printf("\n--------------------------------------------\n\n"); 65 | 66 | public_key_t Bob_public_key; 67 | sidh_public_key_init(Bob_public_key); 68 | sidh_private_key_compute_kernel_gen(kernel_gen, 69 | Bob_private_key, 70 | paramsB->P, 71 | paramsB->Q, 72 | paramsB->le, 73 | paramsB->E); 74 | sidh_public_key_generate(Bob_public_key, kernel_gen, paramsB, paramsA); 75 | printf("Bob's public key: \n"); 76 | sidh_public_key_print(Bob_public_key); 77 | printf("\n--------------------------------------------\n\n"); 78 | 79 | fp2_element_t Alice_shared_key; 80 | sidh_fp2_init(Alice_shared_key); 81 | sidh_shared_key_generate(Alice_shared_key, 82 | Bob_public_key, 83 | Alice_private_key, 84 | paramsA); 85 | printf("Alice's shared key: \n"); 86 | printf("%s\n", sidh_fp2_get_str(Alice_shared_key)); 87 | printf("\n--------------------------------------------\n\n"); 88 | 89 | fp2_element_t Bob_shared_key; 90 | sidh_fp2_init(Bob_shared_key); 91 | sidh_shared_key_generate(Bob_shared_key, 92 | Alice_public_key, 93 | Bob_private_key, 94 | paramsB); 95 | printf("Bob's shared key: \n"); 96 | printf("%s\n", sidh_fp2_get_str(Bob_shared_key)); 97 | printf("\n--------------------------------------------\n\n"); 98 | 99 | sidh_private_key_clear(Alice_private_key); 100 | sidh_public_key_clear(Alice_public_key); 101 | sidh_private_key_clear(Bob_private_key); 102 | sidh_public_key_clear(Bob_public_key); 103 | sidh_point_clear(kernel_gen); 104 | sidh_fp2_clear(Alice_shared_key); 105 | sidh_fp2_clear(Bob_shared_key); 106 | } 107 | 108 | int main(int argc, char** argv) { 109 | char *input_params = "public_params_521"; 110 | if (argc > 1) { 111 | input_params = argv[1]; 112 | } 113 | 114 | public_params_t paramsA; 115 | public_params_t paramsB; 116 | sidh_public_params_init(paramsA); 117 | sidh_public_params_init(paramsB); 118 | 119 | if (!sidh_public_params_read(paramsA, paramsB, input_params)) 120 | return (EXIT_FAILURE); 121 | 122 | printf("Public parameters:\n"); 123 | sidh_public_params_print(paramsA, 0); 124 | sidh_public_params_print(paramsB, 1); 125 | printf("\n--------------------------------------------\n\n"); 126 | 127 | test_key_exchange(paramsA, paramsB); 128 | 129 | sidh_public_params_clear(paramsA); 130 | sidh_public_params_clear(paramsB); 131 | 132 | return (EXIT_SUCCESS); 133 | } 134 | 135 | -------------------------------------------------------------------------------- /sidh/test/test_public_key_encryption.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "sidh_public_key_encryption.h" 24 | #include "sidh_util.h" 25 | #include "sidh_elliptic_curve_dlp.h" 26 | #include "sidh_public_key_validation.h" 27 | 28 | void test_public_key_encryption(const public_params_t paramsA, 29 | const public_params_t paramsB) { 30 | sidh_fp_init_chararacteristic(paramsA->characteristic); 31 | private_key_t Alice_private_key; 32 | sidh_private_key_init(Alice_private_key); 33 | sidh_private_key_generate(Alice_private_key, paramsA); 34 | 35 | public_key_t Alice_public_key; 36 | sidh_public_key_init(Alice_public_key); 37 | point_t kernel_gen; 38 | sidh_point_init(kernel_gen); 39 | sidh_private_key_compute_kernel_gen(kernel_gen, 40 | Alice_private_key, 41 | paramsA->P, 42 | paramsA->Q, 43 | paramsA->le, 44 | paramsA->E); 45 | sidh_public_key_generate(Alice_public_key, kernel_gen, paramsA, paramsB); 46 | 47 | plaintext_t plaintext; 48 | sidh_public_key_plaintext_init(plaintext); 49 | plaintext->content = "The quick brown fox jumps over the lazy dog."; 50 | plaintext->size = strlen(plaintext->content); 51 | printf("plaintext:\n%s", plaintext->content); 52 | printf("\n--------------------------------------------\n\n"); 53 | 54 | ciphertext_t ciphertext; 55 | sidh_public_key_ciphertext_init(ciphertext); 56 | sidh_public_key_pad_plaintext(plaintext, plaintext); 57 | sidh_public_key_encrypt(ciphertext, 58 | plaintext, 59 | Alice_public_key, 60 | paramsA, 61 | paramsB); 62 | printf("ciphertext using Alice's public-key: \n"); 63 | for (long i = 0; i < ciphertext->size; i++) 64 | printf("%x", 0xff & ciphertext->content[i]); 65 | printf("\n--------------------------------------------\n\n"); 66 | 67 | plaintext_t decrypted_text; 68 | sidh_public_key_plaintext_init(decrypted_text); 69 | sidh_public_key_decrypt(decrypted_text, 70 | ciphertext, 71 | Alice_private_key, 72 | paramsA); 73 | printf("decrypted text using Alice's private-key:\n"); 74 | for (long i = 0; i < decrypted_text->size; i++) 75 | printf("%c", decrypted_text->content[i]); 76 | printf("\n--------------------------------------------\n\n"); 77 | 78 | sidh_public_key_ciphertext_clear(ciphertext); 79 | sidh_private_key_clear(Alice_private_key); 80 | sidh_public_key_clear(Alice_public_key); 81 | sidh_point_clear(kernel_gen); 82 | sidh_public_key_plaintext_clear(plaintext); 83 | sidh_public_key_plaintext_clear(decrypted_text); 84 | } 85 | 86 | int main(int argc, char** argv) { 87 | char *input_params = "public_params_263"; 88 | if (argc > 1) { 89 | input_params = argv[1]; 90 | } 91 | 92 | public_params_t paramsA; 93 | public_params_t paramsB; 94 | sidh_public_params_init(paramsA); 95 | sidh_public_params_init(paramsB); 96 | 97 | if (!sidh_public_params_read(paramsA, paramsB, input_params)) 98 | return (EXIT_FAILURE); 99 | 100 | test_public_key_encryption(paramsA, paramsB); 101 | 102 | sidh_public_params_clear(paramsA); 103 | sidh_public_params_clear(paramsB); 104 | 105 | return (EXIT_SUCCESS); 106 | } 107 | 108 | --------------------------------------------------------------------------------