├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── build.sh ├── clean.sh ├── puzzles ├── easy.c ├── sudoku1.c ├── sudoku2.c └── unsolvable_2x2_sudoku.c ├── reductions ├── pentomino_reduction.py ├── sudoku_encryption.py └── sudoku_reduction.py ├── src ├── clt.c ├── clt13.h ├── clt_elem.c ├── clt_elem.h ├── crt_tree.c ├── crt_tree.h ├── estimates.c ├── estimates.h ├── utils.c └── utils.h ├── sudoku_sets ├── sudoku1.txt ├── sudoku2.txt ├── sudoku_convert.txt └── unsolvable_sudoku.txt └── test ├── compute_clt_witness.c ├── test_clt.c ├── test_clt_state_new.c └── test_clt_witness_scheme.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | test_clt 3 | test_clt_state_new 4 | test_polylog 5 | Makefile 6 | build/ 7 | CMakeCache.txt 8 | CMakeFiles/ 9 | *.cmake 10 | libaesrand/ 11 | *.so 12 | vgcore.* 13 | *.out 14 | install_manifest.txt 15 | GPATH 16 | GRTAGS 17 | GTAGS -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | project(clt13 VERSION 0.1.0 LANGUAGES C) 3 | 4 | if(NOT CMAKE_BUILD_TYPE) 5 | set(CMAKE_BUILD_TYPE Release) 6 | endif(NOT CMAKE_BUILD_TYPE) 7 | message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") 8 | 9 | include(GNUInstallDirs) 10 | 11 | set(clt13_SOURCES 12 | src/clt.c 13 | src/clt_elem.c 14 | src/crt_tree.c 15 | src/estimates.c 16 | src/utils.c 17 | ) 18 | 19 | add_library(clt13 SHARED ${clt13_SOURCES}) 20 | target_link_libraries(clt13 PUBLIC gmp m aesrand) 21 | 22 | include(FindOpenMP) 23 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -Werror -fPIC -std=gnu11 -march=native ${OpenMP_C_FLAGS}") 24 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg -ggdb -O0") 25 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3") 26 | target_link_libraries(clt13 INTERFACE "${OpenMP_C_FLAGS}") 27 | 28 | install(TARGETS clt13 LIBRARY DESTINATION lib) 29 | install(FILES src/clt13.h src/clt_pl.h DESTINATION include) 30 | 31 | # Test files 32 | 33 | enable_testing() 34 | macro(add_test_ _name) 35 | add_executable("${_name}" "test/${_name}.c") 36 | target_include_directories("${_name}" PRIVATE 37 | ${CMAKE_CURRENT_SOURCE_DIR}/src 38 | ${CMAKE_CURRENT_SOURCE_DIR}) 39 | target_link_libraries("${_name}" PRIVATE clt13 aesrand) 40 | add_test(NAME "${_name}" COMMAND "${_name}") 41 | endmacro() 42 | 43 | add_test_(test_clt) 44 | add_test_(test_clt_state_new) 45 | add_test_(test_clt_witness_scheme) 46 | add_test_(compute_clt_witness) 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Building Usable Witness Encryption 2 | 3 | Witness encryption using multilinear maps was first proposed in 2013, and has continued to evolve since. In this paper, we build on an open-source multilinear map implementation by Carmer and Malozemoff of the graded encoding scheme CLT13 with asymmetric modifications. Using this map, we created the world's first ciphertext encoded with a candidate witness encryption scheme. Finally, using a reduction from Sudoku to Exact Cover, we encrypted the private key to a Bitcoin wallet with 22,700 Satoshi using a Sudoku. 4 | 5 |

6 | Read the paper on arXiv 7 |

8 | 9 | 10 | # What Is This Repository? 11 | 12 | To prove that witness encryptions can be done on real puzzles with reasonable security assumptions, we provide three below (along with the code used to generate them in this repository). Each puzzle is a Sudoku, which has been reduced to an equivalent `Exact-Cover` problem. The Sudokus are given in human-readable form below - their reductions are given in the `puzzles/` directory. The underlying CLT13 Multilinear Map implentation was written by [5GenCrypto](https://github.com/5GenCrypto/clt13). 13 | 14 | Each puzzle encrypts 256 bits of randomness that were used to generate a Bitcoin wallet. We have transferred 2270 Satoshi (approximately $1.10 at writing) into the wallets that are encrypted by the large Sudokus - puzzles 2 and 3. These Sudokus can be solved by hand or with a computerized solver, and are given only as proof of the validity and scalability of our scheme. 15 | 16 | We also created a `4x4` Sudoku which has no satisfying solutuion. We used this Sudoku to encrypt a wallet containing 22,700 Satoshi (approximately $11 at writing), as the only way this money can be retrieved is through defeating our scheme. 17 | 18 | # The Puzzles 19 | 20 | Sudoku 1 encodes the following 9x9 sudoku puzzle: 21 | ``` 22 | .1....... 23 | .....19.5 24 | .64.2.3.. 25 | .4..1.... 26 | ..13.64.. 27 | ....7..9. 28 | ..5.4.62. 29 | 8.92..... 30 | .......5. 31 | ``` 32 | 33 | Sudoku 2 does likewise for the following puzzle: 34 | ``` 35 | ..48....1 36 | .2..4..3. 37 | 6....37.. 38 | 3....54.. 39 | .6..3..9. 40 | ..27....8 41 | ..31....6 42 | .5..9..4. 43 | 4....78.. 44 | ``` 45 | 46 | The unsolvable Sudoku corresponds to the following puzzle: 47 | ``` 48 | ..13 49 | .... 50 | 3... 51 | 1... 52 | ``` 53 | 54 | # Encryption Statistics 55 | 56 | All encryptions were done on a Dell Precision 7540 Mobile Workstation with 72 GB of RAM and an Intel Core i9-9880H CPU @ 2.30GHz. 57 | 58 | - `sudoku1` was encrypted with security parameter `lambda = 20` and multi-linearity `kappa=729`. Its exact cover reduction has 248 sets. It took ~40 minutes to encrypt and has a ciphertext size of 934 MB. 59 | - `sudoku2` was encrypted with security parameter `lambda = 30` and multi-linearity `kappa=729`. Its exact cover reduction has 206 sets. It took ~3 hours to encrypt and has a ciphtertext size of 4.1 GB. 60 | - `unsolvable` was encrypted with security parameter `lambda = 60` and multi-linearit `kappa=32`. Its exact cover reduction has 32 sets. It took ~4 hours to encrypt and has a ciphertext size of 10.6 GB. 61 | 62 | # Prize Public Keys 63 | 64 | To check if the prizes have been claimed, [Blockchain Explorer](https://www.blockchain.com/explorer) can be used (see below links). 65 | 66 | For `sudoku1`: **[15H79JoED7tZTjmLTojRbiydWEDVMsKxaG](https://www.blockchain.com/btc/address/15H79JoED7tZTjmLTojRbiydWEDVMsKxaG)** (2270 Satoshi) 67 | 68 | For `sudoku2`: **[1LVf6GeNx4DBhMXjy7sUj5bK1jBrRWtmz3](https://www.blockchain.com/btc/address/1LVf6GeNx4DBhMXjy7sUj5bK1jBrRWtmz3)** (2270 Satoshi) 69 | 70 | For the unsolvable puzzle: **[1MndAbkcPnyYksL3VNJtoNt54vxta4Rpns](https://www.blockchain.com/btc/address/1MndAbkcPnyYksL3VNJtoNt54vxta4Rpns)** (22,700 Satoshi) 71 | 72 | # Converting from Sudoku puzzle to an actual solution 73 | 74 | The following mentioned files are located in the `sudoku_sets` director. 75 | 76 | For a number in a grid in a Sudoku puzzle solution, we require the row it is in, the column it is in (all counting from the upper left), and the value in the cell. 77 | 78 | For a given cell of the form `(row, col, val)`, where row, col, and val are all zero-indexed, you can find the corresponding set representation in line `row * n ** 2 + col * n + val + 1` (1-indexed lines) of `sudoku_convert.txt`. The number of the encoding of that set is then `row - 1`, where `row` is the row in which that set is now found in the respective `sudoku{n}.txt` file. 79 | 80 | The 4x4 sudoku is unsolvable, but we provide the set representations in `unsolvable_sudoku.txt`. 81 | 82 | # Downloading and Decoding the Encryptions 83 | 84 | Because of file size limits on GitHub, we've uploaded the puzzle encryptions to Google Drive. They may be accessed via this link: 85 | 86 |

87 | Download the ciphertexts 88 |

89 | 90 | This folder contains the subset reductions of the above Sudoku problems, as well as `.tgz` archives that are the actual encryptions. Each `.tgz` file has the following structure: 91 | 92 | ``` 93 | sudoku1 94 | ├───pp_l=x.enc 95 | ├───message_bit_0 96 | │ ├───message_bit.enc 97 | │ ├───set_0.enc 98 | │ ├───set_1.enc 99 | │ ... 100 | │ └───set_n.enc 101 | ├───message_bit_1 102 | │ ├───message_bit.enc 103 | │ ├───set_0.enc 104 | │ ├───set_1.enc 105 | │ ... 106 | │ └───set_n.enc 107 | ... 108 | ``` 109 | 110 | For each puzzle, the public key is shared between all bit encryptions. Once an exact cover has been calculated (say, for example, with sets `l, m, n, p`), we can decrypt the bits. To decrypt bit `k`, use the sets from the folder `message_bit_k`. Compute: 111 | 112 | ``` 113 | is_zero(set_l * set_m * set_n * set_p - message_bit) 114 | ``` 115 | 116 | The boolean returned by `is_zero` is our bit `k`. Repeating this process for all 256 bits will yield the randomness used to generate our Bitcoin private keys. 117 | 118 | # Accessing the Prizes 119 | 120 | Bitcoin private keys are generated from 256 bits of randomness. This is done by computing the `sha256` hash twice and then encoding in `base58`. The below Python snippet turns a `bytes` object with 256 bits into a private key: 121 | 122 | ```python 123 | def get_private_key(input_bytes): 124 | padded = b"\x80" + input_bytes 125 | hashed = sha256(sha256(padded)) 126 | return b58(padded + hashed[:4]) 127 | ``` 128 | 129 | The 256 bits we used to generate the private keys for each wallet have been encrypted. Once they have been retreived as described above, this mechanism should be used to convert them to a private key that can be used to transfer the funds elsewhere. Further details may be found on [https://strm.sh/post/bitcoin-address-generation/](https://strm.sh/post/bitcoin-address-generation/). 130 | 131 | # Decryption Code Snippet 132 | 133 | We provide a unit test that performs both encryption and decryption in `test_clt_witness_schemes.c`. The test can be run using `ctest -R "test_clt_witness_scheme"`. 134 | 135 | The code we used to generate these encryptions may be found in `test/compute_clt_witness.c`. 136 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #abort if any command fails 4 | set -e 5 | 6 | builddir=$(readlink -f build) 7 | if [[ "$1" == "debug" ]]; then 8 | debug="-DCMAKE_BUILD_TYPE=Debug" 9 | elif [[ "$1" == "clean" ]]; then 10 | rm -rf CMakeCache CMakeFiles/ libaesrand 11 | exit 0 12 | else 13 | debug="" 14 | fi 15 | 16 | export CPPFLAGS=-I$builddir/include 17 | export CFLAGS=-I$builddir/include 18 | export LDFLAGS=-L$builddir/lib 19 | 20 | build () { 21 | echo building $1 22 | path=$1 23 | url=$2 24 | branch=$3 25 | if [ ! -d $path ]; then 26 | git clone $url $path -b $branch; 27 | else 28 | pushd $path; git pull origin $branch; popd 29 | fi 30 | pushd $1 31 | cmake -DCMAKE_INSTALL_PREFIX="${builddir}" . 32 | make 33 | make install 34 | popd 35 | echo 36 | } 37 | 38 | echo 39 | echo builddir = $builddir 40 | echo 41 | 42 | build libaesrand https://github.com/5GenCrypto/libaesrand master 43 | 44 | cmake "${debug}" . 45 | make 46 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | rm -rf Makefile CMakeFiles CMakeCache.txt *.cmake libaesrand/ build/ 4 | -------------------------------------------------------------------------------- /puzzles/easy.c: -------------------------------------------------------------------------------- 1 | uint16_t puzzle[3][2] = { 2 | {0, 2}, 3 | {1, 2}, 4 | {1, 3}, 5 | }; -------------------------------------------------------------------------------- /puzzles/sudoku1.c: -------------------------------------------------------------------------------- 1 | uint16_t puzzle[248][4] = { 2 | {0, 82, 163, 244}, 3 | {0, 83, 164, 245}, 4 | {0, 85, 166, 247}, 5 | {0, 87, 168, 249}, 6 | {0, 89, 170, 251}, 7 | {1, 81, 171, 243}, 8 | {2, 82, 181, 244}, 9 | {2, 83, 182, 245}, 10 | {2, 87, 186, 249}, 11 | {2, 88, 187, 250}, 12 | {3, 84, 192, 255}, 13 | {3, 85, 193, 256}, 14 | {3, 86, 194, 257}, 15 | {3, 87, 195, 258}, 16 | {3, 88, 196, 259}, 17 | {3, 89, 197, 260}, 18 | {4, 83, 200, 254}, 19 | {4, 85, 202, 256}, 20 | {4, 86, 203, 257}, 21 | {4, 88, 205, 259}, 22 | {4, 89, 206, 260}, 23 | {5, 83, 209, 254}, 24 | {5, 84, 210, 255}, 25 | {5, 85, 211, 256}, 26 | {5, 87, 213, 258}, 27 | {5, 88, 214, 259}, 28 | {5, 89, 215, 260}, 29 | {6, 82, 217, 262}, 30 | {6, 87, 222, 267}, 31 | {6, 88, 223, 268}, 32 | {7, 84, 228, 264}, 33 | {7, 86, 230, 266}, 34 | {7, 87, 231, 267}, 35 | {7, 88, 232, 268}, 36 | {8, 82, 235, 262}, 37 | {8, 84, 237, 264}, 38 | {8, 86, 239, 266}, 39 | {8, 87, 240, 267}, 40 | {8, 88, 241, 268}, 41 | {9, 91, 163, 244}, 42 | {9, 92, 164, 245}, 43 | {9, 96, 168, 249}, 44 | {10, 91, 172, 244}, 45 | {10, 92, 173, 245}, 46 | {10, 96, 177, 249}, 47 | {10, 97, 178, 250}, 48 | {11, 91, 181, 244}, 49 | {11, 92, 182, 245}, 50 | {11, 96, 186, 249}, 51 | {11, 97, 187, 250}, 52 | {12, 93, 192, 255}, 53 | {12, 95, 194, 257}, 54 | {12, 96, 195, 258}, 55 | {12, 97, 196, 259}, 56 | {13, 92, 200, 254}, 57 | {13, 95, 203, 257}, 58 | {13, 97, 205, 259}, 59 | {14, 90, 207, 252}, 60 | {15, 98, 224, 269}, 61 | {16, 93, 228, 264}, 62 | {16, 95, 230, 266}, 63 | {16, 96, 231, 267}, 64 | {16, 97, 232, 268}, 65 | {17, 94, 238, 265}, 66 | {18, 103, 166, 247}, 67 | {18, 105, 168, 249}, 68 | {18, 107, 170, 251}, 69 | {19, 104, 176, 248}, 70 | {20, 102, 183, 246}, 71 | {21, 103, 193, 256}, 72 | {21, 105, 195, 258}, 73 | {21, 106, 196, 259}, 74 | {21, 107, 197, 260}, 75 | {22, 100, 199, 253}, 76 | {23, 103, 211, 256}, 77 | {23, 105, 213, 258}, 78 | {23, 106, 214, 259}, 79 | {23, 107, 215, 260}, 80 | {24, 101, 218, 263}, 81 | {25, 99, 225, 261}, 82 | {25, 105, 231, 267}, 83 | {25, 106, 232, 268}, 84 | {26, 99, 234, 261}, 85 | {26, 105, 240, 267}, 86 | {26, 106, 241, 268}, 87 | {27, 109, 163, 271}, 88 | {27, 110, 164, 272}, 89 | {27, 112, 166, 274}, 90 | {27, 113, 167, 275}, 91 | {27, 114, 168, 276}, 92 | {27, 116, 170, 278}, 93 | {28, 111, 174, 273}, 94 | {29, 109, 181, 271}, 95 | {29, 110, 182, 272}, 96 | {29, 113, 185, 275}, 97 | {29, 114, 186, 276}, 98 | {29, 115, 187, 277}, 99 | {30, 112, 193, 283}, 100 | {30, 115, 196, 286}, 101 | {30, 116, 197, 287}, 102 | {31, 108, 198, 279}, 103 | {32, 109, 208, 280}, 104 | {32, 112, 211, 283}, 105 | {32, 115, 214, 286}, 106 | {32, 116, 215, 287}, 107 | {33, 109, 217, 289}, 108 | {33, 112, 220, 292}, 109 | {33, 114, 222, 294}, 110 | {33, 115, 223, 295}, 111 | {34, 110, 227, 290}, 112 | {34, 113, 230, 293}, 113 | {34, 114, 231, 294}, 114 | {34, 115, 232, 295}, 115 | {35, 109, 235, 289}, 116 | {35, 110, 236, 290}, 117 | {35, 113, 239, 293}, 118 | {35, 114, 240, 294}, 119 | {35, 115, 241, 295}, 120 | {36, 118, 163, 271}, 121 | {36, 121, 166, 274}, 122 | {36, 123, 168, 276}, 123 | {36, 125, 170, 278}, 124 | {37, 118, 172, 271}, 125 | {37, 121, 175, 274}, 126 | {37, 123, 177, 276}, 127 | {37, 124, 178, 277}, 128 | {37, 125, 179, 278}, 129 | {38, 117, 180, 270}, 130 | {39, 119, 191, 281}, 131 | {40, 121, 202, 283}, 132 | {40, 124, 205, 286}, 133 | {40, 125, 206, 287}, 134 | {41, 122, 212, 284}, 135 | {42, 120, 219, 291}, 136 | {43, 123, 231, 294}, 137 | {43, 124, 232, 295}, 138 | {44, 118, 235, 289}, 139 | {44, 123, 240, 294}, 140 | {44, 124, 241, 295}, 141 | {45, 127, 163, 271}, 142 | {45, 128, 164, 272}, 143 | {45, 130, 166, 274}, 144 | {45, 131, 167, 275}, 145 | {46, 127, 172, 271}, 146 | {46, 128, 173, 272}, 147 | {46, 130, 175, 274}, 148 | {46, 133, 178, 277}, 149 | {47, 127, 181, 271}, 150 | {47, 128, 182, 272}, 151 | {47, 131, 185, 275}, 152 | {47, 133, 187, 277}, 153 | {48, 129, 192, 282}, 154 | {48, 130, 193, 283}, 155 | {48, 133, 196, 286}, 156 | {49, 132, 204, 285}, 157 | {50, 127, 208, 280}, 158 | {50, 129, 210, 282}, 159 | {50, 130, 211, 283}, 160 | {50, 133, 214, 286}, 161 | {51, 126, 216, 288}, 162 | {51, 127, 217, 289}, 163 | {51, 130, 220, 292}, 164 | {51, 133, 223, 295}, 165 | {52, 134, 233, 296}, 166 | {53, 126, 234, 288}, 167 | {53, 127, 235, 289}, 168 | {53, 128, 236, 290}, 169 | {53, 131, 239, 293}, 170 | {53, 133, 241, 295}, 171 | {54, 135, 162, 297}, 172 | {54, 137, 164, 299}, 173 | {54, 141, 168, 303}, 174 | {55, 137, 173, 299}, 175 | {55, 141, 177, 303}, 176 | {56, 139, 184, 301}, 177 | {57, 135, 189, 306}, 178 | {57, 141, 195, 312}, 179 | {57, 142, 196, 313}, 180 | {57, 143, 197, 314}, 181 | {58, 138, 201, 309}, 182 | {59, 137, 209, 308}, 183 | {59, 141, 213, 312}, 184 | {59, 142, 214, 313}, 185 | {59, 143, 215, 314}, 186 | {60, 140, 221, 320}, 187 | {61, 136, 226, 316}, 188 | {62, 135, 234, 315}, 189 | {62, 137, 236, 317}, 190 | {62, 141, 240, 321}, 191 | {62, 142, 241, 322}, 192 | {62, 143, 242, 323}, 193 | {63, 151, 169, 304}, 194 | {64, 146, 173, 299}, 195 | {64, 150, 177, 303}, 196 | {65, 152, 188, 305}, 197 | {66, 145, 190, 307}, 198 | {67, 146, 200, 308}, 199 | {67, 148, 202, 310}, 200 | {67, 149, 203, 311}, 201 | {68, 146, 209, 308}, 202 | {68, 148, 211, 310}, 203 | {68, 150, 213, 312}, 204 | {69, 144, 216, 315}, 205 | {69, 150, 222, 321}, 206 | {70, 144, 225, 315}, 207 | {70, 146, 227, 317}, 208 | {70, 147, 228, 318}, 209 | {70, 150, 231, 321}, 210 | {71, 144, 234, 315}, 211 | {71, 146, 236, 317}, 212 | {71, 147, 237, 318}, 213 | {71, 150, 240, 321}, 214 | {72, 153, 162, 297}, 215 | {72, 154, 163, 298}, 216 | {72, 155, 164, 299}, 217 | {72, 156, 165, 300}, 218 | {72, 158, 167, 302}, 219 | {72, 159, 168, 303}, 220 | {73, 154, 172, 298}, 221 | {73, 155, 173, 299}, 222 | {73, 159, 177, 303}, 223 | {74, 154, 181, 298}, 224 | {74, 155, 182, 299}, 225 | {74, 158, 185, 302}, 226 | {74, 159, 186, 303}, 227 | {75, 153, 189, 306}, 228 | {75, 158, 194, 311}, 229 | {75, 159, 195, 312}, 230 | {75, 160, 196, 313}, 231 | {75, 161, 197, 314}, 232 | {76, 155, 200, 308}, 233 | {76, 158, 203, 311}, 234 | {76, 160, 205, 313}, 235 | {76, 161, 206, 314}, 236 | {77, 155, 209, 308}, 237 | {77, 159, 213, 312}, 238 | {77, 160, 214, 313}, 239 | {77, 161, 215, 314}, 240 | {78, 153, 216, 315}, 241 | {78, 159, 222, 321}, 242 | {78, 160, 223, 322}, 243 | {79, 157, 229, 319}, 244 | {80, 153, 234, 315}, 245 | {80, 155, 236, 317}, 246 | {80, 156, 237, 318}, 247 | {80, 159, 240, 321}, 248 | {80, 160, 241, 322}, 249 | {80, 161, 242, 323}, 250 | }; -------------------------------------------------------------------------------- /puzzles/sudoku2.c: -------------------------------------------------------------------------------- 1 | uint16_t puzzle[206][4] = { 2 | {0, 85, 166, 247}, 3 | {0, 87, 168, 249}, 4 | {0, 89, 170, 251}, 5 | {1, 83, 173, 245}, 6 | {1, 87, 177, 249}, 7 | {1, 89, 179, 251}, 8 | {2, 84, 183, 246}, 9 | {3, 88, 196, 259}, 10 | {4, 82, 199, 253}, 11 | {4, 85, 202, 256}, 12 | {4, 86, 203, 257}, 13 | {4, 87, 204, 258}, 14 | {5, 82, 208, 253}, 15 | {5, 86, 212, 257}, 16 | {5, 89, 215, 260}, 17 | {6, 82, 217, 262}, 18 | {6, 85, 220, 265}, 19 | {6, 86, 221, 266}, 20 | {6, 89, 224, 269}, 21 | {7, 82, 226, 262}, 22 | {7, 85, 229, 265}, 23 | {7, 86, 230, 266}, 24 | {8, 81, 234, 261}, 25 | {9, 90, 162, 243}, 26 | {9, 94, 166, 247}, 27 | {9, 96, 168, 249}, 28 | {9, 97, 169, 250}, 29 | {9, 98, 170, 251}, 30 | {10, 91, 172, 244}, 31 | {11, 90, 180, 243}, 32 | {11, 94, 184, 247}, 33 | {11, 96, 186, 249}, 34 | {11, 97, 187, 250}, 35 | {11, 98, 188, 251}, 36 | {12, 94, 193, 256}, 37 | {12, 95, 194, 257}, 38 | {12, 98, 197, 260}, 39 | {13, 93, 201, 255}, 40 | {14, 90, 207, 252}, 41 | {14, 95, 212, 257}, 42 | {14, 98, 215, 260}, 43 | {15, 94, 220, 265}, 44 | {15, 95, 221, 266}, 45 | {15, 98, 224, 269}, 46 | {16, 92, 227, 263}, 47 | {17, 94, 238, 265}, 48 | {17, 98, 242, 269}, 49 | {18, 104, 167, 248}, 50 | {19, 99, 171, 243}, 51 | {19, 106, 178, 250}, 52 | {19, 107, 179, 251}, 53 | {20, 99, 180, 243}, 54 | {20, 103, 184, 247}, 55 | {20, 106, 187, 250}, 56 | {20, 107, 188, 251}, 57 | {21, 100, 190, 253}, 58 | {21, 103, 193, 256}, 59 | {21, 107, 197, 260}, 60 | {22, 99, 198, 252}, 61 | {22, 100, 199, 253}, 62 | {22, 103, 202, 256}, 63 | {23, 101, 209, 254}, 64 | {24, 105, 222, 267}, 65 | {25, 100, 226, 262}, 66 | {25, 103, 229, 265}, 67 | {25, 106, 232, 268}, 68 | {26, 100, 235, 262}, 69 | {26, 102, 237, 264}, 70 | {26, 103, 238, 265}, 71 | {26, 107, 242, 269}, 72 | {27, 110, 164, 272}, 73 | {28, 108, 171, 270}, 74 | {28, 114, 177, 276}, 75 | {28, 115, 178, 277}, 76 | {28, 116, 179, 278}, 77 | {29, 108, 180, 270}, 78 | {29, 114, 186, 276}, 79 | {29, 115, 187, 277}, 80 | {29, 116, 188, 278}, 81 | {30, 109, 190, 280}, 82 | {30, 113, 194, 284}, 83 | {30, 116, 197, 287}, 84 | {31, 108, 198, 279}, 85 | {31, 109, 199, 280}, 86 | {31, 113, 203, 284}, 87 | {31, 115, 205, 286}, 88 | {32, 112, 211, 283}, 89 | {33, 111, 219, 291}, 90 | {34, 108, 225, 288}, 91 | {34, 109, 226, 289}, 92 | {34, 113, 230, 293}, 93 | {34, 114, 231, 294}, 94 | {35, 109, 235, 289}, 95 | {35, 114, 240, 294}, 96 | {36, 117, 162, 270}, 97 | {36, 121, 166, 274}, 98 | {36, 123, 168, 276}, 99 | {36, 124, 169, 277}, 100 | {37, 122, 176, 275}, 101 | {38, 117, 180, 270}, 102 | {38, 121, 184, 274}, 103 | {38, 123, 186, 276}, 104 | {38, 124, 187, 277}, 105 | {39, 118, 190, 280}, 106 | {39, 120, 192, 282}, 107 | {40, 119, 200, 281}, 108 | {41, 117, 207, 279}, 109 | {41, 118, 208, 280}, 110 | {41, 120, 210, 282}, 111 | {41, 124, 214, 286}, 112 | {42, 117, 216, 288}, 113 | {42, 118, 217, 289}, 114 | {42, 121, 220, 292}, 115 | {43, 125, 233, 296}, 116 | {44, 118, 235, 289}, 117 | {44, 121, 238, 292}, 118 | {44, 123, 240, 294}, 119 | {45, 126, 162, 270}, 120 | {45, 130, 166, 274}, 121 | {45, 134, 170, 278}, 122 | {46, 126, 171, 270}, 123 | {46, 129, 174, 273}, 124 | {46, 134, 179, 278}, 125 | {47, 127, 181, 271}, 126 | {48, 132, 195, 285}, 127 | {49, 126, 198, 279}, 128 | {49, 131, 203, 284}, 129 | {50, 126, 207, 279}, 130 | {50, 129, 210, 282}, 131 | {50, 131, 212, 284}, 132 | {50, 134, 215, 287}, 133 | {51, 126, 216, 288}, 134 | {51, 128, 218, 290}, 135 | {51, 130, 220, 292}, 136 | {51, 131, 221, 293}, 137 | {52, 126, 225, 288}, 138 | {52, 130, 229, 292}, 139 | {52, 131, 230, 293}, 140 | {53, 133, 241, 295}, 141 | {54, 136, 163, 298}, 142 | {54, 141, 168, 303}, 143 | {54, 142, 169, 304}, 144 | {54, 143, 170, 305}, 145 | {55, 141, 177, 303}, 146 | {55, 142, 178, 304}, 147 | {55, 143, 179, 305}, 148 | {56, 137, 182, 299}, 149 | {57, 135, 189, 306}, 150 | {58, 136, 199, 307}, 151 | {58, 139, 202, 310}, 152 | {58, 142, 205, 313}, 153 | {59, 136, 208, 307}, 154 | {59, 138, 210, 309}, 155 | {59, 142, 214, 313}, 156 | {60, 136, 217, 316}, 157 | {60, 139, 220, 319}, 158 | {60, 143, 224, 323}, 159 | {61, 136, 226, 316}, 160 | {61, 139, 229, 319}, 161 | {61, 141, 231, 321}, 162 | {62, 140, 239, 320}, 163 | {63, 144, 162, 297}, 164 | {63, 145, 163, 298}, 165 | {63, 150, 168, 303}, 166 | {63, 151, 169, 304}, 167 | {64, 148, 175, 301}, 168 | {65, 144, 180, 297}, 169 | {65, 149, 185, 302}, 170 | {65, 150, 186, 303}, 171 | {65, 151, 187, 304}, 172 | {66, 145, 190, 307}, 173 | {66, 146, 191, 308}, 174 | {66, 149, 194, 311}, 175 | {67, 152, 206, 314}, 176 | {68, 145, 208, 307}, 177 | {68, 149, 212, 311}, 178 | {68, 151, 214, 313}, 179 | {69, 144, 216, 315}, 180 | {69, 145, 217, 316}, 181 | {69, 146, 218, 317}, 182 | {70, 147, 228, 318}, 183 | {71, 145, 235, 316}, 184 | {71, 146, 236, 317}, 185 | {71, 150, 240, 321}, 186 | {72, 156, 165, 300}, 187 | {73, 153, 171, 297}, 188 | {73, 161, 179, 305}, 189 | {74, 153, 180, 297}, 190 | {74, 158, 185, 302}, 191 | {74, 161, 188, 305}, 192 | {75, 154, 190, 307}, 193 | {75, 155, 191, 308}, 194 | {75, 157, 193, 310}, 195 | {75, 158, 194, 311}, 196 | {76, 154, 199, 307}, 197 | {76, 157, 202, 310}, 198 | {76, 158, 203, 311}, 199 | {77, 159, 213, 312}, 200 | {78, 160, 223, 322}, 201 | {79, 153, 225, 315}, 202 | {79, 154, 226, 316}, 203 | {79, 157, 229, 319}, 204 | {80, 154, 235, 316}, 205 | {80, 155, 236, 317}, 206 | {80, 157, 238, 319}, 207 | {80, 161, 242, 323}, 208 | } -------------------------------------------------------------------------------- /puzzles/unsolvable_2x2_sudoku.c: -------------------------------------------------------------------------------- 1 | uint16_t puzzle[32][4] = { 2 | {0, 17, 33, 49}, 3 | {0, 19, 35, 51}, 4 | {1, 17, 37, 49}, 5 | {1, 19, 39, 51}, 6 | {2, 16, 40, 52}, 7 | {3, 18, 46, 54}, 8 | {4, 21, 33, 49}, 9 | {4, 23, 35, 51}, 10 | {5, 20, 36, 48}, 11 | {5, 21, 37, 49}, 12 | {5, 22, 38, 50}, 13 | {5, 23, 39, 51}, 14 | {6, 21, 41, 53}, 15 | {6, 23, 43, 55}, 16 | {7, 21, 45, 53}, 17 | {7, 23, 47, 55}, 18 | {8, 26, 34, 58}, 19 | {9, 25, 37, 57}, 20 | {9, 27, 39, 59}, 21 | {10, 25, 41, 61}, 22 | {10, 27, 43, 63}, 23 | {11, 24, 44, 60}, 24 | {11, 25, 45, 61}, 25 | {11, 27, 47, 63}, 26 | {12, 28, 32, 56}, 27 | {13, 29, 37, 57}, 28 | {13, 31, 39, 59}, 29 | {14, 29, 41, 61}, 30 | {14, 30, 42, 62}, 31 | {14, 31, 43, 63}, 32 | {15, 29, 45, 61}, 33 | {15, 31, 47, 63}, 34 | }; -------------------------------------------------------------------------------- /reductions/pentomino_reduction.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | import math 3 | from copy import deepcopy 4 | from util import ExactCoverProblem 5 | 6 | 7 | 8 | class PentominoBitmasks: 9 | def __init__(self): 10 | self.bitmask_list = [] 11 | self.create_bitmasks() 12 | 13 | @staticmethod 14 | def reflect(tile): 15 | return [row[::-1] for row in tile] 16 | 17 | @staticmethod 18 | def rotate_ccw(tile): 19 | n = len(tile) 20 | m = len(tile[0]) 21 | rotated = [[tile[r][m-1-c] for r in range(n)] for c in range(m)] 22 | return rotated 23 | 24 | 25 | def create_bitmasks(self): 26 | tiles = [[[1,1,1,1,1]], 27 | [[1,1,1], [0,1,1]], 28 | [[1,1,1,1], [0,0,0,1]], 29 | [[0,1,1], [1,1,0], [0,1,0]], 30 | [[1,1,1,0],[0,0,1,1]], 31 | [[1,1,1],[0,1,0],[0,1,0]], 32 | [[1,0,1], [1,1,1]], 33 | [[1,0,0], [1,0,0], [1,1,1]], 34 | [[0,0,1], [0,1,1], [1,1,0]], 35 | [[0,1,0], [1,1,1], [0,1,0]], 36 | [[1,1,1,1], [0,1,0,0]], 37 | [[1,1,0], [0,1,0], [0,1,1]] 38 | ] 39 | 40 | r = lambda t: self.rotate_ccw(t) 41 | s = lambda t: self.reflect(t) 42 | 43 | for n, tile in enumerate(tiles): 44 | if n in [0]: 45 | tileset = [tile, r(tile)] 46 | elif n in [5,6,7,8] : 47 | tileset = [tile, r(tile), r(r(tile)), r(r(r(tile)))] 48 | elif n in [9]: 49 | tileset = [tile] 50 | elif n in [11]: 51 | tileset = [tile, r(tile), s(tile), r(s(tile))] 52 | else : 53 | tileset = [tile, r(tile), r(r(tile)), r(r(r(tile))), s(tile), r(s(tile)), r(r(s(tile))), r(r(r(s(tile))))] 54 | # print(f"{n} : {len(tileset)}") 55 | self.bitmask_list.append(tileset) 56 | 57 | 58 | 59 | 60 | class PentominoReduction: 61 | def __init__(self, puzzle, pieces): 62 | # puzzle is n x m of ints in {1, 0} 63 | # '1' indicates cell is available 64 | # pieces is a length 12 array containing the number of pieces of each pentomino 65 | # [O, P, Q, R, S, T, U, V, W, X, Y ,Z] 66 | # See: Conway labeling scheme 67 | self.puzzle = puzzle 68 | self.n = len(puzzle) 69 | self.m = len(puzzle[0]) 70 | self.pieces = pieces 71 | self.piece_count = sum(pieces) 72 | self.cart_to_lbl = None 73 | self.lbl_to_cart = None 74 | self.tile_bitmasks = PentominoBitmasks().bitmask_list 75 | self.setcoverrowlen = 0 76 | # we label the cells from top to bottom, left to right to compress representation. 77 | # this requires a mapping from cell coordinates to index 78 | self.init_cart_to_lbl() 79 | 80 | self.collection = [] 81 | self.gen_sets() 82 | 83 | 84 | def init_cart_to_lbl(self): 85 | counter = 0 86 | cart_to_lbl = dict() 87 | lbl_to_cart = dict() 88 | for r, row in enumerate(self.puzzle): 89 | for c, cell in enumerate(row): 90 | if cell == 1: 91 | cart_to_lbl[(r,c)] = counter 92 | lbl_to_cart[counter] = (r,c) 93 | counter += 1 94 | self.cart_to_lbl = cart_to_lbl 95 | self.lbl_to_cart = lbl_to_cart 96 | self.setcoverrowlen = len(self.cart_to_lbl) 97 | 98 | 99 | def print_cell_map(self): 100 | for r in range(self.n): 101 | for c in range(self.m): 102 | try: 103 | print(self.cart_to_lbl[(r,c)] %10, end="") 104 | except: 105 | print('#', end="") 106 | print() 107 | 108 | 109 | def gen_sets_for_piece(self, pc_id): 110 | sets = [] 111 | for mask in self.tile_bitmasks[pc_id]: 112 | maskn = len(mask) 113 | maskm = len(mask[0]) 114 | 115 | for r in range(self.n-maskn+1): 116 | for c in range(self.m-maskm+1): 117 | overlap = False 118 | thisset = [] 119 | 120 | for i in range (maskn): 121 | for j in range (maskm): 122 | if mask[i][j] == 0: 123 | continue 124 | elif mask[i][j] == 1 and self.puzzle[i+r][j+c] == 0: 125 | overlap = True 126 | break 127 | else: 128 | thisset.append(self.cart_to_lbl[(i+r, j+c)]) 129 | if overlap: 130 | break 131 | 132 | if not overlap: 133 | sets.append(thisset) 134 | return sets 135 | 136 | 137 | def gen_sets(self): 138 | ctr = 0 139 | for id in range(len(self.pieces)): 140 | templ = self.gen_sets_for_piece(id) 141 | for _ in range(self.pieces[id]): 142 | chunk = list(map(lambda x : x+[self.setcoverrowlen + ctr], templ)) 143 | 144 | self.collection += chunk 145 | ctr += 1 146 | 147 | 148 | def to_exact_cover_sets(self): 149 | return self.collection, self.setcoverrowlen + self.piece_count 150 | 151 | def dump(self): 152 | grid = [] 153 | for r, row in enumerate(self.puzzle): 154 | out = "" 155 | for c, cell in enumerate(row): 156 | if cell == 0: 157 | out += '#' 158 | else: 159 | out += '.' 160 | grid.append(out) 161 | 162 | # print ('\n'.join(grid)) 163 | 164 | for s in self.collection: 165 | newgrid = [] 166 | coords = [self.lbl_to_cart[s[i]] for i in range(5)] 167 | for r in range(self.n): 168 | out = "" 169 | for c in range(self.m): 170 | if len(coords) > 0 and coords[0] == (r,c): 171 | out += '#' 172 | coords.pop(0) 173 | else: 174 | out += grid[r][c] 175 | newgrid.append(out) 176 | 177 | print('\n'.join(newgrid)) 178 | print() -------------------------------------------------------------------------------- /reductions/sudoku_encryption.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | from sudoku_reduction import SudokuReduction 3 | from encrypt import BitEncryptor 4 | from mmap_classes import MMap 5 | from Crypto.Util import number 6 | 7 | class SudokuEncryption: 8 | 9 | def __init__(self, puzzle): 10 | assert len(puzzle) == len(puzzle[0]), "not a valid puzzle" 11 | self.puzzle = puzzle 12 | self.n = len(puzzle) 13 | self.bit_enc = None 14 | self.reducer = None 15 | 16 | def encrypt(self, b: bool): 17 | # convert puzzle to exact cover 18 | reducer = SudokuReduction(self.puzzle) 19 | exact_cover = reducer.to_exact_cover() 20 | 21 | self.bit_enc = BitEncryptor(exact_cover) 22 | self.reducer = reducer 23 | return (*self.bit_enc.print_keys(), self.bit_enc.encrypt(b)) 24 | 25 | def decrypt(self, ct, solution, mmap): 26 | # # check that we've setup encryption 27 | # assert isinstance(self.bit_enc, BitEncryptor) 28 | # assert len(solution) == len(self.puzzle) 29 | # assert len(solution[0]) == len(self.puzzle[0]) 30 | # # check that puzzle is a subset of solution 31 | # for i, j in itertools.product(range(len(solution)), range(len(solution))): 32 | # if self.puzzle[i][j] is not None: 33 | # assert solution[i][j] == self.puzzle[i][j] 34 | 35 | # now convert to set indices 36 | indices = [] 37 | n = len(solution) 38 | for i in range(n): 39 | for j in range(n): 40 | indices.append(i * n ** 2 + j * n + solution[i][j]) 41 | print(indices) 42 | total = [0 for _ in range(4 * n ** 2)] 43 | for i in indices: 44 | print(self.reducer.collection[i]) 45 | total = list(map(sum, zip(total, self.reducer.collection[i]))) 46 | print(total) 47 | return BitEncryptor.static_decrypt(ct, indices, mmap) 48 | 49 | @staticmethod 50 | def static_decrypt(ct, solution, mmap): 51 | indices = [] 52 | n = len(solution) 53 | for i in range(n): 54 | for j in range(n): 55 | indices.append(i * n ** 2 + j * n + solution[i][j]) 56 | 57 | return BitEncryptor.static_decrypt(ct, indices, mmap) 58 | -------------------------------------------------------------------------------- /reductions/sudoku_reduction.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | import math 3 | from typing import Collection 4 | from util import ExactCoverProblem 5 | 6 | 7 | class SudokuReduction: 8 | # row, col, val in 0-(n-1) 9 | # block num encoding: (row, col, val) -> row * n^2 + col * n + val 10 | 11 | # constraint encoding (4x nxn): 12 | # nxnblock encoding: (row, col) -> row * n + col 13 | # row encoding: (row, val) -> row * n + val 14 | # col encoding: (col, val) -> col * n + val 15 | # bigblock encoding: (blockrow, blockcol, val) -> (sqrt(n) * blockrow + blockcol) * n + val 16 | 17 | def __init__(self, puzzle): 18 | # puzzle is n x n of ints from 0 to (n-1) 19 | # None indicates no value in cell 20 | self.puzzle = puzzle 21 | self.n = len(puzzle) 22 | self.b = int(self.n ** 0.5) 23 | self.collection = [[0] for _ in range(self.n ** 3)] 24 | self.gen_sets() 25 | self.trim_sets() 26 | 27 | def gen_sets(self): 28 | for row, col, val in itertools.product(range(self.n), range(self.n), range(self.n)): 29 | offset = self.n ** 2 30 | # create the row for this thing 31 | st = [0 for _ in range(4 * self.n ** 2)] 32 | 33 | # one number per cell constraint 34 | st[self.n * row + col] = 1 35 | # one of this number per row constraint 36 | st[offset + row * self.n + val] = 1 37 | # one of this number over column constraint 38 | st[offset * 2 + col * self.n + val] = 1 39 | # one of this number per block constraint 40 | st[int(offset * 3 + ((row // self.n ** 0.5) * self.n ** 41 | 0.5 + (col // self.n ** 0.5)) * self.n + val)] = 1 42 | 43 | self.collection[row * self.n ** 2 + col * self.n + val] = st 44 | 45 | def trim_sets(self): 46 | # set those that are invalid (meaning they have a 1 in the same column that a fixed 47 | # number has a 1) to be empty 48 | # this means to cover the entry in those spots, they must use the fixed number 49 | bad_indices = set() 50 | for row in range(self.n): 51 | for col in range(self.n): 52 | if self.puzzle[row][col] is None: 53 | continue 54 | # set every set that shares a 1 in any column with this one to be empty 55 | # deal with first set, so zero out every other row corresponding to a number in this cell 56 | # means every block with the same row col values 57 | bad_indices.update(set(map(lambda v: self.to_index(row, col, v), range(self.n)))) 58 | # second set, same value and same row 59 | bad_indices.update(set(map(lambda c: self.to_index(row, c, self.puzzle[row][col]), range(self.n)))) 60 | # third set, same value and same column 61 | bad_indices.update(set(map(lambda r: self.to_index(r, col, self.puzzle[row][col]), range(self.n)))) 62 | # last set, same block 63 | bad_indices.update(set(map(lambda x: self.to_index((row // self.b) * self.b + x % self.b, (col // self.b) * self.b + x // self.b, self.puzzle[row][col]), range(self.n)))) 64 | # add back the correct set itself 65 | bad_indices.remove(row * self.n ** 2 + col * self.n + self.puzzle[row][col]) 66 | # print(bad_indices) 67 | # now set all bad_indices to be empty lists 68 | for i in bad_indices: 69 | self.collection[i] = [0 for _ in range(4 * self.n ** 2)] 70 | 71 | def to_index(self, row, col, val): 72 | return int(row * self.n ** 2 + col * self.n + val) 73 | 74 | def to_exact_cover(self): 75 | def bin_to_numeric(ls): 76 | return [i for i, b in enumerate(ls) if b] 77 | subsets = list(map(bin_to_numeric, self.collection)) 78 | return ExactCoverProblem(4 * self.n ** 2, *subsets) 79 | 80 | def to_exact_cover_sets(self): 81 | def bin_to_numeric(ls): 82 | return [i for i, b in enumerate(ls) if b] 83 | subsets = list(map(bin_to_numeric, self.collection)) 84 | return subsets, 4 * self.n ** 2 85 | 86 | def __str__(self): 87 | ml = len(str(self.n))*3+6 88 | offset = self.n**2 89 | 90 | def str_coords(r, c, v): 91 | coords = f"({r}, {c}, {v})" 92 | return coords.rjust(ml, " ") 93 | 94 | def clean(num): 95 | if num == 1: 96 | return "1" 97 | else: 98 | return " " 99 | 100 | def str_constraints(r, c, v): 101 | rownum = self.n**2*r + self.n*c + v 102 | row = '|' + '|'.join([' '.join(map(clean, [(self.collection)[rownum][i+k*offset] for i in range(self.n**2)])) for k in range(4)]) + '|' 103 | return row 104 | 105 | header = str_coords("r", "c", "v") + "|" + "cell".ljust(2*offset-1, " ") + "|" + "row".ljust( 106 | 2*offset-1, " ") + "|" + "col".ljust(2*offset-1, " ") + "|" + "block".ljust(2*offset-1, " ") + "|\n" 107 | return header+"\n".join([str_coords(r, c, v)+str_constraints(r, c, v) for r, c, v in itertools.product(range(self.n), range(self.n), range(self.n))]) 108 | -------------------------------------------------------------------------------- /src/clt.c: -------------------------------------------------------------------------------- 1 | #include "clt13.h" 2 | #include "clt_elem.h" 3 | #include "crt_tree.h" 4 | #include "estimates.h" 5 | #include "utils.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* etap is the size of the factors in the p_i's when using the composite ps 17 | * optimization. We default this to 420, as is done in 18 | * https://github.com/tlepoint/new-multilinear-maps/blob/master/generate_pp.cpp */ 19 | #define ETAP_DEFAULT 420 20 | 21 | struct clt_state_t { 22 | size_t n; /* number of slots */ 23 | size_t nzs; /* number of z's in the index set */ 24 | size_t rho; /* bitsize of randomness */ 25 | size_t nu; /* number of most-significant-bits to extract */ 26 | mpz_t *gs; /* plaintext moduli */ 27 | aes_randstate_t *rngs; /* random number generators (one per slot) */ 28 | mpz_t x0; 29 | mpz_t pzt; /* zero testing parameter */ 30 | mpz_t *zinvs; /* z inverses */ 31 | union { 32 | crt_tree *crt; 33 | mpz_t *crt_coeffs; 34 | }; 35 | size_t flags; 36 | }; 37 | 38 | struct clt_pp_t { 39 | mpz_t x0; 40 | mpz_t pzt; /* zero testing parameter */ 41 | size_t nu; /* number of most-significant-bits to extract */ 42 | }; 43 | 44 | int 45 | clt_elem_add(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, const clt_elem_t *b) 46 | { 47 | mpz_add(rop->elem, a->elem, b->elem); 48 | mpz_mod(rop->elem, rop->elem, pp->x0); 49 | return CLT_OK; 50 | } 51 | 52 | int 53 | clt_elem_sub(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, const clt_elem_t *b) 54 | { 55 | mpz_sub(rop->elem, a->elem, b->elem); 56 | mpz_mod(rop->elem, rop->elem, pp->x0); 57 | return CLT_OK; 58 | } 59 | 60 | int 61 | clt_elem_mul(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, const clt_elem_t *b) 62 | { 63 | mpz_mul(rop->elem, a->elem, b->elem); 64 | mpz_mod(rop->elem, rop->elem, pp->x0); 65 | return CLT_OK; 66 | } 67 | 68 | int 69 | clt_elem_mul_ui(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, unsigned int b) 70 | { 71 | mpz_mul_ui(rop->elem, a->elem, b); 72 | mpz_mod(rop->elem, rop->elem, pp->x0); 73 | return CLT_OK; 74 | } 75 | 76 | clt_state_t * 77 | clt_state_fread(FILE *fp) 78 | { 79 | clt_state_t *s; 80 | 81 | if ((s = calloc(1, sizeof s[0])) == NULL) return NULL; 82 | if (size_t_fread(fp, &s->flags) == CLT_ERR) goto error; 83 | if (size_t_fread(fp, &s->n) == CLT_ERR) goto error; 84 | if (size_t_fread(fp, &s->nzs) == CLT_ERR) goto error; 85 | if (size_t_fread(fp, &s->rho) == CLT_ERR) goto error; 86 | if (size_t_fread(fp, &s->nu) == CLT_ERR) goto error; 87 | mpz_init(s->x0); 88 | if (mpz_fread(s->x0, fp) == CLT_ERR) goto error; 89 | mpz_init(s->pzt); 90 | if (mpz_fread(s->pzt, fp) == CLT_ERR) goto error; 91 | s->gs = mpz_vector_new(s->n); 92 | if (mpz_vector_fread(s->gs, s->n, fp) == CLT_ERR) goto error; 93 | s->zinvs = mpz_vector_new(s->nzs); 94 | if (mpz_vector_fread(s->zinvs, s->nzs, fp) == CLT_ERR) goto error; 95 | if (s->flags & CLT_FLAG_OPT_CRT_TREE) { 96 | if ((s->crt = crt_tree_fread(fp, s->n)) == NULL) goto error; 97 | } else { 98 | s->crt_coeffs = mpz_vector_new(s->n); 99 | if (mpz_vector_fread(s->crt_coeffs, s->n, fp) == CLT_ERR) goto error; 100 | } 101 | s->rngs = calloc(max(s->n, s->nzs), sizeof s->rngs[0]); 102 | for (size_t i = 0; i < max(s->n, s->nzs); ++i) 103 | if (aes_randstate_fread(s->rngs[i], fp) == AESRAND_ERR) goto error; 104 | return s; 105 | error: 106 | free(s); 107 | return NULL; 108 | } 109 | 110 | int 111 | clt_state_fwrite(clt_state_t *const s, FILE *const fp) 112 | { 113 | if (s == NULL || fp == NULL) 114 | return CLT_ERR; 115 | if (size_t_fwrite(fp, s->flags) == CLT_ERR) goto error; 116 | if (size_t_fwrite(fp, s->n) == CLT_ERR) goto error; 117 | if (size_t_fwrite(fp, s->nzs) == CLT_ERR) goto error; 118 | if (size_t_fwrite(fp, s->rho) == CLT_ERR) goto error; 119 | if (size_t_fwrite(fp, s->nu) == CLT_ERR) goto error; 120 | if (mpz_fwrite(s->x0, fp) == CLT_ERR) goto error; 121 | if (mpz_fwrite(s->pzt, fp) == CLT_ERR) goto error; 122 | if (mpz_vector_fwrite(s->gs, s->n, fp) == CLT_ERR) goto error; 123 | if (mpz_vector_fwrite(s->zinvs, s->nzs, fp) == CLT_ERR) goto error; 124 | if (s->flags & CLT_FLAG_OPT_CRT_TREE) { 125 | if (crt_tree_fwrite(fp, s->crt, s->n) == CLT_ERR) goto error; 126 | } else { 127 | if (mpz_vector_fwrite(s->crt_coeffs, s->n, fp) == CLT_ERR) goto error; 128 | } 129 | for (size_t i = 0; i < max(s->n, s->nzs); ++i) 130 | aes_randstate_fwrite(s->rngs[i], fp); 131 | return CLT_OK; 132 | error: 133 | return CLT_ERR; 134 | } 135 | 136 | clt_pp_t * 137 | clt_pp_new(const clt_state_t *mmap) 138 | { 139 | clt_pp_t *pp; 140 | 141 | if ((pp = calloc(1, sizeof pp[0])) == NULL) 142 | return NULL; 143 | mpz_inits(pp->x0, pp->pzt, NULL); 144 | mpz_set(pp->x0, mmap->x0); 145 | mpz_set(pp->pzt, mmap->pzt); 146 | pp->nu = mmap->nu; 147 | return pp; 148 | } 149 | 150 | void 151 | clt_pp_free(clt_pp_t *pp) 152 | { 153 | mpz_clears(pp->x0, pp->pzt, NULL); 154 | free(pp); 155 | } 156 | 157 | clt_pp_t * 158 | clt_pp_fread(FILE *fp) 159 | { 160 | clt_pp_t *pp; 161 | 162 | if ((pp = calloc(1, sizeof pp[0])) == NULL) 163 | return NULL; 164 | mpz_inits(pp->x0, pp->pzt, NULL); 165 | if (size_t_fread(fp, &pp->nu) == CLT_ERR) goto cleanup; 166 | if (mpz_fread(pp->x0, fp) == CLT_ERR) goto cleanup; 167 | if (mpz_fread(pp->pzt, fp) == CLT_ERR) goto cleanup; 168 | return pp; 169 | cleanup: 170 | clt_pp_free(pp); 171 | return NULL; 172 | } 173 | 174 | int 175 | clt_pp_fwrite(clt_pp_t *pp, FILE *fp) 176 | { 177 | if (size_t_fwrite(fp, pp->nu) == CLT_ERR) goto cleanup; 178 | if (mpz_fwrite(pp->x0, fp) == CLT_ERR) goto cleanup; 179 | if (mpz_fwrite(pp->pzt, fp) == CLT_ERR) goto cleanup; 180 | return CLT_OK; 181 | cleanup: 182 | return CLT_ERR; 183 | } 184 | 185 | static int 186 | generate_primes_composite_ps(mpz_t *v, aes_randstate_t *rngs, size_t n, size_t eta, bool verbose) 187 | { 188 | int count = 0; 189 | double start = current_time(); 190 | size_t etap = ETAP_DEFAULT; 191 | if (eta > 350) 192 | /* TODO: change how we set etap, should be resistant to factoring x_0 */ 193 | for (/* */; eta % etap < 350; etap++) 194 | ; 195 | if (verbose) { 196 | fprintf(stderr, " [eta_p: %lu] ", etap); 197 | } 198 | size_t nchunks = eta / etap; 199 | size_t leftover = eta - nchunks * etap; 200 | if (verbose) { 201 | fprintf(stderr, "[nchunks=%lu leftover=%lu]\n", nchunks, leftover); 202 | print_progress(count, n); 203 | } 204 | #pragma omp parallel for 205 | for (size_t i = 0; i < n; i++) { 206 | mpz_t p_unif; 207 | mpz_set_ui(v[i], 1); 208 | mpz_init(p_unif); 209 | /* generate a p_i */ 210 | for (size_t j = 0; j < nchunks; j++) { 211 | mpz_prime(p_unif, rngs[i], etap); 212 | mpz_mul(v[i], v[i], p_unif); 213 | } 214 | mpz_prime(p_unif, rngs[i], leftover); 215 | mpz_mul(v[i], v[i], p_unif); 216 | mpz_clear(p_unif); 217 | 218 | if (verbose) { 219 | #pragma omp critical 220 | print_progress(++count, n); 221 | } 222 | } 223 | if (verbose) { 224 | fprintf(stderr, "\t[%.2fs]\n", current_time() - start); 225 | } 226 | return CLT_OK; 227 | } 228 | 229 | static inline size_t 230 | max3(size_t a, size_t b, size_t c) 231 | { 232 | return a >= b && a >= c ? a : b >= a && b >= c ? b : c; 233 | } 234 | 235 | clt_state_t * 236 | clt_state_new(const clt_params_t *params, const clt_opt_params_t *opts, 237 | size_t ncores, size_t flags, aes_randstate_t rng) 238 | { 239 | clt_state_t *s; 240 | size_t alpha, beta, eta, rho_f; 241 | mpz_t *ps = NULL, *zs; 242 | double start_time = 0.0; 243 | const bool verbose = flags & CLT_FLAG_VERBOSE; 244 | const size_t slots = opts ? opts->slots : 0; 245 | 246 | if ((s = calloc(1, sizeof s[0])) == NULL) 247 | return NULL; 248 | 249 | if (ncores == 0) 250 | ncores = sysconf(_SC_NPROCESSORS_ONLN); 251 | (void) omp_set_num_threads(ncores); 252 | 253 | /* calculate CLT parameters */ 254 | s->nzs = params->nzs; 255 | alpha = params->lambda; /* bitsize of g_i primes */ 256 | beta = params->lambda; /* bitsize of h_i entries */ 257 | s->rho = params->lambda; /* bitsize of randomness */ 258 | rho_f = params->kappa * (s->rho + alpha); /* max bitsize of r_i's */ 259 | eta = rho_f + alpha + beta + 9; /* bitsize of primes p_i */ 260 | s->n = max(estimate_n(params->lambda, eta, flags), slots); /* number of primes */ 261 | eta = rho_f + alpha + beta + nb_of_bits(s->n) + 9; /* bitsize of primes p_i */ 262 | s->nu = eta - beta - rho_f - nb_of_bits(s->n) - 3; /* number of msbs to extract */ 263 | s->flags = flags; 264 | 265 | /* Loop until a fixed point reached for choosing eta, n, and nu */ 266 | { 267 | size_t old_eta = 0, old_n = 0, old_nu = 0; 268 | int i = 0; 269 | for (; i < 10 && (old_eta != eta || old_n != s->n || old_nu != s->nu); 270 | ++i) { 271 | old_eta = eta, old_n = s->n, old_nu = s->nu; 272 | eta = rho_f + alpha + beta + nb_of_bits(s->n) + 9; 273 | s->n = max(estimate_n(params->lambda, eta, flags), slots); 274 | s->nu = eta - beta - rho_f - nb_of_bits(s->n) - 3; 275 | } 276 | 277 | if (i == 10 && (old_eta != eta || old_n != s->n || old_nu != s->nu)) { 278 | fprintf(stderr, "error: unable to find valid η, n, and ν choices\n"); 279 | free(s); 280 | return NULL; 281 | } 282 | } 283 | 284 | /* Make sure the proper bounds are hit [CLT13, Lemma 8] */ 285 | assert(s->nu >= alpha + 6); 286 | assert(beta + alpha + rho_f + nb_of_bits(s->n) <= eta - 9); 287 | assert(s->n >= slots); 288 | 289 | if (verbose) { 290 | fprintf(stderr, " λ: %ld\n", params->lambda); 291 | fprintf(stderr, " κ: %ld\n", params->kappa); 292 | fprintf(stderr, " α: %ld\n", alpha); 293 | fprintf(stderr, " β: %ld\n", beta); 294 | fprintf(stderr, " η: %ld\n", eta); 295 | fprintf(stderr, " ν: %ld\n", s->nu); 296 | fprintf(stderr, " ρ: %ld\n", s->rho); 297 | fprintf(stderr, " ρ_f: %ld\n", rho_f); 298 | fprintf(stderr, " n: %ld\n", s->n); 299 | fprintf(stderr, " nzs: %ld\n", s->nzs); 300 | fprintf(stderr, " ncores: %ld\n", ncores); 301 | fprintf(stderr, " Flags: \n"); 302 | if (s->flags & CLT_FLAG_OPT_CRT_TREE) 303 | fprintf(stderr, " CRT TREE\n"); 304 | if (s->flags & CLT_FLAG_OPT_PARALLEL_ENCODE) 305 | fprintf(stderr, " PARALLEL ENCODE\n"); 306 | if (s->flags & CLT_FLAG_OPT_COMPOSITE_PS) 307 | fprintf(stderr, " COMPOSITE PS\n"); 308 | if (s->flags & CLT_FLAG_SEC_IMPROVED_BKZ) 309 | fprintf(stderr, " IMPROVED BKZ\n"); 310 | if (s->flags & CLT_FLAG_SEC_CONSERVATIVE) 311 | fprintf(stderr, " CONSERVATIVE\n"); 312 | } 313 | 314 | /* Generate randomness for each core */ 315 | s->rngs = calloc(max(s->n, s->nzs), sizeof s->rngs[0]); 316 | for (size_t i = 0; i < max(s->n, s->nzs); ++i) { 317 | unsigned char *buf; 318 | size_t nbytes; 319 | 320 | buf = random_aes(rng, 128, &nbytes); 321 | aes_randinit_seedn(s->rngs[i], (char *) buf, nbytes, NULL, 0); 322 | free(buf); 323 | } 324 | 325 | /* Generate "plaintext" moduli */ 326 | s->gs = mpz_vector_new(s->n); 327 | if (verbose) 328 | fprintf(stderr, " Generating g_i's:\n"); 329 | if (opts && opts->moduli && opts->nmoduli) { 330 | for (size_t i = 0; i < opts->nmoduli; ++i) 331 | mpz_set(s->gs[i], opts->moduli[i]); 332 | generate_primes(s->gs + opts->nmoduli, s->rngs, s->n - opts->nmoduli, alpha, verbose); 333 | } else { 334 | generate_primes(s->gs, s->rngs, s->n, alpha, verbose); 335 | } 336 | 337 | mpz_init_set_ui(s->x0, 1); 338 | 339 | if (!(s->flags & CLT_FLAG_OPT_CRT_TREE)) { 340 | s->crt_coeffs = mpz_vector_new(s->n); 341 | } 342 | 343 | /* Generate "ciphertext" moduli */ 344 | if (verbose) 345 | fprintf(stderr, " Generating p_i's:\n"); 346 | ps = mpz_vector_new(s->n); 347 | generate_ps: 348 | if (s->flags & CLT_FLAG_OPT_COMPOSITE_PS) { 349 | generate_primes_composite_ps(ps, s->rngs, s->n, eta, verbose); 350 | } else { 351 | generate_primes(ps, s->rngs, s->n, eta, verbose); 352 | } 353 | 354 | /* Compute product if "ciphertext" moduli */ 355 | if (s->flags & CLT_FLAG_OPT_CRT_TREE) { 356 | start_time = current_time(); 357 | if (verbose) 358 | fprintf(stderr, " Generating CRT tree: "); 359 | if ((s->crt = crt_tree_new(ps, s->n)) == NULL) { 360 | /* if crt_tree_new fails, regenerate with new p_i's */ 361 | if (verbose) 362 | fprintf(stderr, "(restarting)\n"); 363 | goto generate_ps; 364 | } 365 | mpz_set(s->x0, s->crt->mod); 366 | if (verbose) 367 | fprintf(stderr, "[%.2fs]\n", current_time() - start_time); 368 | } else { 369 | if (verbose) 370 | fprintf(stderr, " Computing x0:\n"); 371 | product(s->x0, ps, s->n, verbose); 372 | if (verbose) 373 | fprintf(stderr, " Generating CRT coefficients:\n"); 374 | crt_coeffs(s->crt_coeffs, ps, s->n, s->x0, verbose); 375 | } 376 | 377 | zs = mpz_vector_new(s->nzs); 378 | s->zinvs = mpz_vector_new(s->nzs); 379 | if (verbose) 380 | fprintf(stderr, " Generating z_i's:\n"); 381 | generate_zs(zs, s->zinvs, s->rngs, s->nzs, s->x0, verbose); 382 | 383 | mpz_init(s->pzt); 384 | generate_pzt(s->pzt, beta, s->n, ps, s->gs, s->nzs, zs, params->pows, 385 | s->x0, s->rngs, verbose); 386 | 387 | mpz_vector_free(ps, s->n); 388 | mpz_vector_free(zs, s->nzs); 389 | 390 | return s; 391 | } 392 | 393 | void 394 | clt_state_free(clt_state_t *s) 395 | { 396 | mpz_clear(s->x0); 397 | mpz_clear(s->pzt); 398 | mpz_vector_free(s->gs, s->n); 399 | mpz_vector_free(s->zinvs, s->nzs); 400 | if (s->flags & CLT_FLAG_OPT_CRT_TREE) { 401 | crt_tree_free(s->crt); 402 | } else { 403 | mpz_vector_free(s->crt_coeffs, s->n); 404 | } 405 | if (s->rngs) { 406 | for (size_t i = 0; i < max(s->n, s->nzs); ++i) { 407 | aes_randclear(s->rngs[i]); 408 | } 409 | free(s->rngs); 410 | } 411 | free(s); 412 | } 413 | 414 | mpz_t * 415 | clt_state_moduli(const clt_state_t *s) 416 | { 417 | return s->gs; 418 | } 419 | 420 | size_t 421 | clt_state_nslots(const clt_state_t *s) 422 | { 423 | return s->n; 424 | } 425 | 426 | size_t 427 | clt_state_nzs(const clt_state_t *s) 428 | { 429 | return s->nzs; 430 | } 431 | 432 | int 433 | clt_encode(clt_elem_t *rop, const clt_state_t *s, size_t n, const mpz_t *xs, 434 | const int *ix) 435 | { 436 | if (rop == NULL || s == NULL || n == 0 || xs == NULL) 437 | return CLT_ERR; 438 | 439 | if (!(s->flags & CLT_FLAG_OPT_PARALLEL_ENCODE)) 440 | omp_set_num_threads(1); 441 | 442 | /* slots[i] = m[i] + r·g[i] */ 443 | if (s->flags & CLT_FLAG_OPT_CRT_TREE) { 444 | mpz_t *slots = mpz_vector_new(s->n); 445 | #pragma omp parallel for 446 | for (size_t i = 0; i < s->n; i++) { 447 | mpz_random_(slots[i], s->rngs[i], s->rho); 448 | mpz_mul(slots[i], slots[i], s->gs[i]); 449 | if (i < n) 450 | mpz_add(slots[i], slots[i], xs[i]); 451 | /* mpz_add(slots[i], slots[i], xs[slot(i, n, s->n)]); */ 452 | } 453 | crt_tree_do_crt(rop->elem, s->crt, slots); 454 | mpz_vector_free(slots, s->n); 455 | } else { 456 | mpz_set_ui(rop->elem, 0); 457 | #pragma omp parallel for 458 | for (size_t i = 0; i < s->n; ++i) { 459 | mpz_t tmp; 460 | mpz_init(tmp); 461 | mpz_random_(tmp, s->rngs[i], s->rho); 462 | mpz_mul(tmp, tmp, s->gs[i]); 463 | if (i < n) 464 | mpz_add(tmp, tmp, xs[i]); 465 | /* mpz_add(tmp, tmp, xs[slot(i, n, s->n)]); */ 466 | mpz_mul(tmp, tmp, s->crt_coeffs[i]); 467 | #pragma omp critical 468 | { 469 | mpz_add(rop->elem, rop->elem, tmp); 470 | } 471 | mpz_clear(tmp); 472 | } 473 | } 474 | if (ix) { 475 | mpz_t tmp; 476 | mpz_init(tmp); 477 | /* multiply by appropriate zinvs */ 478 | for (size_t i = 0; i < s->nzs; ++i) { 479 | if (ix[i] <= 0) continue; 480 | mpz_powm_ui(tmp, s->zinvs[i], ix[i], s->x0); 481 | mpz_mul_mod_near(rop->elem, rop->elem, tmp, s->x0); 482 | } 483 | mpz_clear(tmp); 484 | } 485 | return CLT_OK; 486 | } 487 | 488 | int 489 | clt_is_zero(const clt_elem_t *c, const clt_pp_t *pp) 490 | { 491 | int ret; 492 | 493 | mpz_t tmp; 494 | mpz_init(tmp); 495 | 496 | mpz_mul(tmp, c->elem, pp->pzt); 497 | mpz_mod_near(tmp, tmp, pp->x0); 498 | 499 | ret = mpz_sizeinbase(tmp, 2) < mpz_sizeinbase(pp->x0, 2) - pp->nu; 500 | mpz_clear(tmp); 501 | return ret ? 1 : 0; 502 | } 503 | -------------------------------------------------------------------------------- /src/clt13.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLT13_H__ 2 | #define __CLT13_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #define CLT_OK 0 9 | #define CLT_ERR (-1) 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | typedef struct clt_elem_t clt_elem_t; 16 | typedef struct clt_state_t clt_state_t; 17 | typedef struct clt_pp_t clt_pp_t; 18 | 19 | /* Required parameters to clt_state_new */ 20 | typedef struct { 21 | /* security parameter */ 22 | size_t lambda; 23 | /* multilinearity */ 24 | size_t kappa; 25 | /* number of values in the index set */ 26 | size_t nzs; 27 | /* powers of the index set values at the top level */ 28 | int *pows; 29 | } clt_params_t; 30 | 31 | /* Optional parameters to clt_state_new */ 32 | typedef struct { 33 | /* minimum number of slots needed */ 34 | size_t slots; 35 | /* plaintext moduli */ 36 | mpz_t *moduli; 37 | /* number of plaintext moduli given */ 38 | size_t nmoduli; 39 | } clt_opt_params_t; 40 | 41 | #define CLT_FLAG_NONE 0x00 42 | /* Be verbose */ 43 | #define CLT_FLAG_VERBOSE 0x01 44 | 45 | /* CLT optimization flags */ 46 | 47 | /* Use CRT tree optimization */ 48 | #define CLT_FLAG_OPT_CRT_TREE 0x02 49 | /* Parallelize the encoding procedure */ 50 | #define CLT_FLAG_OPT_PARALLEL_ENCODE 0x04 51 | /* Use composite primes (each "real" prime is the product of smaller primes) */ 52 | #define CLT_FLAG_OPT_COMPOSITE_PS 0x08 53 | 54 | /* CLT security parameterization flags */ 55 | 56 | /* Use improved BKZ algorithm when generating attack estimates */ 57 | #define CLT_FLAG_SEC_IMPROVED_BKZ 0x10 58 | /* Be conservative when generating attack estimates */ 59 | #define CLT_FLAG_SEC_CONSERVATIVE 0x20 60 | 61 | #define CLT_FLAG_DEFAULT \ 62 | ( CLT_FLAG_OPT_CRT_TREE \ 63 | | CLT_FLAG_OPT_COMPOSITE_PS \ 64 | | CLT_FLAG_SEC_IMPROVED_BKZ \ 65 | ) 66 | 67 | clt_state_t * clt_state_new(const clt_params_t *params, 68 | const clt_opt_params_t *opts, size_t ncores, 69 | size_t flags, aes_randstate_t rng); 70 | void clt_state_free(clt_state_t *s); 71 | clt_state_t * clt_state_fread(FILE *fp); 72 | int clt_state_fwrite(clt_state_t *s, FILE *fp); 73 | mpz_t * clt_state_moduli(const clt_state_t *s); 74 | size_t clt_state_nslots(const clt_state_t *s); 75 | size_t clt_state_nzs(const clt_state_t *s); 76 | 77 | clt_pp_t * clt_pp_new(const clt_state_t *mmap); 78 | void clt_pp_free(clt_pp_t *pp); 79 | clt_pp_t * clt_pp_fread(FILE *fp); 80 | int clt_pp_fwrite(clt_pp_t *pp, FILE *fp); 81 | 82 | /* Creates an encoding `rop` using CLT state `s` of integers `xs` of length `n` 83 | * and index set `ix` of length `clt_state_nzs(s)` */ 84 | int clt_encode(clt_elem_t *rop, const clt_state_t *s, size_t n, const mpz_t *xs, 85 | const int *ix); 86 | int clt_is_zero(const clt_elem_t *a, const clt_pp_t *pp); 87 | 88 | clt_elem_t * clt_elem_new(void); 89 | void clt_elem_free(clt_elem_t *a); 90 | clt_elem_t * clt_elem_copy(clt_elem_t *a); 91 | void clt_elem_set(clt_elem_t *a, const clt_elem_t *b); 92 | int clt_elem_add(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, const clt_elem_t *b); 93 | int clt_elem_sub(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, const clt_elem_t *b); 94 | int clt_elem_mul(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, const clt_elem_t *b); 95 | int clt_elem_mul_ui(clt_elem_t *rop, const clt_pp_t *pp, const clt_elem_t *a, unsigned int b); 96 | void clt_elem_print(const clt_elem_t *a); 97 | int clt_elem_fread(clt_elem_t *x, FILE *fp); 98 | int clt_elem_fwrite(clt_elem_t *x, FILE *fp); 99 | 100 | #ifdef __cplusplus 101 | } 102 | #endif 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/clt_elem.c: -------------------------------------------------------------------------------- 1 | #include "clt13.h" 2 | #include "clt_elem.h" 3 | #include "utils.h" 4 | 5 | #include 6 | 7 | clt_elem_t * 8 | clt_elem_new(void) 9 | { 10 | clt_elem_t *e = calloc(1, sizeof e[0]); 11 | mpz_init(e->elem); 12 | e->level = 0; 13 | return e; 14 | } 15 | 16 | void 17 | clt_elem_free(clt_elem_t *e) 18 | { 19 | mpz_clear(e->elem); 20 | free(e); 21 | } 22 | 23 | clt_elem_t * 24 | clt_elem_copy(clt_elem_t *a) 25 | { 26 | clt_elem_t *e; 27 | e = calloc(1, sizeof e[0]); 28 | clt_elem_set(e, a); 29 | return e; 30 | } 31 | 32 | void 33 | clt_elem_set(clt_elem_t *a, const clt_elem_t *b) 34 | { 35 | mpz_set(a->elem, b->elem); 36 | a->level = b->level; 37 | } 38 | 39 | void 40 | clt_elem_print(const clt_elem_t *a) 41 | { 42 | gmp_printf("%lu | %Zd", a->level, a->elem); 43 | } 44 | 45 | int 46 | clt_elem_fread(clt_elem_t *x, FILE *fp) 47 | { 48 | if (mpz_fread(x->elem, fp) == CLT_ERR) return CLT_ERR; 49 | if (size_t_fread(fp, &x->level) == CLT_ERR) return CLT_ERR; 50 | return CLT_OK; 51 | } 52 | 53 | int 54 | clt_elem_fwrite(clt_elem_t *x, FILE *fp) 55 | { 56 | if (mpz_fwrite(x->elem, fp) == CLT_ERR) return CLT_ERR; 57 | if (size_t_fwrite(fp, x->level) == CLT_ERR) return CLT_ERR; 58 | return CLT_OK; 59 | } 60 | -------------------------------------------------------------------------------- /src/clt_elem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct clt_elem_t { 6 | mpz_t elem; 7 | size_t level; 8 | }; 9 | -------------------------------------------------------------------------------- /src/crt_tree.c: -------------------------------------------------------------------------------- 1 | #include "crt_tree.h" 2 | #include "utils.h" 3 | 4 | #include 5 | #include 6 | 7 | static crt_tree * 8 | _crt_tree_new(mpz_t *ps, size_t n) 9 | { 10 | crt_tree *crt; 11 | 12 | if (ps == NULL || n == 0) 13 | return NULL; 14 | 15 | crt = calloc(1, sizeof(crt_tree)); 16 | crt->n = n; 17 | mpz_inits(crt->mod, crt->crt_left, crt->crt_right, NULL); 18 | if (crt->n == 1) { 19 | crt->left = NULL; 20 | crt->right = NULL; 21 | mpz_set(crt->mod, ps[0]); 22 | } else { 23 | mpz_t g; 24 | 25 | { 26 | #pragma omp task 27 | { 28 | crt->left = _crt_tree_new(ps, crt->n / 2); 29 | } 30 | #pragma omp task 31 | { 32 | crt->right = _crt_tree_new(ps + crt->n / 2, crt->n - crt->n / 2); 33 | } 34 | #pragma omp taskwait 35 | } 36 | 37 | if (!crt->left || !crt->right) { 38 | crt_tree_free(crt); 39 | return NULL; 40 | } 41 | 42 | mpz_init_set_ui(g, 0); 43 | mpz_gcdext(g, crt->crt_right, crt->crt_left, crt->left->mod, crt->right->mod); 44 | if (mpz_cmp_ui(g, 1) != 0) { 45 | crt_tree_free(crt); 46 | mpz_clear(g); 47 | return NULL; 48 | } 49 | mpz_clear(g); 50 | 51 | mpz_mul(crt->crt_left, crt->crt_left, crt->right->mod); 52 | mpz_mul(crt->crt_right, crt->crt_right, crt->left->mod); 53 | mpz_mul(crt->mod, crt->left->mod, crt->right->mod); 54 | } 55 | return crt; 56 | } 57 | 58 | crt_tree * 59 | crt_tree_new(mpz_t *ps, size_t n) 60 | { 61 | crt_tree *crt; 62 | #pragma omp parallel default(shared) 63 | #pragma omp single 64 | crt = _crt_tree_new(ps, n); 65 | return crt; 66 | } 67 | 68 | void 69 | crt_tree_free(crt_tree *crt) 70 | { 71 | if (crt->left) 72 | crt_tree_free(crt->left); 73 | if (crt->right) 74 | crt_tree_free(crt->right); 75 | mpz_clears(crt->mod, crt->crt_left, crt->crt_right, NULL); 76 | free(crt); 77 | } 78 | 79 | void 80 | crt_tree_do_crt(mpz_t rop, const crt_tree *crt, mpz_t *cs) 81 | { 82 | if (crt->n == 1) { 83 | mpz_set(rop, cs[0]); 84 | } else { 85 | mpz_t left, right, tmp; 86 | mpz_inits(left, right, tmp, NULL); 87 | 88 | crt_tree_do_crt(left, crt->left, cs); 89 | crt_tree_do_crt(right, crt->right, cs + crt->n / 2); 90 | 91 | mpz_mul(rop, left, crt->crt_left); 92 | mpz_mul(tmp, right, crt->crt_right); 93 | mpz_add(rop, rop, tmp); 94 | mpz_mod(rop, rop, crt->mod); 95 | 96 | mpz_clears(left, right, tmp, NULL); 97 | } 98 | } 99 | 100 | static void 101 | _crt_tree_get_leafs(mpz_t *leafs, int *i, const crt_tree *crt) 102 | { 103 | if (crt->n == 1) { 104 | mpz_set(leafs[(*i)++], crt->mod); 105 | } else { 106 | _crt_tree_get_leafs(leafs, i, crt->left); 107 | _crt_tree_get_leafs(leafs, i, crt->right); 108 | } 109 | } 110 | 111 | crt_tree * 112 | crt_tree_fread(FILE *fp, size_t n) 113 | { 114 | crt_tree *crt = NULL; 115 | mpz_t *ps; 116 | 117 | ps = mpz_vector_new(n); 118 | if (mpz_vector_fread(ps, n, fp) == CLT_ERR) 119 | goto cleanup; 120 | if ((crt = crt_tree_new(ps, n)) == NULL) 121 | goto cleanup; 122 | 123 | cleanup: 124 | mpz_vector_free(ps, n); 125 | return crt; 126 | } 127 | 128 | int 129 | crt_tree_fwrite(FILE *fp, const crt_tree *crt, size_t n) 130 | { 131 | int ret = CLT_ERR, ctr = 0; 132 | mpz_t *ps; 133 | 134 | ps = mpz_vector_new(n); 135 | _crt_tree_get_leafs(ps, &ctr, crt); 136 | if (mpz_vector_fwrite(ps, n, fp) == CLT_ERR) 137 | goto cleanup; 138 | ret = CLT_OK; 139 | cleanup: 140 | mpz_vector_free(ps, n); 141 | return ret; 142 | } 143 | -------------------------------------------------------------------------------- /src/crt_tree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "clt13.h" 4 | 5 | #pragma GCC visibility push(hidden) 6 | 7 | typedef struct crt_tree { 8 | size_t n; 9 | mpz_t mod; 10 | mpz_t crt_left; 11 | mpz_t crt_right; 12 | struct crt_tree *left; 13 | struct crt_tree *right; 14 | } crt_tree; 15 | 16 | crt_tree * crt_tree_new(mpz_t *const ps, size_t n); 17 | void crt_tree_free(crt_tree *crt); 18 | 19 | void crt_tree_do_crt(mpz_t rop, const crt_tree *crt, mpz_t *cs); 20 | crt_tree * crt_tree_fread(FILE *const fp, size_t n); 21 | void crt_tree_write(const char *fname, const crt_tree *const crt, size_t n); 22 | int crt_tree_fwrite(FILE *const fp, const crt_tree *const crt, size_t n); 23 | 24 | #pragma GCC visibility pop 25 | -------------------------------------------------------------------------------- /src/estimates.c: -------------------------------------------------------------------------------- 1 | /* 2 | Code for estimating n, the number of primes p_i to use. Mostly adapted from the 3 | SAGE code provided by Tancrède Lepoint in his thesis (Figures 7.2 and 7.3). 4 | */ 5 | 6 | #include "estimates.h" 7 | #include "utils.h" 8 | 9 | #include 10 | #include 11 | 12 | static double 13 | time_LLL(double m, double gamma) 14 | { 15 | return log2(0.06 * pow(m, 4) * gamma); 16 | } 17 | 18 | static double 19 | time_BKZ20(double m, double gamma) 20 | { 21 | return log2(0.36 * pow(m, 4.2) * gamma); 22 | } 23 | 24 | static double 25 | m_min(size_t lambda, size_t eta, double gamma, double hermite_factor) 26 | { 27 | double lh, result; 28 | lh = log2(hermite_factor); 29 | result = (eta - sqrt(eta * eta - 4 * lh * (gamma - lambda)))/(2 * lh); 30 | if (result > 0) 31 | return ceil(result); 32 | else 33 | return pow(2, lambda); 34 | } 35 | 36 | static double 37 | gamma_from_orthogonal_attack(size_t lambda, size_t eta, bool conservative) 38 | { 39 | double gamma = ceil(lambda + eta * eta / 4 / log2(1.012)); 40 | if (!conservative) { 41 | while (gamma > 1) { 42 | double m1, m2; 43 | gamma /= 1.1; 44 | m1 = time_LLL(m_min(lambda, eta, gamma, 1.021), gamma); 45 | m2 = time_BKZ20(m_min(lambda, eta, gamma, 1.013), gamma); 46 | if (min(m1, m2) < lambda) { 47 | gamma *= 1.1; 48 | break; 49 | } 50 | } 51 | } 52 | return gamma; 53 | } 54 | 55 | static double 56 | gamma_from_orthogonal_attack_2(size_t lambda, size_t eta, double hermite_factor, 57 | bool conservative) 58 | { 59 | double gamma = ceil(lambda + eta * eta / 4 / log2(hermite_factor)); 60 | if (!conservative) { 61 | while (gamma > 1) { 62 | double m; 63 | gamma /= 1.1; 64 | m = time_LLL(m_min(lambda, eta, gamma, hermite_factor), gamma); 65 | if (m < lambda) { 66 | gamma *= 1.1; 67 | break; 68 | } 69 | } 70 | } 71 | return gamma; 72 | } 73 | 74 | size_t 75 | estimate_n(size_t lambda, size_t eta, size_t flags) 76 | { 77 | bool conservative = flags & CLT_FLAG_SEC_CONSERVATIVE; 78 | double gamma; 79 | if (flags & CLT_FLAG_SEC_IMPROVED_BKZ) { 80 | gamma = gamma_from_orthogonal_attack_2(lambda, eta, 1.005, conservative); 81 | } else { 82 | gamma = gamma_from_orthogonal_attack(lambda, eta, conservative); 83 | } 84 | return (size_t) ceil(gamma / eta); 85 | } 86 | -------------------------------------------------------------------------------- /src/estimates.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "clt13.h" 4 | 5 | #pragma GCC visibility push(hidden) 6 | 7 | size_t estimate_n(size_t lambda, size_t eta, size_t flags); 8 | 9 | #pragma GCC visibility pop 10 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | #include "clt13.h" 2 | #include "utils.h" 3 | 4 | #include 5 | 6 | int 7 | mpz_fread(mpz_t x, FILE *fp) 8 | { 9 | if (mpz_inp_raw(x, fp) == 0) 10 | return CLT_ERR; 11 | return CLT_OK; 12 | } 13 | 14 | int 15 | mpz_fwrite(mpz_t x, FILE *fp) 16 | { 17 | if (mpz_out_raw(fp, x) == 0) 18 | return CLT_ERR; 19 | return CLT_OK; 20 | } 21 | 22 | mpz_t * 23 | mpz_vector_new(size_t n) 24 | { 25 | mpz_t *v; 26 | if ((v = calloc(n, sizeof v[0])) == NULL) 27 | return NULL; 28 | for (size_t i = 0; i < n; ++i) 29 | mpz_init(v[i]); 30 | return v; 31 | } 32 | 33 | void 34 | mpz_vector_free(mpz_t *v, size_t n) 35 | { 36 | for (size_t i = 0; i < n; ++i) 37 | mpz_clear(v[i]); 38 | free(v); 39 | } 40 | 41 | int 42 | mpz_vector_fread(mpz_t *m, size_t len, FILE *fp) 43 | { 44 | for (size_t i = 0; i < len; ++i) { 45 | if (mpz_fread(m[i], fp) == CLT_ERR) 46 | return CLT_ERR; 47 | } 48 | return CLT_OK; 49 | } 50 | 51 | int 52 | mpz_vector_fwrite(mpz_t *m, size_t len, FILE *fp) 53 | { 54 | for (size_t i = 0; i < len; ++i) { 55 | if (mpz_fwrite(m[i], fp) == CLT_ERR) 56 | return CLT_ERR; 57 | } 58 | return CLT_OK; 59 | } 60 | 61 | double 62 | current_time(void) 63 | { 64 | struct timeval t; 65 | gettimeofday(&t, NULL); 66 | return t.tv_sec + (double) (t.tv_usec / 1000000.0); 67 | } 68 | 69 | #define PBSTR "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||" 70 | #define PBWIDTH 60 71 | 72 | void 73 | print_progress(size_t cur, size_t total) 74 | { 75 | static int last_val = 0; 76 | double percentage = (double) cur / total; 77 | int val = percentage * 100; 78 | int lpad = percentage * PBWIDTH; 79 | int rpad = PBWIDTH - lpad; 80 | if (val != last_val) { 81 | fprintf(stderr, "\r\t%3d%% [%.*s%*s] %lu/%lu", val, lpad, PBSTR, rpad, "", cur, total); 82 | fflush(stderr); 83 | last_val = val; 84 | } 85 | } 86 | 87 | int 88 | size_t_fread(FILE *fp, size_t *x) 89 | { 90 | if (fread(x, sizeof x[0], 1, fp) != 1) 91 | return CLT_ERR; 92 | return CLT_OK; 93 | } 94 | 95 | int 96 | size_t_fwrite(FILE *fp, size_t x) 97 | { 98 | if (fwrite(&x, sizeof x, 1, fp) != 1) 99 | return CLT_ERR; 100 | return CLT_OK; 101 | } 102 | 103 | int 104 | bool_fread(FILE *fp, bool *x) 105 | { 106 | return (fread(x, sizeof x[0], 1, fp) == 1) ? CLT_OK : CLT_ERR; 107 | } 108 | int 109 | bool_fwrite(FILE *fp, bool x) 110 | { 111 | return (fwrite(&x, sizeof x, 1, fp) == 1) ? CLT_OK : CLT_ERR; 112 | } 113 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma GCC visibility push(hidden) 10 | 11 | static inline size_t 12 | max(size_t a, size_t b) { 13 | return a > b ? a : b; 14 | } 15 | 16 | static inline size_t 17 | min(size_t a, size_t b) { 18 | return a > b ? b : a; 19 | } 20 | 21 | double current_time(void); 22 | void print_progress(size_t cur, size_t total); 23 | 24 | /* `rop` = `a` mod `p`, where -p/2 < rop < p/2 */ 25 | static inline void 26 | mpz_mod_near(mpz_t rop, const mpz_t a, const mpz_t p) 27 | { 28 | mpz_t p_; 29 | mpz_init(p_); 30 | mpz_mod(rop, a, p); 31 | mpz_tdiv_q_2exp(p_, p, 1); 32 | if (mpz_cmp(rop, p_) > 0) 33 | mpz_sub(rop, rop, p); 34 | mpz_clear(p_); 35 | } 36 | 37 | static inline void 38 | mpz_mod_near_ui(mpz_t rop, const mpz_t a, size_t p) 39 | { 40 | 41 | mpz_mod_ui(rop, a, p); 42 | if (mpz_cmp_ui(rop, p / 2) > 0) 43 | mpz_sub_ui(rop, rop, p); 44 | } 45 | 46 | static inline void 47 | mpz_mul_mod_near(mpz_t rop, const mpz_t a, const mpz_t b, const mpz_t p) 48 | { 49 | mpz_mul(rop, a, b); 50 | mpz_mod_near(rop, rop, p); 51 | } 52 | 53 | static inline void 54 | mpz_quotient(mpz_t rop, const mpz_t a, const mpz_t b) 55 | { 56 | mpz_t tmp; 57 | mpz_init(tmp); 58 | mpz_mod_near(tmp, a, b); 59 | mpz_sub(rop, a, tmp); 60 | mpz_tdiv_q(rop, rop, b); 61 | mpz_clear(tmp); 62 | } 63 | 64 | static inline void 65 | mpz_quotient_2exp(mpz_t rop, const mpz_t a, const size_t b) 66 | { 67 | mpz_t tmp; 68 | mpz_init(tmp); 69 | mpz_mod_near_ui(tmp, a, 1 << b); 70 | mpz_sub(rop, a, tmp); 71 | mpz_tdiv_q_2exp(rop, rop, b); 72 | mpz_clear(tmp); 73 | } 74 | 75 | static inline void 76 | mpz_random_(mpz_t rop, aes_randstate_t rng, size_t len) 77 | { 78 | mpz_urandomb_aes(rop, rng, len); 79 | mpz_setbit(rop, len-1); 80 | } 81 | 82 | static inline void 83 | mpz_prime(mpz_t rop, aes_randstate_t rng, size_t len) 84 | { 85 | mpz_t p_unif; 86 | mpz_init(p_unif); 87 | do { 88 | mpz_random_(p_unif, rng, len); 89 | mpz_nextprime(rop, p_unif); 90 | } while (mpz_tstbit(rop, len) == 1); 91 | assert(mpz_tstbit(rop, len-1) == 1); 92 | mpz_clear(p_unif); 93 | } 94 | 95 | static inline void 96 | product(mpz_t rop, mpz_t *xs, size_t n, bool verbose) 97 | { 98 | double start = current_time(); 99 | /* TODO: could parallelize this if desired */ 100 | mpz_set_ui(rop, 1); 101 | for (size_t i = 0; i < n; i++) { 102 | mpz_mul(rop, rop, xs[i]); 103 | if (verbose) 104 | print_progress(i, n-1); 105 | } 106 | if (verbose) 107 | fprintf(stderr, "\t[%.2fs]\n", current_time() - start); 108 | } 109 | 110 | static inline void 111 | crt_coeffs(mpz_t *coeffs, mpz_t *ps, size_t n, mpz_t x0, bool verbose) 112 | { 113 | const double start = current_time(); 114 | int count = 0; 115 | #pragma omp parallel for 116 | for (size_t i = 0; i < n; i++) { 117 | mpz_t q; 118 | mpz_init(q); 119 | mpz_div(q, x0, ps[i]); 120 | mpz_invert(coeffs[i], q, ps[i]); 121 | mpz_mul_mod_near(coeffs[i], coeffs[i], q, x0); 122 | if (verbose) { 123 | #pragma omp critical 124 | print_progress(++count, n); 125 | } 126 | mpz_clear(q); 127 | } 128 | if (verbose) 129 | fprintf(stderr, "\t[%.2fs]\n", current_time() - start); 130 | } 131 | 132 | static inline void 133 | generate_zs(mpz_t *zs, mpz_t *zinvs, aes_randstate_t *rngs, size_t nzs, const mpz_t x0, bool verbose) 134 | { 135 | const double start = current_time(); 136 | int count = 0; 137 | #pragma omp parallel for 138 | for (size_t i = 0; i < nzs; ++i) { 139 | do { 140 | mpz_urandomm_aes(zs[i], rngs[i], x0); 141 | } while (mpz_invert(zinvs[i], zs[i], x0) == 0); 142 | if (verbose) 143 | #pragma omp critical 144 | print_progress(++count, nzs); 145 | } 146 | if (verbose) 147 | fprintf(stderr, "\t[%.2fs]\n", current_time() - start); 148 | } 149 | 150 | static inline void 151 | generate_pzt(mpz_t pzt, size_t rho, size_t n, mpz_t *ps, mpz_t *gs, 152 | size_t nzs, mpz_t *zs, const int *ix, const mpz_t x0, 153 | aes_randstate_t *rngs, bool verbose) 154 | { 155 | mpz_t zk; 156 | int count = 0; 157 | double start = current_time(); 158 | mpz_set_ui(pzt, 0); 159 | if (verbose) 160 | fprintf(stderr, " Generating pzt:\n"); 161 | mpz_init_set_ui(zk, 1); 162 | /* compute z_1^t_1 ... z_k^t_k mod x0 */ 163 | if (ix) { 164 | for (size_t i = 0; i < nzs; ++i) { 165 | mpz_t tmp; 166 | mpz_init(tmp); 167 | mpz_powm_ui(tmp, zs[i], ix[i], x0); 168 | mpz_mul_mod_near(zk, zk, tmp, x0); 169 | mpz_clear(tmp); 170 | if (verbose) 171 | print_progress(++count, n + nzs); 172 | } 173 | } 174 | #pragma omp parallel for 175 | for (size_t i = 0; i < n; ++i) { 176 | mpz_t tmp, qpi, rnd, test; 177 | mpz_inits(tmp, qpi, rnd, test, NULL); 178 | /* compute ((g_i^{-1} mod p_i) · z · r_i · (x0 / p_i) */ 179 | mpz_invert(tmp, gs[i], ps[i]); 180 | mpz_mul(tmp, tmp, zk); 181 | do { 182 | mpz_urandomb_aes(rnd, rngs[i], rho); 183 | mpz_mod(test, rnd, gs[i]); 184 | } while (mpz_cmp_ui(test, 0) == 0); 185 | mpz_mul(tmp, tmp, rnd); 186 | mpz_divexact(qpi, x0, ps[i]); 187 | mpz_mul_mod_near(tmp, tmp, qpi, x0); 188 | #pragma omp critical 189 | { 190 | mpz_add(pzt, pzt, tmp); 191 | } 192 | mpz_clears(tmp, qpi, rnd, test, NULL); 193 | if (verbose) 194 | #pragma omp critical 195 | { 196 | print_progress(++count, n + nzs); 197 | } 198 | } 199 | mpz_mod_near(pzt, pzt, x0); 200 | mpz_clear(zk); 201 | if (verbose) 202 | fprintf(stderr, "\t[%.2fs]\n", current_time() - start); 203 | } 204 | 205 | 206 | /* Generates `n` primes each of bitlength `len` */ 207 | static inline int 208 | generate_primes(mpz_t *v, aes_randstate_t *rngs, size_t n, size_t len, bool verbose) 209 | { 210 | const double start = current_time(); 211 | int count = 0; 212 | if (verbose) 213 | fprintf(stderr, "%lu", len); 214 | print_progress(count, n); 215 | #pragma omp parallel for 216 | for (size_t i = 0; i < n; ++i) { 217 | mpz_prime(v[i], rngs[i], len); 218 | if (verbose) { 219 | #pragma omp critical 220 | print_progress(++count, n); 221 | } 222 | } 223 | if (verbose) 224 | fprintf(stderr, "\t[%.2fs]\n", current_time() - start); 225 | return CLT_OK; 226 | } 227 | 228 | /* Returns the number of ones in `x` */ 229 | static inline size_t 230 | nb_of_bits(size_t x) 231 | { 232 | size_t nb = 0; 233 | while (x > 0) { 234 | x >>= 1; 235 | nb++; 236 | } 237 | return nb; 238 | } 239 | 240 | static inline size_t 241 | slot(size_t i, size_t n, size_t maxslots) 242 | { 243 | if (i == maxslots - 1) 244 | return n - 1; 245 | else 246 | return i / (maxslots / n); 247 | } 248 | 249 | int mpz_fread(mpz_t x, FILE *fp); 250 | int mpz_fwrite(mpz_t x, FILE *fp); 251 | mpz_t * mpz_vector_new(size_t n); 252 | void mpz_vector_free(mpz_t *v, size_t n); 253 | int mpz_vector_fread(mpz_t *m, size_t len, FILE *fp); 254 | int mpz_vector_fwrite(mpz_t *m, size_t len, FILE *fp); 255 | 256 | int size_t_fread(FILE *fp, size_t *x); 257 | int size_t_fwrite(FILE *fp, size_t x); 258 | int bool_fread(FILE *fp, bool *x); 259 | int bool_fwrite(FILE *fp, bool x); 260 | 261 | #pragma GCC visibility pop 262 | -------------------------------------------------------------------------------- /sudoku_sets/sudoku1.txt: -------------------------------------------------------------------------------- 1 | 0 82 163 244 2 | 0 83 164 245 3 | 0 85 166 247 4 | 0 87 168 249 5 | 0 89 170 251 6 | 1 81 171 243 7 | 2 82 181 244 8 | 2 83 182 245 9 | 2 87 186 249 10 | 2 88 187 250 11 | 3 84 192 255 12 | 3 85 193 256 13 | 3 86 194 257 14 | 3 87 195 258 15 | 3 88 196 259 16 | 3 89 197 260 17 | 4 83 200 254 18 | 4 85 202 256 19 | 4 86 203 257 20 | 4 88 205 259 21 | 4 89 206 260 22 | 5 83 209 254 23 | 5 84 210 255 24 | 5 85 211 256 25 | 5 87 213 258 26 | 5 88 214 259 27 | 5 89 215 260 28 | 6 82 217 262 29 | 6 87 222 267 30 | 6 88 223 268 31 | 7 84 228 264 32 | 7 86 230 266 33 | 7 87 231 267 34 | 7 88 232 268 35 | 8 82 235 262 36 | 8 84 237 264 37 | 8 86 239 266 38 | 8 87 240 267 39 | 8 88 241 268 40 | 9 91 163 244 41 | 9 92 164 245 42 | 9 96 168 249 43 | 10 91 172 244 44 | 10 92 173 245 45 | 10 96 177 249 46 | 10 97 178 250 47 | 11 91 181 244 48 | 11 92 182 245 49 | 11 96 186 249 50 | 11 97 187 250 51 | 12 93 192 255 52 | 12 95 194 257 53 | 12 96 195 258 54 | 12 97 196 259 55 | 13 92 200 254 56 | 13 95 203 257 57 | 13 97 205 259 58 | 14 90 207 252 59 | 15 98 224 269 60 | 16 93 228 264 61 | 16 95 230 266 62 | 16 96 231 267 63 | 16 97 232 268 64 | 17 94 238 265 65 | 18 103 166 247 66 | 18 105 168 249 67 | 18 107 170 251 68 | 19 104 176 248 69 | 20 102 183 246 70 | 21 103 193 256 71 | 21 105 195 258 72 | 21 106 196 259 73 | 21 107 197 260 74 | 22 100 199 253 75 | 23 103 211 256 76 | 23 105 213 258 77 | 23 106 214 259 78 | 23 107 215 260 79 | 24 101 218 263 80 | 25 99 225 261 81 | 25 105 231 267 82 | 25 106 232 268 83 | 26 99 234 261 84 | 26 105 240 267 85 | 26 106 241 268 86 | 27 109 163 271 87 | 27 110 164 272 88 | 27 112 166 274 89 | 27 113 167 275 90 | 27 114 168 276 91 | 27 116 170 278 92 | 28 111 174 273 93 | 29 109 181 271 94 | 29 110 182 272 95 | 29 113 185 275 96 | 29 114 186 276 97 | 29 115 187 277 98 | 30 112 193 283 99 | 30 115 196 286 100 | 30 116 197 287 101 | 31 108 198 279 102 | 32 109 208 280 103 | 32 112 211 283 104 | 32 115 214 286 105 | 32 116 215 287 106 | 33 109 217 289 107 | 33 112 220 292 108 | 33 114 222 294 109 | 33 115 223 295 110 | 34 110 227 290 111 | 34 113 230 293 112 | 34 114 231 294 113 | 34 115 232 295 114 | 35 109 235 289 115 | 35 110 236 290 116 | 35 113 239 293 117 | 35 114 240 294 118 | 35 115 241 295 119 | 36 118 163 271 120 | 36 121 166 274 121 | 36 123 168 276 122 | 36 125 170 278 123 | 37 118 172 271 124 | 37 121 175 274 125 | 37 123 177 276 126 | 37 124 178 277 127 | 37 125 179 278 128 | 38 117 180 270 129 | 39 119 191 281 130 | 40 121 202 283 131 | 40 124 205 286 132 | 40 125 206 287 133 | 41 122 212 284 134 | 42 120 219 291 135 | 43 123 231 294 136 | 43 124 232 295 137 | 44 118 235 289 138 | 44 123 240 294 139 | 44 124 241 295 140 | 45 127 163 271 141 | 45 128 164 272 142 | 45 130 166 274 143 | 45 131 167 275 144 | 46 127 172 271 145 | 46 128 173 272 146 | 46 130 175 274 147 | 46 133 178 277 148 | 47 127 181 271 149 | 47 128 182 272 150 | 47 131 185 275 151 | 47 133 187 277 152 | 48 129 192 282 153 | 48 130 193 283 154 | 48 133 196 286 155 | 49 132 204 285 156 | 50 127 208 280 157 | 50 129 210 282 158 | 50 130 211 283 159 | 50 133 214 286 160 | 51 126 216 288 161 | 51 127 217 289 162 | 51 130 220 292 163 | 51 133 223 295 164 | 52 134 233 296 165 | 53 126 234 288 166 | 53 127 235 289 167 | 53 128 236 290 168 | 53 131 239 293 169 | 53 133 241 295 170 | 54 135 162 297 171 | 54 137 164 299 172 | 54 141 168 303 173 | 55 137 173 299 174 | 55 141 177 303 175 | 56 139 184 301 176 | 57 135 189 306 177 | 57 141 195 312 178 | 57 142 196 313 179 | 57 143 197 314 180 | 58 138 201 309 181 | 59 137 209 308 182 | 59 141 213 312 183 | 59 142 214 313 184 | 59 143 215 314 185 | 60 140 221 320 186 | 61 136 226 316 187 | 62 135 234 315 188 | 62 137 236 317 189 | 62 141 240 321 190 | 62 142 241 322 191 | 62 143 242 323 192 | 63 151 169 304 193 | 64 146 173 299 194 | 64 150 177 303 195 | 65 152 188 305 196 | 66 145 190 307 197 | 67 146 200 308 198 | 67 148 202 310 199 | 67 149 203 311 200 | 68 146 209 308 201 | 68 148 211 310 202 | 68 150 213 312 203 | 69 144 216 315 204 | 69 150 222 321 205 | 70 144 225 315 206 | 70 146 227 317 207 | 70 147 228 318 208 | 70 150 231 321 209 | 71 144 234 315 210 | 71 146 236 317 211 | 71 147 237 318 212 | 71 150 240 321 213 | 72 153 162 297 214 | 72 154 163 298 215 | 72 155 164 299 216 | 72 156 165 300 217 | 72 158 167 302 218 | 72 159 168 303 219 | 73 154 172 298 220 | 73 155 173 299 221 | 73 159 177 303 222 | 74 154 181 298 223 | 74 155 182 299 224 | 74 158 185 302 225 | 74 159 186 303 226 | 75 153 189 306 227 | 75 158 194 311 228 | 75 159 195 312 229 | 75 160 196 313 230 | 75 161 197 314 231 | 76 155 200 308 232 | 76 158 203 311 233 | 76 160 205 313 234 | 76 161 206 314 235 | 77 155 209 308 236 | 77 159 213 312 237 | 77 160 214 313 238 | 77 161 215 314 239 | 78 153 216 315 240 | 78 159 222 321 241 | 78 160 223 322 242 | 79 157 229 319 243 | 80 153 234 315 244 | 80 155 236 317 245 | 80 156 237 318 246 | 80 159 240 321 247 | 80 160 241 322 248 | 80 161 242 323 249 | -------------------------------------------------------------------------------- /sudoku_sets/sudoku2.txt: -------------------------------------------------------------------------------- 1 | 0 85 166 247 2 | 0 87 168 249 3 | 0 89 170 251 4 | 1 83 173 245 5 | 1 87 177 249 6 | 1 89 179 251 7 | 2 84 183 246 8 | 3 88 196 259 9 | 4 82 199 253 10 | 4 85 202 256 11 | 4 86 203 257 12 | 4 87 204 258 13 | 5 82 208 253 14 | 5 86 212 257 15 | 5 89 215 260 16 | 6 82 217 262 17 | 6 85 220 265 18 | 6 86 221 266 19 | 6 89 224 269 20 | 7 82 226 262 21 | 7 85 229 265 22 | 7 86 230 266 23 | 8 81 234 261 24 | 9 90 162 243 25 | 9 94 166 247 26 | 9 96 168 249 27 | 9 97 169 250 28 | 9 98 170 251 29 | 10 91 172 244 30 | 11 90 180 243 31 | 11 94 184 247 32 | 11 96 186 249 33 | 11 97 187 250 34 | 11 98 188 251 35 | 12 94 193 256 36 | 12 95 194 257 37 | 12 98 197 260 38 | 13 93 201 255 39 | 14 90 207 252 40 | 14 95 212 257 41 | 14 98 215 260 42 | 15 94 220 265 43 | 15 95 221 266 44 | 15 98 224 269 45 | 16 92 227 263 46 | 17 94 238 265 47 | 17 98 242 269 48 | 18 104 167 248 49 | 19 99 171 243 50 | 19 106 178 250 51 | 19 107 179 251 52 | 20 99 180 243 53 | 20 103 184 247 54 | 20 106 187 250 55 | 20 107 188 251 56 | 21 100 190 253 57 | 21 103 193 256 58 | 21 107 197 260 59 | 22 99 198 252 60 | 22 100 199 253 61 | 22 103 202 256 62 | 23 101 209 254 63 | 24 105 222 267 64 | 25 100 226 262 65 | 25 103 229 265 66 | 25 106 232 268 67 | 26 100 235 262 68 | 26 102 237 264 69 | 26 103 238 265 70 | 26 107 242 269 71 | 27 110 164 272 72 | 28 108 171 270 73 | 28 114 177 276 74 | 28 115 178 277 75 | 28 116 179 278 76 | 29 108 180 270 77 | 29 114 186 276 78 | 29 115 187 277 79 | 29 116 188 278 80 | 30 109 190 280 81 | 30 113 194 284 82 | 30 116 197 287 83 | 31 108 198 279 84 | 31 109 199 280 85 | 31 113 203 284 86 | 31 115 205 286 87 | 32 112 211 283 88 | 33 111 219 291 89 | 34 108 225 288 90 | 34 109 226 289 91 | 34 113 230 293 92 | 34 114 231 294 93 | 35 109 235 289 94 | 35 114 240 294 95 | 36 117 162 270 96 | 36 121 166 274 97 | 36 123 168 276 98 | 36 124 169 277 99 | 37 122 176 275 100 | 38 117 180 270 101 | 38 121 184 274 102 | 38 123 186 276 103 | 38 124 187 277 104 | 39 118 190 280 105 | 39 120 192 282 106 | 40 119 200 281 107 | 41 117 207 279 108 | 41 118 208 280 109 | 41 120 210 282 110 | 41 124 214 286 111 | 42 117 216 288 112 | 42 118 217 289 113 | 42 121 220 292 114 | 43 125 233 296 115 | 44 118 235 289 116 | 44 121 238 292 117 | 44 123 240 294 118 | 45 126 162 270 119 | 45 130 166 274 120 | 45 134 170 278 121 | 46 126 171 270 122 | 46 129 174 273 123 | 46 134 179 278 124 | 47 127 181 271 125 | 48 132 195 285 126 | 49 126 198 279 127 | 49 131 203 284 128 | 50 126 207 279 129 | 50 129 210 282 130 | 50 131 212 284 131 | 50 134 215 287 132 | 51 126 216 288 133 | 51 128 218 290 134 | 51 130 220 292 135 | 51 131 221 293 136 | 52 126 225 288 137 | 52 130 229 292 138 | 52 131 230 293 139 | 53 133 241 295 140 | 54 136 163 298 141 | 54 141 168 303 142 | 54 142 169 304 143 | 54 143 170 305 144 | 55 141 177 303 145 | 55 142 178 304 146 | 55 143 179 305 147 | 56 137 182 299 148 | 57 135 189 306 149 | 58 136 199 307 150 | 58 139 202 310 151 | 58 142 205 313 152 | 59 136 208 307 153 | 59 138 210 309 154 | 59 142 214 313 155 | 60 136 217 316 156 | 60 139 220 319 157 | 60 143 224 323 158 | 61 136 226 316 159 | 61 139 229 319 160 | 61 141 231 321 161 | 62 140 239 320 162 | 63 144 162 297 163 | 63 145 163 298 164 | 63 150 168 303 165 | 63 151 169 304 166 | 64 148 175 301 167 | 65 144 180 297 168 | 65 149 185 302 169 | 65 150 186 303 170 | 65 151 187 304 171 | 66 145 190 307 172 | 66 146 191 308 173 | 66 149 194 311 174 | 67 152 206 314 175 | 68 145 208 307 176 | 68 149 212 311 177 | 68 151 214 313 178 | 69 144 216 315 179 | 69 145 217 316 180 | 69 146 218 317 181 | 70 147 228 318 182 | 71 145 235 316 183 | 71 146 236 317 184 | 71 150 240 321 185 | 72 156 165 300 186 | 73 153 171 297 187 | 73 161 179 305 188 | 74 153 180 297 189 | 74 158 185 302 190 | 74 161 188 305 191 | 75 154 190 307 192 | 75 155 191 308 193 | 75 157 193 310 194 | 75 158 194 311 195 | 76 154 199 307 196 | 76 157 202 310 197 | 76 158 203 311 198 | 77 159 213 312 199 | 78 160 223 322 200 | 79 153 225 315 201 | 79 154 226 316 202 | 79 157 229 319 203 | 80 154 235 316 204 | 80 155 236 317 205 | 80 157 238 319 206 | 80 161 242 323 207 | -------------------------------------------------------------------------------- /sudoku_sets/sudoku_convert.txt: -------------------------------------------------------------------------------- 1 | 0 81 162 243 2 | 0 82 163 244 3 | 0 83 164 245 4 | 0 84 165 246 5 | 0 85 166 247 6 | 0 86 167 248 7 | 0 87 168 249 8 | 0 88 169 250 9 | 0 89 170 251 10 | 1 81 171 243 11 | 1 82 172 244 12 | 1 83 173 245 13 | 1 84 174 246 14 | 1 85 175 247 15 | 1 86 176 248 16 | 1 87 177 249 17 | 1 88 178 250 18 | 1 89 179 251 19 | 2 81 180 243 20 | 2 82 181 244 21 | 2 83 182 245 22 | 2 84 183 246 23 | 2 85 184 247 24 | 2 86 185 248 25 | 2 87 186 249 26 | 2 88 187 250 27 | 2 89 188 251 28 | 3 81 189 252 29 | 3 82 190 253 30 | 3 83 191 254 31 | 3 84 192 255 32 | 3 85 193 256 33 | 3 86 194 257 34 | 3 87 195 258 35 | 3 88 196 259 36 | 3 89 197 260 37 | 4 81 198 252 38 | 4 82 199 253 39 | 4 83 200 254 40 | 4 84 201 255 41 | 4 85 202 256 42 | 4 86 203 257 43 | 4 87 204 258 44 | 4 88 205 259 45 | 4 89 206 260 46 | 5 81 207 252 47 | 5 82 208 253 48 | 5 83 209 254 49 | 5 84 210 255 50 | 5 85 211 256 51 | 5 86 212 257 52 | 5 87 213 258 53 | 5 88 214 259 54 | 5 89 215 260 55 | 6 81 216 261 56 | 6 82 217 262 57 | 6 83 218 263 58 | 6 84 219 264 59 | 6 85 220 265 60 | 6 86 221 266 61 | 6 87 222 267 62 | 6 88 223 268 63 | 6 89 224 269 64 | 7 81 225 261 65 | 7 82 226 262 66 | 7 83 227 263 67 | 7 84 228 264 68 | 7 85 229 265 69 | 7 86 230 266 70 | 7 87 231 267 71 | 7 88 232 268 72 | 7 89 233 269 73 | 8 81 234 261 74 | 8 82 235 262 75 | 8 83 236 263 76 | 8 84 237 264 77 | 8 85 238 265 78 | 8 86 239 266 79 | 8 87 240 267 80 | 8 88 241 268 81 | 8 89 242 269 82 | 9 90 162 243 83 | 9 91 163 244 84 | 9 92 164 245 85 | 9 93 165 246 86 | 9 94 166 247 87 | 9 95 167 248 88 | 9 96 168 249 89 | 9 97 169 250 90 | 9 98 170 251 91 | 10 90 171 243 92 | 10 91 172 244 93 | 10 92 173 245 94 | 10 93 174 246 95 | 10 94 175 247 96 | 10 95 176 248 97 | 10 96 177 249 98 | 10 97 178 250 99 | 10 98 179 251 100 | 11 90 180 243 101 | 11 91 181 244 102 | 11 92 182 245 103 | 11 93 183 246 104 | 11 94 184 247 105 | 11 95 185 248 106 | 11 96 186 249 107 | 11 97 187 250 108 | 11 98 188 251 109 | 12 90 189 252 110 | 12 91 190 253 111 | 12 92 191 254 112 | 12 93 192 255 113 | 12 94 193 256 114 | 12 95 194 257 115 | 12 96 195 258 116 | 12 97 196 259 117 | 12 98 197 260 118 | 13 90 198 252 119 | 13 91 199 253 120 | 13 92 200 254 121 | 13 93 201 255 122 | 13 94 202 256 123 | 13 95 203 257 124 | 13 96 204 258 125 | 13 97 205 259 126 | 13 98 206 260 127 | 14 90 207 252 128 | 14 91 208 253 129 | 14 92 209 254 130 | 14 93 210 255 131 | 14 94 211 256 132 | 14 95 212 257 133 | 14 96 213 258 134 | 14 97 214 259 135 | 14 98 215 260 136 | 15 90 216 261 137 | 15 91 217 262 138 | 15 92 218 263 139 | 15 93 219 264 140 | 15 94 220 265 141 | 15 95 221 266 142 | 15 96 222 267 143 | 15 97 223 268 144 | 15 98 224 269 145 | 16 90 225 261 146 | 16 91 226 262 147 | 16 92 227 263 148 | 16 93 228 264 149 | 16 94 229 265 150 | 16 95 230 266 151 | 16 96 231 267 152 | 16 97 232 268 153 | 16 98 233 269 154 | 17 90 234 261 155 | 17 91 235 262 156 | 17 92 236 263 157 | 17 93 237 264 158 | 17 94 238 265 159 | 17 95 239 266 160 | 17 96 240 267 161 | 17 97 241 268 162 | 17 98 242 269 163 | 18 99 162 243 164 | 18 100 163 244 165 | 18 101 164 245 166 | 18 102 165 246 167 | 18 103 166 247 168 | 18 104 167 248 169 | 18 105 168 249 170 | 18 106 169 250 171 | 18 107 170 251 172 | 19 99 171 243 173 | 19 100 172 244 174 | 19 101 173 245 175 | 19 102 174 246 176 | 19 103 175 247 177 | 19 104 176 248 178 | 19 105 177 249 179 | 19 106 178 250 180 | 19 107 179 251 181 | 20 99 180 243 182 | 20 100 181 244 183 | 20 101 182 245 184 | 20 102 183 246 185 | 20 103 184 247 186 | 20 104 185 248 187 | 20 105 186 249 188 | 20 106 187 250 189 | 20 107 188 251 190 | 21 99 189 252 191 | 21 100 190 253 192 | 21 101 191 254 193 | 21 102 192 255 194 | 21 103 193 256 195 | 21 104 194 257 196 | 21 105 195 258 197 | 21 106 196 259 198 | 21 107 197 260 199 | 22 99 198 252 200 | 22 100 199 253 201 | 22 101 200 254 202 | 22 102 201 255 203 | 22 103 202 256 204 | 22 104 203 257 205 | 22 105 204 258 206 | 22 106 205 259 207 | 22 107 206 260 208 | 23 99 207 252 209 | 23 100 208 253 210 | 23 101 209 254 211 | 23 102 210 255 212 | 23 103 211 256 213 | 23 104 212 257 214 | 23 105 213 258 215 | 23 106 214 259 216 | 23 107 215 260 217 | 24 99 216 261 218 | 24 100 217 262 219 | 24 101 218 263 220 | 24 102 219 264 221 | 24 103 220 265 222 | 24 104 221 266 223 | 24 105 222 267 224 | 24 106 223 268 225 | 24 107 224 269 226 | 25 99 225 261 227 | 25 100 226 262 228 | 25 101 227 263 229 | 25 102 228 264 230 | 25 103 229 265 231 | 25 104 230 266 232 | 25 105 231 267 233 | 25 106 232 268 234 | 25 107 233 269 235 | 26 99 234 261 236 | 26 100 235 262 237 | 26 101 236 263 238 | 26 102 237 264 239 | 26 103 238 265 240 | 26 104 239 266 241 | 26 105 240 267 242 | 26 106 241 268 243 | 26 107 242 269 244 | 27 108 162 270 245 | 27 109 163 271 246 | 27 110 164 272 247 | 27 111 165 273 248 | 27 112 166 274 249 | 27 113 167 275 250 | 27 114 168 276 251 | 27 115 169 277 252 | 27 116 170 278 253 | 28 108 171 270 254 | 28 109 172 271 255 | 28 110 173 272 256 | 28 111 174 273 257 | 28 112 175 274 258 | 28 113 176 275 259 | 28 114 177 276 260 | 28 115 178 277 261 | 28 116 179 278 262 | 29 108 180 270 263 | 29 109 181 271 264 | 29 110 182 272 265 | 29 111 183 273 266 | 29 112 184 274 267 | 29 113 185 275 268 | 29 114 186 276 269 | 29 115 187 277 270 | 29 116 188 278 271 | 30 108 189 279 272 | 30 109 190 280 273 | 30 110 191 281 274 | 30 111 192 282 275 | 30 112 193 283 276 | 30 113 194 284 277 | 30 114 195 285 278 | 30 115 196 286 279 | 30 116 197 287 280 | 31 108 198 279 281 | 31 109 199 280 282 | 31 110 200 281 283 | 31 111 201 282 284 | 31 112 202 283 285 | 31 113 203 284 286 | 31 114 204 285 287 | 31 115 205 286 288 | 31 116 206 287 289 | 32 108 207 279 290 | 32 109 208 280 291 | 32 110 209 281 292 | 32 111 210 282 293 | 32 112 211 283 294 | 32 113 212 284 295 | 32 114 213 285 296 | 32 115 214 286 297 | 32 116 215 287 298 | 33 108 216 288 299 | 33 109 217 289 300 | 33 110 218 290 301 | 33 111 219 291 302 | 33 112 220 292 303 | 33 113 221 293 304 | 33 114 222 294 305 | 33 115 223 295 306 | 33 116 224 296 307 | 34 108 225 288 308 | 34 109 226 289 309 | 34 110 227 290 310 | 34 111 228 291 311 | 34 112 229 292 312 | 34 113 230 293 313 | 34 114 231 294 314 | 34 115 232 295 315 | 34 116 233 296 316 | 35 108 234 288 317 | 35 109 235 289 318 | 35 110 236 290 319 | 35 111 237 291 320 | 35 112 238 292 321 | 35 113 239 293 322 | 35 114 240 294 323 | 35 115 241 295 324 | 35 116 242 296 325 | 36 117 162 270 326 | 36 118 163 271 327 | 36 119 164 272 328 | 36 120 165 273 329 | 36 121 166 274 330 | 36 122 167 275 331 | 36 123 168 276 332 | 36 124 169 277 333 | 36 125 170 278 334 | 37 117 171 270 335 | 37 118 172 271 336 | 37 119 173 272 337 | 37 120 174 273 338 | 37 121 175 274 339 | 37 122 176 275 340 | 37 123 177 276 341 | 37 124 178 277 342 | 37 125 179 278 343 | 38 117 180 270 344 | 38 118 181 271 345 | 38 119 182 272 346 | 38 120 183 273 347 | 38 121 184 274 348 | 38 122 185 275 349 | 38 123 186 276 350 | 38 124 187 277 351 | 38 125 188 278 352 | 39 117 189 279 353 | 39 118 190 280 354 | 39 119 191 281 355 | 39 120 192 282 356 | 39 121 193 283 357 | 39 122 194 284 358 | 39 123 195 285 359 | 39 124 196 286 360 | 39 125 197 287 361 | 40 117 198 279 362 | 40 118 199 280 363 | 40 119 200 281 364 | 40 120 201 282 365 | 40 121 202 283 366 | 40 122 203 284 367 | 40 123 204 285 368 | 40 124 205 286 369 | 40 125 206 287 370 | 41 117 207 279 371 | 41 118 208 280 372 | 41 119 209 281 373 | 41 120 210 282 374 | 41 121 211 283 375 | 41 122 212 284 376 | 41 123 213 285 377 | 41 124 214 286 378 | 41 125 215 287 379 | 42 117 216 288 380 | 42 118 217 289 381 | 42 119 218 290 382 | 42 120 219 291 383 | 42 121 220 292 384 | 42 122 221 293 385 | 42 123 222 294 386 | 42 124 223 295 387 | 42 125 224 296 388 | 43 117 225 288 389 | 43 118 226 289 390 | 43 119 227 290 391 | 43 120 228 291 392 | 43 121 229 292 393 | 43 122 230 293 394 | 43 123 231 294 395 | 43 124 232 295 396 | 43 125 233 296 397 | 44 117 234 288 398 | 44 118 235 289 399 | 44 119 236 290 400 | 44 120 237 291 401 | 44 121 238 292 402 | 44 122 239 293 403 | 44 123 240 294 404 | 44 124 241 295 405 | 44 125 242 296 406 | 45 126 162 270 407 | 45 127 163 271 408 | 45 128 164 272 409 | 45 129 165 273 410 | 45 130 166 274 411 | 45 131 167 275 412 | 45 132 168 276 413 | 45 133 169 277 414 | 45 134 170 278 415 | 46 126 171 270 416 | 46 127 172 271 417 | 46 128 173 272 418 | 46 129 174 273 419 | 46 130 175 274 420 | 46 131 176 275 421 | 46 132 177 276 422 | 46 133 178 277 423 | 46 134 179 278 424 | 47 126 180 270 425 | 47 127 181 271 426 | 47 128 182 272 427 | 47 129 183 273 428 | 47 130 184 274 429 | 47 131 185 275 430 | 47 132 186 276 431 | 47 133 187 277 432 | 47 134 188 278 433 | 48 126 189 279 434 | 48 127 190 280 435 | 48 128 191 281 436 | 48 129 192 282 437 | 48 130 193 283 438 | 48 131 194 284 439 | 48 132 195 285 440 | 48 133 196 286 441 | 48 134 197 287 442 | 49 126 198 279 443 | 49 127 199 280 444 | 49 128 200 281 445 | 49 129 201 282 446 | 49 130 202 283 447 | 49 131 203 284 448 | 49 132 204 285 449 | 49 133 205 286 450 | 49 134 206 287 451 | 50 126 207 279 452 | 50 127 208 280 453 | 50 128 209 281 454 | 50 129 210 282 455 | 50 130 211 283 456 | 50 131 212 284 457 | 50 132 213 285 458 | 50 133 214 286 459 | 50 134 215 287 460 | 51 126 216 288 461 | 51 127 217 289 462 | 51 128 218 290 463 | 51 129 219 291 464 | 51 130 220 292 465 | 51 131 221 293 466 | 51 132 222 294 467 | 51 133 223 295 468 | 51 134 224 296 469 | 52 126 225 288 470 | 52 127 226 289 471 | 52 128 227 290 472 | 52 129 228 291 473 | 52 130 229 292 474 | 52 131 230 293 475 | 52 132 231 294 476 | 52 133 232 295 477 | 52 134 233 296 478 | 53 126 234 288 479 | 53 127 235 289 480 | 53 128 236 290 481 | 53 129 237 291 482 | 53 130 238 292 483 | 53 131 239 293 484 | 53 132 240 294 485 | 53 133 241 295 486 | 53 134 242 296 487 | 54 135 162 297 488 | 54 136 163 298 489 | 54 137 164 299 490 | 54 138 165 300 491 | 54 139 166 301 492 | 54 140 167 302 493 | 54 141 168 303 494 | 54 142 169 304 495 | 54 143 170 305 496 | 55 135 171 297 497 | 55 136 172 298 498 | 55 137 173 299 499 | 55 138 174 300 500 | 55 139 175 301 501 | 55 140 176 302 502 | 55 141 177 303 503 | 55 142 178 304 504 | 55 143 179 305 505 | 56 135 180 297 506 | 56 136 181 298 507 | 56 137 182 299 508 | 56 138 183 300 509 | 56 139 184 301 510 | 56 140 185 302 511 | 56 141 186 303 512 | 56 142 187 304 513 | 56 143 188 305 514 | 57 135 189 306 515 | 57 136 190 307 516 | 57 137 191 308 517 | 57 138 192 309 518 | 57 139 193 310 519 | 57 140 194 311 520 | 57 141 195 312 521 | 57 142 196 313 522 | 57 143 197 314 523 | 58 135 198 306 524 | 58 136 199 307 525 | 58 137 200 308 526 | 58 138 201 309 527 | 58 139 202 310 528 | 58 140 203 311 529 | 58 141 204 312 530 | 58 142 205 313 531 | 58 143 206 314 532 | 59 135 207 306 533 | 59 136 208 307 534 | 59 137 209 308 535 | 59 138 210 309 536 | 59 139 211 310 537 | 59 140 212 311 538 | 59 141 213 312 539 | 59 142 214 313 540 | 59 143 215 314 541 | 60 135 216 315 542 | 60 136 217 316 543 | 60 137 218 317 544 | 60 138 219 318 545 | 60 139 220 319 546 | 60 140 221 320 547 | 60 141 222 321 548 | 60 142 223 322 549 | 60 143 224 323 550 | 61 135 225 315 551 | 61 136 226 316 552 | 61 137 227 317 553 | 61 138 228 318 554 | 61 139 229 319 555 | 61 140 230 320 556 | 61 141 231 321 557 | 61 142 232 322 558 | 61 143 233 323 559 | 62 135 234 315 560 | 62 136 235 316 561 | 62 137 236 317 562 | 62 138 237 318 563 | 62 139 238 319 564 | 62 140 239 320 565 | 62 141 240 321 566 | 62 142 241 322 567 | 62 143 242 323 568 | 63 144 162 297 569 | 63 145 163 298 570 | 63 146 164 299 571 | 63 147 165 300 572 | 63 148 166 301 573 | 63 149 167 302 574 | 63 150 168 303 575 | 63 151 169 304 576 | 63 152 170 305 577 | 64 144 171 297 578 | 64 145 172 298 579 | 64 146 173 299 580 | 64 147 174 300 581 | 64 148 175 301 582 | 64 149 176 302 583 | 64 150 177 303 584 | 64 151 178 304 585 | 64 152 179 305 586 | 65 144 180 297 587 | 65 145 181 298 588 | 65 146 182 299 589 | 65 147 183 300 590 | 65 148 184 301 591 | 65 149 185 302 592 | 65 150 186 303 593 | 65 151 187 304 594 | 65 152 188 305 595 | 66 144 189 306 596 | 66 145 190 307 597 | 66 146 191 308 598 | 66 147 192 309 599 | 66 148 193 310 600 | 66 149 194 311 601 | 66 150 195 312 602 | 66 151 196 313 603 | 66 152 197 314 604 | 67 144 198 306 605 | 67 145 199 307 606 | 67 146 200 308 607 | 67 147 201 309 608 | 67 148 202 310 609 | 67 149 203 311 610 | 67 150 204 312 611 | 67 151 205 313 612 | 67 152 206 314 613 | 68 144 207 306 614 | 68 145 208 307 615 | 68 146 209 308 616 | 68 147 210 309 617 | 68 148 211 310 618 | 68 149 212 311 619 | 68 150 213 312 620 | 68 151 214 313 621 | 68 152 215 314 622 | 69 144 216 315 623 | 69 145 217 316 624 | 69 146 218 317 625 | 69 147 219 318 626 | 69 148 220 319 627 | 69 149 221 320 628 | 69 150 222 321 629 | 69 151 223 322 630 | 69 152 224 323 631 | 70 144 225 315 632 | 70 145 226 316 633 | 70 146 227 317 634 | 70 147 228 318 635 | 70 148 229 319 636 | 70 149 230 320 637 | 70 150 231 321 638 | 70 151 232 322 639 | 70 152 233 323 640 | 71 144 234 315 641 | 71 145 235 316 642 | 71 146 236 317 643 | 71 147 237 318 644 | 71 148 238 319 645 | 71 149 239 320 646 | 71 150 240 321 647 | 71 151 241 322 648 | 71 152 242 323 649 | 72 153 162 297 650 | 72 154 163 298 651 | 72 155 164 299 652 | 72 156 165 300 653 | 72 157 166 301 654 | 72 158 167 302 655 | 72 159 168 303 656 | 72 160 169 304 657 | 72 161 170 305 658 | 73 153 171 297 659 | 73 154 172 298 660 | 73 155 173 299 661 | 73 156 174 300 662 | 73 157 175 301 663 | 73 158 176 302 664 | 73 159 177 303 665 | 73 160 178 304 666 | 73 161 179 305 667 | 74 153 180 297 668 | 74 154 181 298 669 | 74 155 182 299 670 | 74 156 183 300 671 | 74 157 184 301 672 | 74 158 185 302 673 | 74 159 186 303 674 | 74 160 187 304 675 | 74 161 188 305 676 | 75 153 189 306 677 | 75 154 190 307 678 | 75 155 191 308 679 | 75 156 192 309 680 | 75 157 193 310 681 | 75 158 194 311 682 | 75 159 195 312 683 | 75 160 196 313 684 | 75 161 197 314 685 | 76 153 198 306 686 | 76 154 199 307 687 | 76 155 200 308 688 | 76 156 201 309 689 | 76 157 202 310 690 | 76 158 203 311 691 | 76 159 204 312 692 | 76 160 205 313 693 | 76 161 206 314 694 | 77 153 207 306 695 | 77 154 208 307 696 | 77 155 209 308 697 | 77 156 210 309 698 | 77 157 211 310 699 | 77 158 212 311 700 | 77 159 213 312 701 | 77 160 214 313 702 | 77 161 215 314 703 | 78 153 216 315 704 | 78 154 217 316 705 | 78 155 218 317 706 | 78 156 219 318 707 | 78 157 220 319 708 | 78 158 221 320 709 | 78 159 222 321 710 | 78 160 223 322 711 | 78 161 224 323 712 | 79 153 225 315 713 | 79 154 226 316 714 | 79 155 227 317 715 | 79 156 228 318 716 | 79 157 229 319 717 | 79 158 230 320 718 | 79 159 231 321 719 | 79 160 232 322 720 | 79 161 233 323 721 | 80 153 234 315 722 | 80 154 235 316 723 | 80 155 236 317 724 | 80 156 237 318 725 | 80 157 238 319 726 | 80 158 239 320 727 | 80 159 240 321 728 | 80 160 241 322 729 | 80 161 242 323 -------------------------------------------------------------------------------- /sudoku_sets/unsolvable_sudoku.txt: -------------------------------------------------------------------------------- 1 | 0 17 33 49 2 | 0 19 35 51 3 | 1 17 37 49 4 | 1 19 39 51 5 | 2 16 40 52 6 | 3 18 46 54 7 | 4 21 33 49 8 | 4 23 35 51 9 | 5 20 36 48 10 | 5 21 37 49 11 | 5 22 38 50 12 | 5 23 39 51 13 | 6 21 41 53 14 | 6 23 43 55 15 | 7 21 45 53 16 | 7 23 47 55 17 | 8 26 34 58 18 | 9 25 37 57 19 | 9 27 39 59 20 | 10 25 41 61 21 | 10 27 43 63 22 | 11 24 44 60 23 | 11 25 45 61 24 | 11 27 47 63 25 | 12 28 32 56 26 | 13 29 37 57 27 | 13 31 39 59 28 | 14 29 41 61 29 | 14 30 42 62 30 | 14 31 43 63 31 | 15 29 45 61 32 | 15 31 47 63 33 | -------------------------------------------------------------------------------- /test/compute_clt_witness.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | const char folder[] = "sudoku1"; 17 | static int 18 | test_levels(size_t flags, size_t kappa, size_t lambda) 19 | { 20 | int pows[kappa], top_level[kappa]; 21 | clt_state_t *s; 22 | clt_pp_t *pp; 23 | aes_randstate_t rng; 24 | clt_elem_t *value, *result; 25 | int ok = 1; 26 | 27 | clt_params_t params = { 28 | .lambda = lambda, 29 | .kappa = kappa, 30 | .nzs = kappa, 31 | .pows = top_level 32 | }; 33 | 34 | mpz_t *a; 35 | mpz_t target_product, false_product; 36 | 37 | value = clt_elem_new(); 38 | result = clt_elem_new(); 39 | 40 | printf("Testing levels: λ = %lu, κ = %lu\n", lambda, kappa); 41 | 42 | aes_randinit(rng); 43 | 44 | for (size_t i = 0; i < kappa; ++i) 45 | top_level[i] = 1; 46 | 47 | s = clt_state_new(¶ms, NULL, 0, flags, rng); 48 | pp = clt_pp_new(s); 49 | 50 | // Helper variable for computing intermediate products 51 | mpz_t intermediate; 52 | mpz_init(intermediate); 53 | 54 | char filename_buff[80]; 55 | FILE *f = NULL; 56 | 57 | 58 | mkdir(folder, 0777); 59 | sprintf(filename_buff, "%s/pp_l=%zu.enc", folder, lambda); 60 | f = fopen(filename_buff,"w"); 61 | clt_pp_fwrite(pp, f); 62 | if (f) fclose(f); 63 | 64 | for (size_t b_i = 0; b_i < 256; ++b_i) { 65 | sprintf(filename_buff, "%s/message_bit_%zu", folder, b_i); 66 | mkdir(filename_buff, 0777); 67 | 68 | a = malloc(kappa * sizeof(mpz_t)); 69 | mpz_init_set_ui(target_product, 1); 70 | mpz_init_set_ui(false_product, 1); 71 | mpz_array_init(*a, kappa, 1); 72 | for (size_t i = 0; i < kappa; i++) { 73 | mpz_urandomb_aes(a[i], rng, 2 * lambda); 74 | mpz_mul(target_product, a[i], target_product); 75 | } 76 | mpz_add_ui(false_product, target_product, 1); 77 | 78 | // Write set encodings to file 79 | for (size_t i = 0; i < 248; ++i) { 80 | // Reset from previous iterations 81 | mpz_set_ui(intermediate, 1); 82 | for (size_t j = 0; j < kappa; ++j) { 83 | pows[j] = 0; 84 | } 85 | 86 | for (size_t j = 0; j < 4; ++j) { 87 | uint16_t index = puzzle[i][j]; 88 | pows[index] = 1; 89 | mpz_mul(intermediate, a[index], intermediate); 90 | } 91 | 92 | clt_encode(value, s, 1, (const mpz_t *) &intermediate, pows); 93 | 94 | // Write out file 95 | sprintf(filename_buff, "%s/message_bit_%zu/set_%zu.enc", folder, b_i, i); 96 | f = fopen(filename_buff,"w"); 97 | clt_elem_fwrite(value, f); 98 | if (f) fclose(f); 99 | } 100 | 101 | // Bit encoding 102 | if (message[b_i] == 0) { 103 | clt_encode(value, s, 1, (const mpz_t *) &false_product, top_level); 104 | } else { 105 | clt_encode(value, s, 1, (const mpz_t *) &target_product, top_level); 106 | } 107 | 108 | sprintf(filename_buff, "%s/message_bit_%zu/message_bit.enc", folder, b_i); 109 | f = fopen(filename_buff,"w"); 110 | clt_elem_fwrite(value, f); 111 | if (f) fclose(f); 112 | 113 | printf("Wrote message bit %zu/256\n", b_i); 114 | } 115 | 116 | clt_pp_free(pp); 117 | clt_state_free(s); 118 | clt_elem_free(value); 119 | clt_elem_free(result); 120 | aes_randclear(rng); 121 | return !ok; 122 | } 123 | 124 | int main() { 125 | size_t flags = CLT_FLAG_VERBOSE | CLT_FLAG_OPT_CRT_TREE | CLT_FLAG_OPT_PARALLEL_ENCODE | CLT_FLAG_OPT_COMPOSITE_PS; 126 | if (test_levels(flags, 64, 20)) 127 | return 1; 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /test/test_clt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static size_t 12 | ram_usage(void) 13 | { 14 | FILE *fp; 15 | size_t rss = 0; 16 | if ((fp = fopen("/proc/self/statm", "r")) == NULL) 17 | return 0; 18 | if (fscanf(fp, "%*s%lu", &rss) != 1) { 19 | fclose(fp); 20 | return 0; 21 | } 22 | fclose(fp); 23 | return rss * sysconf(_SC_PAGESIZE) / 1024; 24 | } 25 | 26 | static int 27 | expect(char *desc, int expected, int recieved) 28 | { 29 | if (expected != recieved) { 30 | printf("\033[1;41m"); 31 | } 32 | printf("%s = %d", desc, recieved); 33 | if (expected != recieved) { 34 | printf("\033[0m"); 35 | } 36 | puts(""); 37 | return expected == recieved; 38 | } 39 | 40 | static int 41 | test(size_t flags, size_t nzs, size_t lambda, size_t kappa) 42 | { 43 | srand(time(NULL)); 44 | 45 | clt_state_t *mmap; 46 | clt_pp_t *pp; 47 | mpz_t *moduli, modulus; 48 | aes_randstate_t rng; 49 | int pows[nzs]; 50 | 51 | int ok = 1; 52 | 53 | aes_randinit(rng); 54 | for (size_t i = 0; i < nzs; i++) pows[i] = 1; 55 | mpz_init_set_ui(modulus, 2); 56 | 57 | clt_params_t params = { 58 | .lambda = lambda, 59 | .kappa = kappa, 60 | .nzs = nzs, 61 | .pows = pows, 62 | }; 63 | clt_opt_params_t opts = { 64 | .slots = 0, 65 | .moduli = &modulus, 66 | .nmoduli = 1, 67 | }; 68 | mmap = clt_state_new(¶ms, &opts, 0, flags, rng); 69 | pp = clt_pp_new(mmap); 70 | 71 | /* Test read/write */ 72 | 73 | { 74 | FILE *mmap_f; 75 | 76 | mmap_f = tmpfile(); 77 | if (clt_state_fwrite(mmap, mmap_f) == CLT_ERR) { 78 | fprintf(stderr, "clt_state_fwrite failed!\n"); 79 | exit(1); 80 | } 81 | clt_state_free(mmap); 82 | rewind(mmap_f); 83 | if ((mmap = clt_state_fread(mmap_f)) == NULL) { 84 | fprintf(stderr, "clt_state_fread failed!\n"); 85 | exit(1); 86 | } 87 | fclose(mmap_f); 88 | } 89 | 90 | { 91 | FILE *pp_f; 92 | 93 | pp_f = tmpfile(); 94 | if (pp_f == NULL) { 95 | fprintf(stderr, "Couldn't open tmpfile!\n"); 96 | exit(1); 97 | } 98 | if (clt_pp_fwrite(pp, pp_f) == CLT_ERR) { 99 | fprintf(stderr, "clt_pp_fwrite failed!\n"); 100 | exit(1); 101 | } 102 | clt_pp_free(pp); 103 | rewind(pp_f); 104 | if ((pp = clt_pp_fread(pp_f)) == NULL) { 105 | fprintf(stderr, "clt_pp_fread failed!\n"); 106 | exit(1); 107 | } 108 | fclose(pp_f); 109 | } 110 | 111 | moduli = clt_state_moduli(mmap); 112 | 113 | mpz_t x[1], zero[1], one[1], two[1], three[1]; 114 | int top_level[nzs]; 115 | 116 | mpz_init_set_ui(x[0], 0); 117 | while (mpz_cmp_ui(x[0], 0) <= 0) { 118 | mpz_set_ui(x[0], rand()); 119 | mpz_mod(x[0], x[0], moduli[0]); 120 | } 121 | gmp_printf("x = %Zd\n", x[0]); 122 | 123 | mpz_init_set_ui(zero[0], 0); 124 | mpz_init_set_ui(one[0], 1); 125 | mpz_init_set_ui(two[0], 2); 126 | mpz_init_set_ui(three[0], 3); 127 | 128 | for (size_t i = 0; i < nzs; i++) { 129 | top_level[i] = 1; 130 | } 131 | 132 | clt_elem_t *x0, *x1, *xp; 133 | x0 = clt_elem_new(); 134 | x1 = clt_elem_new(); 135 | xp = clt_elem_new(); 136 | 137 | clt_encode(x0, mmap, 1, (const mpz_t *) zero, top_level); 138 | clt_encode(x1, mmap, 1, (const mpz_t *) zero, top_level); 139 | clt_elem_add(xp, pp, x0, x1); 140 | ok &= expect("is_zero(0 + 0)", 1, clt_is_zero(xp, pp)); 141 | 142 | clt_encode(x0, mmap, 1, (const mpz_t *) zero, top_level); 143 | clt_encode(x1, mmap, 1, (const mpz_t *) one, top_level); 144 | ok &= expect("is_zero(0)", 1, clt_is_zero(x0, pp)); 145 | ok &= expect("is_zero(1)", 0, clt_is_zero(x1, pp)); 146 | clt_elem_add(xp, pp, x0, x1); 147 | ok &= expect("is_zero(0 + 1)", 0, clt_is_zero(xp, pp)); 148 | 149 | clt_encode(x0, mmap, 1, (const mpz_t *) one, top_level); 150 | clt_encode(x1, mmap, 1, (const mpz_t *) two, top_level); 151 | clt_elem_mul_ui(x0, pp, x0, 2); 152 | clt_elem_sub(xp, pp, x1, x0); 153 | ok &= expect("is_zero(2 - 2[1])", 1, clt_is_zero(xp, pp)); 154 | 155 | clt_encode(x0, mmap, 1, (const mpz_t *) zero, top_level); 156 | clt_encode(x1, mmap, 1, (const mpz_t *) x, top_level); 157 | clt_elem_add(xp, pp, x0, x1); 158 | ok &= expect("is_zero(0 + x)", 0, clt_is_zero(xp, pp)); 159 | 160 | clt_encode(x0, mmap, 1, (const mpz_t *) x, top_level); 161 | clt_encode(x1, mmap, 1, (const mpz_t *) x, top_level); 162 | clt_elem_sub(xp, pp, x0, x1); 163 | ok &= expect("is_zero(x - x)", 1, clt_is_zero(xp, pp)); 164 | 165 | clt_encode(x0, mmap, 1, (const mpz_t *) zero, top_level); 166 | clt_encode(x1, mmap, 1, (const mpz_t *) x, top_level); 167 | clt_elem_sub(xp, pp, x0, x1); 168 | ok &= expect("is_zero(0 - x)", 0, clt_is_zero(xp, pp)); 169 | 170 | clt_encode(x0, mmap, 1, (const mpz_t *) one, top_level); 171 | clt_encode(x1, mmap, 1, (const mpz_t *) zero, top_level); 172 | clt_elem_sub(xp, pp, x0, x1); 173 | ok &= expect("is_zero(1 - 0)", 0, clt_is_zero(xp, pp)); 174 | 175 | clt_encode(x0, mmap, 1, (const mpz_t *) one, top_level); 176 | clt_encode(x1, mmap, 1, (const mpz_t *) three, top_level); 177 | clt_elem_mul_ui(x0, pp, x0, 3); 178 | clt_elem_sub(xp, pp, x0, x1); 179 | ok &= expect("is_zero(3*[1] - [3])", 1, clt_is_zero(xp, pp)); 180 | 181 | int ix0[nzs], ix1[nzs]; 182 | for (size_t i = 0; i < nzs; i++) { 183 | if (i < nzs / 2) { 184 | ix0[i] = 1; 185 | ix1[i] = 0; 186 | } else { 187 | ix0[i] = 0; 188 | ix1[i] = 1; 189 | } 190 | } 191 | clt_encode(x0, mmap, 1, (const mpz_t *) x , ix0); 192 | clt_encode(x1, mmap, 1, (const mpz_t *) zero, ix1); 193 | clt_elem_mul(xp, pp, x0, x1); 194 | ok &= expect("is_zero(x * 0)", 1, clt_is_zero(xp, pp)); 195 | 196 | clt_encode(x0, mmap, 1, (const mpz_t *) x , ix0); 197 | clt_encode(x1, mmap, 1, (const mpz_t *) one, ix1); 198 | clt_elem_mul(xp, pp, x0, x1); 199 | ok &= expect("is_zero(x * 1)", 0, clt_is_zero(xp, pp)); 200 | 201 | clt_encode(x0, mmap, 1, (const mpz_t *) x, ix0); 202 | clt_encode(x1, mmap, 1, (const mpz_t *) x, ix1); 203 | clt_elem_mul(xp, pp, x0, x1); 204 | ok &= expect("is_zero(x * x)", 0, clt_is_zero(xp, pp)); 205 | 206 | // zimmerman-like test 207 | 208 | mpz_t in0[2], in1[2], cin[2]; 209 | clt_elem_t *c = clt_elem_new(); 210 | 211 | mpz_inits(in0[0], in0[1], in1[0], in1[1], cin[0], cin[1], NULL); 212 | 213 | mpz_set_ui (in0[0], 0); 214 | mpz_urandomb_aes(in0[1], rng, lambda); 215 | mpz_mod (in0[1], in0[1], moduli[1]); 216 | 217 | mpz_urandomb_aes(in1[0], rng, lambda); 218 | mpz_mod (in1[0], in1[0], moduli[0]); 219 | mpz_urandomb_aes(in1[1], rng, lambda); 220 | mpz_mod (in1[1], in1[1], moduli[1]); 221 | 222 | mpz_set_ui(cin[0], 0); 223 | mpz_mul (cin[1], in0[1], in1[1]); 224 | 225 | clt_encode(x0, mmap, 2, (const mpz_t *) in0, ix0); 226 | clt_encode(x1, mmap, 2, (const mpz_t *) in1, ix1); 227 | clt_encode(c, mmap, 2, (const mpz_t *) cin, top_level); 228 | 229 | clt_elem_mul(xp, pp, x0, x1); 230 | clt_elem_sub(xp, pp, xp, c); 231 | 232 | ok &= expect("[Z] is_zero(0 * x)", 1, clt_is_zero(xp, pp)); 233 | 234 | /* [ $, $ ] */ 235 | mpz_urandomb_aes(in0[0], rng, lambda); 236 | mpz_mod (in0[0], in0[0], moduli[0]); 237 | mpz_urandomb_aes(in0[1], rng, lambda); 238 | mpz_mod (in0[1], in0[1], moduli[1]); 239 | /* [ $, $ ] */ 240 | mpz_urandomb_aes(in1[0], rng, lambda); 241 | mpz_mod (in1[0], in1[0], moduli[0]); 242 | mpz_urandomb_aes(in1[1], rng, lambda); 243 | mpz_mod (in1[1], in1[1], moduli[1]); 244 | 245 | mpz_set_ui (cin[0], 0); 246 | mpz_urandomb_aes(cin[1], rng, lambda); 247 | mpz_mod (cin[1], cin[1], moduli[1]); 248 | /* mpz_mul (cin[1], in0[1], in1[1]); */ 249 | 250 | clt_encode(x0, mmap, 2, (const mpz_t *) in0, ix0); 251 | clt_encode(x1, mmap, 2, (const mpz_t *) in1, ix1); 252 | clt_encode(c, mmap, 2, (const mpz_t *) cin, top_level); 253 | 254 | clt_elem_mul(xp, pp, x0, x1); 255 | clt_elem_sub(xp, pp, xp, c); 256 | 257 | ok &= expect("[Z] is_zero(x * y)", 0, clt_is_zero(xp, pp)); 258 | 259 | mpz_clears(x[0], zero[0], one[0], two[0], three[0], 260 | in0[0], in0[1], in1[0], in1[1], cin[0], cin[1], NULL); 261 | 262 | clt_elem_free(c); 263 | clt_elem_free(x0); 264 | clt_elem_free(x1); 265 | clt_elem_free(xp); 266 | clt_pp_free(pp); 267 | clt_state_free(mmap); 268 | aes_randclear(rng); 269 | 270 | { 271 | size_t ram = ram_usage(); 272 | printf("RAM: %lu Kb\n", ram); 273 | } 274 | 275 | return !ok; 276 | } 277 | 278 | static int 279 | test_levels(size_t flags, size_t kappa, size_t lambda) 280 | { 281 | int pows[kappa], top_level[kappa]; 282 | clt_state_t *s; 283 | clt_pp_t *pp; 284 | aes_randstate_t rng; 285 | mpz_t zero, one; 286 | clt_elem_t *value, *result, *top_one, *top_zero; 287 | int ok = 1; 288 | 289 | clt_params_t params = { 290 | .lambda = lambda, 291 | .kappa = kappa, 292 | .nzs = kappa, 293 | .pows = top_level 294 | }; 295 | 296 | value = clt_elem_new(); 297 | result = clt_elem_new(); 298 | top_one = clt_elem_new(); 299 | top_zero = clt_elem_new(); 300 | 301 | printf("Testing levels: λ = %lu, κ = %lu\n", lambda, kappa); 302 | 303 | aes_randinit(rng); 304 | mpz_init_set_ui(zero, 0); 305 | mpz_init_set_ui(one, 1); 306 | 307 | for (size_t i = 0; i < kappa; ++i) 308 | top_level[i] = 1; 309 | 310 | s = clt_state_new(¶ms, NULL, 0, flags, rng); 311 | pp = clt_pp_new(s); 312 | 313 | clt_encode(top_one, s, 1, (const mpz_t *) &one, top_level); 314 | clt_encode(top_zero, s, 1, (const mpz_t *) &zero, top_level); 315 | 316 | for (size_t i = 0; i < kappa; ++i) { 317 | for (size_t j = 0; j < kappa; ++j) { 318 | if (j != i) 319 | pows[j] = 0; 320 | else 321 | pows[j] = 1; 322 | } 323 | clt_encode(value, s, 1, (const mpz_t *) &one, pows); 324 | if (i == 0) 325 | clt_elem_set(result, value); 326 | else { 327 | clt_elem_mul(result, pp, result, value); 328 | } 329 | } 330 | 331 | ok &= expect("is_zero(1 * ... * 1)", 0, clt_is_zero(result, pp)); 332 | 333 | clt_elem_sub(result, pp, result, top_one); 334 | 335 | ok &= expect("is_zero(1 * ... * 1 - 1)", 1, clt_is_zero(result, pp)); 336 | 337 | for (size_t i = 0; i < kappa; ++i) { 338 | for (size_t j = 0; j < kappa; ++j) { 339 | if (j != i) 340 | pows[j] = 0; 341 | else 342 | pows[j] = 1; 343 | } 344 | if (i == 0) { 345 | clt_encode(value, s, 1, (const mpz_t *) &zero, pows); 346 | clt_elem_set(result, value); 347 | } else { 348 | clt_encode(value, s, 1, (const mpz_t *) &one, pows); 349 | clt_elem_mul(result, pp, result, value); 350 | } 351 | } 352 | 353 | ok &= expect("is_zero(0 * 1 * ... * 1)", 1, clt_is_zero(result, pp)); 354 | 355 | clt_elem_add(result, pp, result, top_one); 356 | 357 | ok &= expect("is_zero(0 * 1 * ... * 1 + 1)", 0, clt_is_zero(result, pp)); 358 | 359 | { 360 | size_t ram = ram_usage(); 361 | printf("RAM: %lu Kb\n", ram); 362 | } 363 | 364 | clt_pp_free(pp); 365 | clt_state_free(s); 366 | 367 | mpz_clears(zero, one, NULL); 368 | clt_elem_free(value); 369 | clt_elem_free(result); 370 | clt_elem_free(top_one); 371 | clt_elem_free(top_zero); 372 | aes_randclear(rng); 373 | 374 | return !ok; 375 | } 376 | 377 | int 378 | main(int argc, char *argv[]) 379 | { 380 | size_t default_flags = CLT_FLAG_NONE | CLT_FLAG_VERBOSE; 381 | size_t flags; 382 | size_t kappa; 383 | size_t lambda = 20; 384 | size_t nzs = 10; 385 | 386 | if (argc == 2) { 387 | lambda = atoi(argv[1]); 388 | } 389 | 390 | if (test_levels(default_flags, 32, 10)) 391 | return 1; 392 | 393 | printf("* No optimizations\n"); 394 | flags = default_flags; 395 | if (test(flags, nzs, 16, 2) == 1) 396 | return 1; 397 | 398 | kappa = 15; 399 | 400 | printf("* No optimizations\n"); 401 | flags = default_flags; 402 | if (test(flags, nzs, lambda, kappa) == 1) 403 | return 1; 404 | 405 | printf("* CRT tree\n"); 406 | flags = default_flags | CLT_FLAG_OPT_CRT_TREE; 407 | if (test(flags, nzs, lambda, kappa) == 1) 408 | return 1; 409 | 410 | printf("* CRT tree + parallel encode\n"); 411 | flags = default_flags | CLT_FLAG_OPT_CRT_TREE | CLT_FLAG_OPT_PARALLEL_ENCODE; 412 | if (test(flags, nzs, lambda, kappa) == 1) 413 | return 1; 414 | 415 | printf("* CRT tree + composite ps\n"); 416 | flags = default_flags | CLT_FLAG_OPT_CRT_TREE | CLT_FLAG_OPT_COMPOSITE_PS; 417 | if (test(flags, nzs, lambda, kappa) == 1) 418 | return 1; 419 | 420 | printf("* CRT tree + parallel encode + composite ps\n"); 421 | flags = default_flags | CLT_FLAG_OPT_CRT_TREE | CLT_FLAG_OPT_PARALLEL_ENCODE | CLT_FLAG_OPT_COMPOSITE_PS; 422 | if (test(flags, nzs, lambda, kappa) == 1) 423 | return 1; 424 | 425 | kappa = 12; 426 | printf("* CRT tree + parallel encode + composite ps\n"); 427 | flags = default_flags | CLT_FLAG_OPT_CRT_TREE | CLT_FLAG_OPT_PARALLEL_ENCODE | CLT_FLAG_OPT_COMPOSITE_PS; 428 | if (test(flags, nzs, lambda, kappa) == 1) 429 | return 1; 430 | 431 | return 0; 432 | } 433 | -------------------------------------------------------------------------------- /test/test_clt_state_new.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static int lambda = 60; 6 | static int kappa = 21; 7 | static int nzs = 17; 8 | static size_t flags = CLT_FLAG_VERBOSE | CLT_FLAG_OPT_CRT_TREE | CLT_FLAG_OPT_COMPOSITE_PS | CLT_FLAG_SEC_IMPROVED_BKZ; 9 | 10 | static double 11 | current_time(void) 12 | { 13 | struct timeval t; 14 | gettimeofday(&t, NULL); 15 | return t.tv_sec + (double) (t.tv_usec / 1000000.0); 16 | } 17 | 18 | int 19 | main(void) 20 | { 21 | clt_state_t *s; 22 | int pows[nzs]; 23 | aes_randstate_t rng; 24 | int ret = 1; 25 | double start; 26 | 27 | clt_params_t params = { 28 | .lambda = lambda, 29 | .kappa = kappa, 30 | .nzs = nzs, 31 | .pows = pows 32 | }; 33 | 34 | aes_randinit(rng); 35 | for (int i = 0; i < nzs; ++i) 36 | pows[i] = 1; 37 | 38 | 39 | start = current_time(); 40 | s = clt_state_new(¶ms, NULL, 0, flags, rng); 41 | if (s == NULL) 42 | goto cleanup; 43 | fprintf(stderr, "Parameter Generation Time: %.2fs\n", current_time() - start); 44 | 45 | { 46 | clt_elem_t *x; 47 | mpz_t zero[1]; 48 | 49 | x = clt_elem_new(); 50 | mpz_init_set_ui(zero[0], 0); 51 | 52 | fprintf(stderr, "Encoding...\n"); 53 | start = current_time(); 54 | clt_encode(x, s, 1, (const mpz_t *) zero, pows); 55 | fprintf(stderr, "Encoding Time: %.2fs\n", current_time() - start); 56 | 57 | { 58 | FILE *f = NULL; 59 | struct stat st; 60 | 61 | f = tmpfile(); 62 | if (clt_elem_fwrite(x, f) == CLT_ERR) { 63 | fprintf(stderr, "Failed writing element to disk\n"); 64 | return 1; 65 | } 66 | fstat(fileno(f), &st); 67 | fprintf(stderr, "Encoding Size: %ld KB\n", st.st_size / 1024); 68 | if (f) 69 | fclose(f); 70 | } 71 | clt_elem_free(x); 72 | mpz_clear(zero[0]); 73 | } 74 | 75 | clt_state_free(s); 76 | ret = 0; 77 | cleanup: 78 | aes_randclear(rng); 79 | return ret; 80 | } 81 | -------------------------------------------------------------------------------- /test/test_clt_witness_scheme.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | static int 15 | expect(char *desc, int expected, int recieved) 16 | { 17 | if (expected != recieved) { 18 | printf("\033[1;41m"); 19 | } 20 | printf("%s = %d", desc, recieved); 21 | if (expected != recieved) { 22 | printf("\033[0m"); 23 | } 24 | puts(""); 25 | return expected == recieved; 26 | } 27 | 28 | static int 29 | test_levels(size_t flags, size_t kappa, size_t lambda) 30 | { 31 | int pows[kappa], top_level[kappa]; 32 | clt_state_t *s; 33 | clt_pp_t *pp; 34 | aes_randstate_t rng; 35 | clt_elem_t *value, *result, *top_target; 36 | int ok = 1; 37 | 38 | clt_params_t params = { 39 | .lambda = lambda, 40 | .kappa = kappa, 41 | .nzs = kappa, 42 | .pows = top_level 43 | }; 44 | 45 | mpz_t *a; 46 | mpz_t target_product; 47 | mpz_t test_product; 48 | a = malloc(kappa * sizeof(mpz_t)); 49 | mpz_init_set_ui(target_product, 1); 50 | mpz_init_set_ui(test_product, 1); 51 | mpz_array_init(*a, kappa, 1); 52 | for (size_t i = 0; i < kappa; i++) { 53 | mpz_urandomb_aes(a[i], rng, 2 * lambda); 54 | mpz_mul(target_product, a[i], target_product); 55 | } 56 | 57 | value = clt_elem_new(); 58 | result = clt_elem_new(); 59 | top_target = clt_elem_new(); 60 | 61 | printf("Testing levels: λ = %lu, κ = %lu\n", lambda, kappa); 62 | 63 | aes_randinit(rng); 64 | 65 | for (size_t i = 0; i < kappa; ++i) 66 | top_level[i] = 1; 67 | 68 | s = clt_state_new(¶ms, NULL, 0, flags, rng); 69 | pp = clt_pp_new(s); 70 | 71 | mpz_t intermediate; 72 | mpz_init(intermediate); 73 | for (size_t i = 0; i < 3; ++i) { 74 | mpz_set_ui(intermediate, 1); 75 | for (size_t j = 0; j < kappa; ++j) { 76 | pows[j] = 0; 77 | } 78 | 79 | for (size_t j = 0; j < 2; ++j) { 80 | uint16_t index = puzzle[i][j]; 81 | pows[index] = 1; 82 | mpz_mul(intermediate, a[index], intermediate); 83 | } 84 | 85 | 86 | clt_encode(value, s, 1, (const mpz_t *) &intermediate, pows); 87 | // Our witness is {0, 2} 88 | if (i == 0 || i == 2) { 89 | if (i == 0) 90 | clt_elem_set(result, value); 91 | else { 92 | clt_elem_mul(result, pp, result, value); 93 | } 94 | } 95 | } 96 | clt_encode(top_target, s, 1, (const mpz_t *) &target_product, top_level); 97 | 98 | ok &= expect("is_zero(1 * ... * 1)", 0, clt_is_zero(result, pp)); 99 | 100 | clt_elem_sub(result, pp, result, top_target); 101 | 102 | ok &= expect("is_zero(1 * ... * 1 - 1)", 1, clt_is_zero(result, pp)); 103 | 104 | clt_pp_free(pp); 105 | clt_state_free(s); 106 | clt_elem_free(value); 107 | clt_elem_free(result); 108 | clt_elem_free(top_target); 109 | aes_randclear(rng); 110 | 111 | return !ok; 112 | } 113 | 114 | int 115 | main() 116 | { 117 | size_t default_flags = CLT_FLAG_NONE | CLT_FLAG_VERBOSE; 118 | if (test_levels(default_flags, 4, 20)) 119 | return 1; 120 | return 0; 121 | } 122 | --------------------------------------------------------------------------------