├── .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 |
--------------------------------------------------------------------------------