├── Makefile ├── .gitmodules ├── README.md ├── COPYING ├── sampling.c ├── template ├── simulator.c └── diff_groups.h /Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -Wall -Wextra -O3 -march=native -g -std=c99 2 | LDLIBS = -lm 3 | 4 | all: simulator sampling 5 | 6 | .PHONY: all 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sha1_gpu_nearcollisionattacks"] 2 | path = sha1_gpu_nearcollisionattacks 3 | url = https://github.com/SHA-mbles/sha1_gpu_nearcollisionattacks 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SHA1 Chosen-prefix Collision Attack 2 | 3 | This repository contains additional data and code from two papers: 4 | 5 | > [*From Collisions to Chosen-Prefix Collisions — Application to Full SHA-1*](https://eprint.iacr.org/2019/459) 6 | > Gaëtan Leurent and Thomas Peyrin 7 | > Eurocrypt 2019 8 | 9 | > [*SHA-1 is a Shambles: First Chosen-Prefix Collision on SHA-1 and Application to the PGP Web of Trust*](https://eprint.iacr.org/2020/014.pdf) 10 | > Gaëtan Leurent and Thomas Peyrin 11 | > Usenix Security 2020 12 | 13 | 14 | ## Repository content 15 | 16 | This repository includes: 17 | 18 | 1. A full description of the **set of output differences** 𝓓 and the 19 | bundles used in the attack. This was obtained by sampling the last 20 | rounds of SHA-1, and extends the partial data given in 21 | Table 4 of the Eurocrypt paper. 22 | The set is described in file `diff_group.h`, and the program 23 | `sampling.c` can be used to verify the sampling. 24 | 25 | 2. A **simulator** for the attack, to enable easy verification of our 26 | claims (see below for details). This corresponds to the Eurocrypt attack. 27 | 28 | 3. A **graph** for the attack, corresponding to the set 𝓢 29 | with maximum cost 2×C_block_ (first line of Table 5). 30 | This corresponds to a variant of the Eurocrypt attack. 31 | Due to size limits, the graph is not in the git repo, but if available as part of the releases: 32 | https://github.com/Cryptosaurus/sha1-cp/releases/download/v1/diffset 33 | (Note: the graph only contains the nodes, the edges are recomputed on the fly) 34 | 35 | 4. The **GPU code** to generate near-collision blocks, improved from the 36 | code of the Shattered attack. 37 | This is the code from the Usenix attack. 38 | 39 | In order to make sure proper countermeasures can be deployed before 40 | harmful exploitation of SHA-1 chosen-prefix collisions, we are not 41 | releasing the full source code of the attack at this point. 42 | 43 | ## Attack simulator 44 | 45 | ### What the simulator does 46 | 47 | For each block, our simulator computes the message equations and list 48 | of useful output differences from the graph 𝓖 49 | and simulates the attack by picking random messages and internal 50 | states at step 64 until reaching a useful output difference. This 51 | validates both the overall attack strategy, and the sampling results; 52 | the simulation results closely match the claims in the paper. 53 | 54 | ### How to use it 55 | 56 | To compile the program, just run `make`. To use the simulator, you 57 | need a graph for the attack; you can download one with a release of 58 | the code: https://github.com/Cryptosaurus/sha1-cp/releases/download/v1/diffset 59 | 60 | There are several ways to use the attack simulator, here are a few example: 61 | 62 | 1. Generate conditions and path template for a given difference 63 | ``` 64 | ./simulator -sdiffset -dffffda04/fffffed4/fffffffc/fffffff8/00000000 -ttemplate 65 | ``` 66 | 67 | 2. Simulate attack form a random input difference in the set 68 | ``` 69 | ./simulator -sdiffset -b 70 | ``` 71 | 72 | ## CC0 Public Domain Dedication 73 | 74 | To the extent possible under law, the author(s) have dedicated all 75 | copyright and related and neighboring rights to this software to the 76 | public domain worldwide. This software is distributed without any 77 | warranty. You should have received a copy of the CC0 Public Domain 78 | Dedication along with this software. If not, see 79 | http://creativecommons.org/publicdomain/zero/1.0/. 80 | 81 | 82 | ## Contact 83 | 84 | If you have any questions, feel free to contact us: 85 | 86 | - Gaëtan Leurent: gaetan.leurent@inria.fr 87 | - Thomas Peyrin: thomas.peyrin@ntu.edu.sg 88 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /sampling.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) Gaëtan Leurent and Thomas Peyrin, 2018-2019 2 | 3 | // To the extent possible under law, the author(s) have dedicated all 4 | // copyright and related and neighboring rights to this software to the 5 | // public domain worldwide. This software is distributed without any 6 | // warranty. You should have received a copy of the CC0 Public Domain 7 | // Dedication along with this software. If not, see 8 | // . 9 | 10 | #define _XOPEN_SOURCE 600 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | #define tablength(t) (sizeof((t))/sizeof((t)[0])) 29 | 30 | uint32_t rotate_left(uint32_t x, int n) { 31 | n&=31; 32 | if (n==0) 33 | return n; 34 | return (x<>(32-n)); 35 | } 36 | 37 | struct diff_group { 38 | int z; 39 | struct {double p; uint32_t diff[5];} g[38]; 40 | }; 41 | 42 | struct diff_group diff_groups[] = { 43 | #include "diff_groups.h" 44 | }; 45 | 46 | int main() { 47 | 48 | srand(getpid()*0xdeadbeef + time(NULL)*0xbadc0ffe); 49 | 50 | int n = random()%tablength(diff_groups); 51 | 52 | printf ("Checking group %i (z=0b", n); 53 | for (int i=7; i>=0; i--) 54 | printf ("%i", (diff_groups[n].z>>i)&1); 55 | printf (")\n"); 56 | int z = ~diff_groups[n].z; 57 | printf (" Z conditions: z13=%i", ((z<<=1)>>13)&1); 58 | printf (" z12=%i", ((z<<=1)>>13)&1); 59 | printf (" z11=%i", ((z<<=1)>>13)&1); 60 | printf (" z10=%i", ((z<<=1)>>13)&1); 61 | printf (" z9=%i", ((z<<=1)>>13)&1); 62 | printf (" z1=%i", ((z<<=1)>>13)&1); 63 | printf (" z7=%i", ((z<<=1)>>13)&1); 64 | printf (" z2=%i", ((z<<=1)>>13)&1); 65 | printf (" z3=%i", ((z<<=1)>>13)&1); 66 | printf (" z8=%i", ((z<<=1)>>13)&1); 67 | printf (" z6=%i", ((z<<=1)>>13)&1); 68 | printf (" z4=%i", ((z<<=1)>>13)&1); 69 | printf (" z5=%i", ((z<<=1)>>13)&1); 70 | printf ("\n"); 71 | 72 | 73 | 74 | uint64_t count[tablength(diff_groups[n].g)] = {0}; 75 | 76 | #define SAMPLE (1ULL<<28) 77 | printf ("Using 2^%i samples\n", (int)log2(SAMPLE)); 78 | 79 | for (uint64_t t = 0; t < SAMPLE; t++) { 80 | // Random state at step 64 81 | uint32_t a1 = (rand()<<16) + rand(); 82 | uint32_t b1 = (rand()<<16) + rand(); 83 | uint32_t c1 = (rand()<<16) + rand(); 84 | uint32_t d1 = (rand()<<16) + rand(); 85 | uint32_t e1 = (rand()<<16) + rand(); 86 | 87 | uint32_t a2 = a1; 88 | uint32_t b2 = b1; 89 | uint32_t c2 = c1; 90 | uint32_t d2 = d1; 91 | uint32_t e2 = e1; 92 | 93 | // Random message 94 | uint32_t m[16]; // Last 16 message words 95 | for (int i=0; i<16; i++) 96 | m[i] = (rand()<<16) + rand(); 97 | 98 | #define setm(i,j,z) m[(i)-64] &= ~(1U<<(j)), m[(i)-64] |= (z)<<(j) 99 | 100 | // Apply zi conditions 101 | int z = ~diff_groups[n].z; 102 | setm(79, 4, ((z<<=1)>>13)&1); // z13 103 | setm(79, 2, ((z<<=1)>>13)&1); // z12 104 | setm(78, 7, ((z<<=1)>>13)&1); // z11 105 | setm(78, 3, ((z<<=1)>>13)&1); // z10 106 | setm(78, 0, ((z<<=1)>>13)&1); // z9 107 | setm(73, 2, ((z<<=1)>>13)&1); // z1 108 | setm(76, 3, ((z<<=1)>>13)&1); // z7 109 | setm(76, 1, ((z<<=1)>>13)&1); // z2 110 | setm(76, 0, ((z<<=1)>>13)&1); // z3 111 | setm(77, 8, ((z<<=1)>>13)&1); // z8 112 | setm(77, 2, ((z<<=1)>>13)&1); // z6 113 | setm(77, 1, ((z<<=1)>>13)&1); // z4 114 | setm(77, 0, ((z<<=1)>>13)&1); // z5 115 | 116 | // Apply message conditions 117 | setm(68, 5, (~m[3]>>0)&1); // 67[0]+68[5] = 1 118 | setm(72, 30, (~m[3]>>0)&1); // 67[0]+72[30] = 1 119 | setm(71, 6, (~m[6]>>1)&1); // 70[1]+71[6] = 1 120 | setm(72, 5, (~m[7]>>0)&1); // 71[0]+72[5] = 1 121 | setm(76, 30, (~m[7]>>0)&1); // 71[0]+76[30] = 1 122 | setm(74, 7, (~m[9]>>2)&1); // 73[2]+74[7] = 1 123 | setm(75, 6, (~m[10]>>1)&1); // 74[1]+75[6] = 1 124 | setm(76, 6, (~m[11]>>1)&1); // 75[1]+76[6] = 1 125 | 126 | 127 | #define sha1_round4(a,b,c,d,e,m) \ 128 | rotate_left(a,5) + (b^rotate_left(c,30)^rotate_left(d,30)) + rotate_left(e,30) + m + 0xCA62C1D6; 129 | 130 | e1 = sha1_round4(a1, b1, c1, d1, e1, m[0]); 131 | d1 = sha1_round4(e1, a1, b1, c1, d1, m[1]); 132 | c1 = sha1_round4(d1, e1, a1, b1, c1, m[2]); 133 | b1 = sha1_round4(c1, d1, e1, a1, b1, m[3]); 134 | a1 = sha1_round4(b1, c1, d1, e1, a1, m[4]); 135 | 136 | e1 = sha1_round4(a1, b1, c1, d1, e1, m[5]); 137 | d1 = sha1_round4(e1, a1, b1, c1, d1, m[6]); 138 | c1 = sha1_round4(d1, e1, a1, b1, c1, m[7]); 139 | b1 = sha1_round4(c1, d1, e1, a1, b1, m[8]); 140 | a1 = sha1_round4(b1, c1, d1, e1, a1, m[9]); 141 | 142 | e1 = sha1_round4(a1, b1, c1, d1, e1, m[10]); 143 | d1 = sha1_round4(e1, a1, b1, c1, d1, m[11]); 144 | c1 = sha1_round4(d1, e1, a1, b1, c1, m[12]); 145 | b1 = sha1_round4(c1, d1, e1, a1, b1, m[13]); 146 | a1 = sha1_round4(b1, c1, d1, e1, a1, m[14]); 147 | 148 | e1 = sha1_round4(a1, b1, c1, d1, e1, m[15]); 149 | 150 | // Apply message difference corresponding to path 151 | m[ 0] ^= 0b00000000000000000000000000000000; 152 | m[ 1] ^= 0b00000000000000000000000000000000; 153 | m[ 2] ^= 0b00000000000000000000000000000000; 154 | m[ 3] ^= 0b00000000000000000000000000000001; 155 | m[ 4] ^= 0b00000000000000000000000000100000; 156 | m[ 5] ^= 0b00000000000000000000000000000001; 157 | m[ 6] ^= 0b01000000000000000000000000000010; 158 | m[ 7] ^= 0b01000000000000000000000001000001; 159 | m[ 8] ^= 0b01000000000000000000000000100010; 160 | m[ 9] ^= 0b10000000000000000000000000000101; 161 | m[10] ^= 0b11000000000000000000000010000010; 162 | m[11] ^= 0b11000000000000000000000001000110; 163 | m[12] ^= 0b01000000000000000000000001001011; 164 | m[13] ^= 0b10000000000000000000000100000111; 165 | m[14] ^= 0b00000000000000000000000010001001; 166 | m[15] ^= 0b00000000000000000000000000010100; 167 | 168 | 169 | e2 = sha1_round4(a2, b2, c2, d2, e2, m[0]); 170 | d2 = sha1_round4(e2, a2, b2, c2, d2, m[1]); 171 | c2 = sha1_round4(d2, e2, a2, b2, c2, m[2]); 172 | b2 = sha1_round4(c2, d2, e2, a2, b2, m[3]); 173 | a2 = sha1_round4(b2, c2, d2, e2, a2, m[4]); 174 | 175 | e2 = sha1_round4(a2, b2, c2, d2, e2, m[5]); 176 | d2 = sha1_round4(e2, a2, b2, c2, d2, m[6]); 177 | c2 = sha1_round4(d2, e2, a2, b2, c2, m[7]); 178 | b2 = sha1_round4(c2, d2, e2, a2, b2, m[8]); 179 | a2 = sha1_round4(b2, c2, d2, e2, a2, m[9]); 180 | 181 | e2 = sha1_round4(a2, b2, c2, d2, e2, m[10]); 182 | d2 = sha1_round4(e2, a2, b2, c2, d2, m[11]); 183 | c2 = sha1_round4(d2, e2, a2, b2, c2, m[12]); 184 | b2 = sha1_round4(c2, d2, e2, a2, b2, m[13]); 185 | a2 = sha1_round4(b2, c2, d2, e2, a2, m[14]); 186 | 187 | e2 = sha1_round4(a2, b2, c2, d2, e2, m[15]); 188 | 189 | // Compute output difference 190 | uint32_t dd = rotate_left(d2,30) - rotate_left(d1,30); 191 | uint32_t dc = rotate_left(c2,30) - rotate_left(c1,30); 192 | uint32_t db = rotate_left(b2,30) - rotate_left(b1,30); 193 | uint32_t da = a2 - a1; 194 | uint32_t de = e2 - e1; 195 | 196 | for (unsigned i=0; i < tablength(diff_groups[n].g) && diff_groups[n].g[i].p; i++) { 197 | if (diff_groups[n].g[i].diff[0] == de && 198 | diff_groups[n].g[i].diff[1] == da && 199 | diff_groups[n].g[i].diff[2] == db && 200 | diff_groups[n].g[i].diff[3] == dc && 201 | diff_groups[n].g[i].diff[4] == dd) { 202 | count[i]++; 203 | } 204 | } 205 | } 206 | 207 | // Print results 208 | for (unsigned i=0; i. 9 | 10 | 11 | #define _XOPEN_SOURCE 600 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | 29 | #define tablength(t) (sizeof((t))/sizeof((t)[0])) 30 | 31 | uint32_t rotate_left(uint32_t x, int n) { 32 | n&=31; 33 | if (n==0) 34 | return n; 35 | return (x<>(32-n)); 36 | } 37 | 38 | typedef uint64_t word; 39 | 40 | typedef struct { 41 | uint32_t x[5]; 42 | double p; 43 | } __attribute__((packed)) data_t; 44 | 45 | int cmp_array(const void *A, const void *B) { 46 | const uint32_t *a = A; 47 | const uint32_t *b = B; 48 | for (int i=0; i<5; i++) { 49 | if (a[i] > b[i]) 50 | return 1; 51 | else if (a[i] < b[i]) 52 | return -1; 53 | } 54 | return 0; 55 | } 56 | 57 | // Binary search 58 | data_t *find (uint32_t x[5], data_t *diffset, size_t min, size_t max) { 59 | if (min >= max) 60 | return NULL; 61 | int mid = (min+max)/2; 62 | 63 | int c = cmp_array(&diffset[mid].x, x); 64 | if (c == 0) 65 | return &diffset[mid]; 66 | if (c > 0) 67 | return find(x, diffset, min, mid); 68 | if (c < 0) 69 | return find(x, diffset, mid+1, max); 70 | } 71 | 72 | struct edge { double c, p; }; 73 | struct edge2 { double c, p; uint32_t data[5]; }; 74 | 75 | void printf_diff(uint32_t a, uint32_t b, int rot, FILE *out) { 76 | a = (a<>(32-rot)); 77 | b = (b<>(32-rot)); 78 | 79 | for (int i=31; i>=0; i--) { 80 | int idx = 2*((a>>i)&1) + ((b>>i)&1); 81 | putc(((char[]){'0', 'n', 'u', '1'}[idx]), out); 82 | } 83 | } 84 | 85 | void print_template (char template[], uint32_t IV1[5], uint32_t IV2[5], int z, FILE *out) { 86 | z = ~z; 87 | 88 | FILE *t = fopen(template, "r"); 89 | // FSM to find pattern '00:' 90 | int state = 0; 91 | while (state != 3) { 92 | switch (fgetc(t)) { 93 | case '0': 94 | if (state < 2) 95 | state ++; 96 | else 97 | state = 0; 98 | break; 99 | case ':': 100 | if (state == 2) 101 | state ++; 102 | else 103 | state = 0; 104 | break; 105 | default: 106 | state = 0; 107 | } 108 | } 109 | fseek(t, 33, SEEK_CUR); 110 | 111 | // Header 112 | fprintf (out, "80\n"); 113 | fprintf (out, " A[i] W[i] Dw Pu[i] Pc[i] N[i] \n"); 114 | 115 | // Initial state 116 | fprintf (out, "\n-4: "); printf_diff(IV1[4], IV2[4], 2, out); 117 | fprintf (out, "\n-3: "); printf_diff(IV1[3], IV2[3], 2, out); 118 | fprintf (out, "\n-2: "); printf_diff(IV1[2], IV2[2], 2, out); 119 | fprintf (out, "\n-1: "); printf_diff(IV1[1], IV2[1], 0, out); 120 | fprintf (out, "\n00: "); printf_diff(IV1[0], IV2[0], 0, out); 121 | 122 | // Template 123 | int c; 124 | while ((c = fgetc(t)) != EOF) { putc(c,out); }; 125 | 126 | // Extra conditions 127 | fprintf (out, "79[4] = %i\n", ((z<<=1)>>13)&1); // z13 128 | fprintf (out, "79[2] = %i\n", ((z<<=1)>>13)&1); // z12 129 | fprintf (out, "78[7] = %i\n", ((z<<=1)>>13)&1); // z11 130 | fprintf (out, "78[3] = %i\n", ((z<<=1)>>13)&1); // z10 131 | fprintf (out, "78[0] = %i\n", ((z<<=1)>>13)&1); // z9 132 | 133 | fprintf (out, "73[2] = %i\n", ((z<<=1)>>13)&1); // z1 134 | fprintf (out, "76[3] = %i\n", ((z<<=1)>>13)&1); // z7 135 | fprintf (out, "76[1] = %i\n", ((z<<=1)>>13)&1); // z2 136 | fprintf (out, "76[0] = %i\n", ((z<<=1)>>13)&1); // z3 137 | fprintf (out, "77[8] = %i\n", ((z<<=1)>>13)&1); // z8 138 | fprintf (out, "77[2] = %i\n", ((z<<=1)>>13)&1); // z6 139 | fprintf (out, "77[1] = %i\n", ((z<<=1)>>13)&1); // z4 140 | fprintf (out, "77[0] = %i\n", ((z<<=1)>>13)&1); // z5 141 | } 142 | 143 | 144 | // Main differences (fixed signs in last two rounds) 145 | struct diff_group { 146 | int z; 147 | struct {double p; uint32_t diff[5];} g[38]; 148 | }; 149 | 150 | struct diff_group diff_groups[] = { 151 | #include "diff_groups.h" 152 | }; 153 | 154 | int main(int argc, char *argv[]) { 155 | 156 | char* infile = NULL; 157 | char* template = NULL; 158 | uint32_t indiff[5], IV1[5], IV2[5]; 159 | int random = 1; 160 | int do_simulation = 0; 161 | FILE* out = stdout; 162 | 163 | srand(getpid()*0xdeadbeef + time(NULL)*0xbadc0ffe); 164 | 165 | for (int i=1; i [-o] [-t