├── .gitignore ├── makefile ├── README.md ├── main.c ├── LICENSE └── quark.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | 5 | # Libraries 6 | *.lib 7 | *.a 8 | 9 | # Shared objects (inc. Windows DLLs) 10 | *.dll 11 | *.so 12 | *.so.* 13 | *.dylib 14 | 15 | # Executables 16 | *.exe 17 | *.out 18 | *.app 19 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS= -Wall 3 | BIN = uquark_test dquark_test squark_test cquark_test\ 4 | uquark_test_debug dquark_test_debug\ 5 | squark_test_debug cquark_test_debug 6 | 7 | all: $(BIN) 8 | 9 | uquark_test: quark.c main.c 10 | $(CC) $(CFLAGS) -DUQUARK $^ -o $@ 11 | 12 | dquark_test: quark.c main.c 13 | $(CC) $(CFLAGS) -DDQUARK $^ -o $@ 14 | 15 | squark_test: quark.c main.c 16 | $(CC) $(CFLAGS) -DSQUARK $^ -o $@ 17 | 18 | cquark_test: quark.c main.c 19 | $(CC) $(CFLAGS) -DCQUARK $^ -o $@ 20 | 21 | uquark_test_debug: quark.c main.c 22 | $(CC) $(CFLAGS) -DUQUARK -DDEBUG $^ -o $@ 23 | 24 | dquark_test_debug: quark.c main.c 25 | $(CC) $(CFLAGS) -DDQUARK -DDEBUG $^ -o $@ 26 | 27 | squark_test_debug: quark.c main.c 28 | $(CC) $(CFLAGS) -DSQUARK -DDEBUG $^ -o $@ 29 | 30 | cquark_test_debug: quark.c main.c 31 | $(CC) $(CFLAGS) -DCQUARK -DDEBUG $^ -o $@ 32 | clean: 33 | rm -fr *.o $(BIN) 34 | 35 | dist: clean 36 | cd ..; \ 37 | tar zcf Quark-`date +%Y%m%d%H%M`.tgz Quark/* 38 | 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Quark 2 | ===== 3 | 4 | Reference implementation of Quark, a family of lightweight cryptographic 5 | hash functions composed of 4 instances: 6 | * u-Quark (at least 64-bit security) 7 | * d-Quark (at least 80-bit security) 8 | * s-Quark (at least 112-bit security) 9 | * c-Quark (at least 160-bit security) 10 | 11 | Quark instances can be used as cryptographic hash functions, as well as 12 | building blocks of [authenticated 13 | ciphers](https://131002.net/data/papers/AKM12.pdf). 14 | 15 | Quark was designed by [Jean-Philippe Aumasson](https://131002.net) with 16 | Luca Henzen, Simon Knellwolf, Willi Meier, and Maria Naya-Plasencia. 17 | 18 | 19 | Usage 20 | ----- 21 | 22 | Running 23 | 24 | ```sh 25 | make 26 | ``` 27 | 28 | will build sanity checks (test vectors) for all 4 Quark instances. For 29 | example: 30 | 31 | ```C 32 | ./uquark_test 33 | ``` 34 | 35 | verifies that u-Quark returns the expected hash value given the empty 36 | message, and 37 | 38 | ```c 39 | ./uquark_test_debug 40 | ``` 41 | 42 | does the same and prints intermediate values. 43 | 44 | Similar executables are provided for d-Quark, s-Quark, and c-Quark. 45 | 46 | 47 | Intellectual property 48 | --------------------- 49 | 50 | The Quark reference code is released under [CC0 51 | license](https://creativecommons.org/publicdomain/zero/1.0/), a public 52 | domain-like licence. 53 | 54 | We aren't aware of any patents or patent applications relevant to 55 | Quark, and we aren't planning to apply for any. 56 | 57 | 58 | References 59 | ---------- 60 | 61 | The [Quark page](https://131002.net/quark) includes 62 | * academic publications (CHES 2010, Journal of Cryptology) 63 | * slides of Quark presentations at conferences and workshops 64 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | Quark reference C implementation 3 | 4 | Copyright (c) 2010-2014 Jean-Philippe Aumasson 5 | 6 | To the extent possible under law, the author(s) have dedicated all copyright 7 | and related and neighboring rights to this software to the public domain 8 | worldwide. This software is distributed without any warranty. 9 | 10 | You should have received a copy of the CC0 Public Domain Dedication along with 11 | this software. If not, see . 12 | */ 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | typedef uint64_t u64; 19 | typedef uint8_t u8; 20 | 21 | int quark( u8 *out, const u8 *in, u64 inlen ); 22 | 23 | #define MAXDIGEST 48 24 | 25 | int test_vectors() 26 | { 27 | u8 out[MAXDIGEST]; 28 | 29 | #if defined(UQUARK) 30 | const u8 digest_empty[] = 31 | { 32 | 0x12,0x6b,0x75,0xbc,0xab,0x23,0x14,0x47, 33 | 0x50,0xd0,0x8b,0xa3,0x13,0xbb,0xd8,0x00, 34 | 0xa4 35 | }; 36 | const char prefix='u'; 37 | #elif defined(DQUARK) 38 | const u8 digest_empty[] = 39 | { 40 | 0x82,0xc7,0xf3,0x80,0xe2,0x31,0x57,0x8e, 41 | 0x2f,0xf4,0xc2,0xa4,0x02,0xe1,0x8b,0xf3, 42 | 0x7a,0xea,0x84,0x77,0x29,0x8d 43 | }; 44 | const char prefix='d'; 45 | #elif defined(SQUARK) 46 | const u8 digest_empty[] = 47 | { 48 | 0x03,0x25,0x62,0x14,0xb9,0x2e,0x81,0x1c, 49 | 0x32,0x1a,0xe8,0x6b,0xab,0x4b,0x0e,0x7a, 50 | 0xe9,0xc2,0x2c,0x42,0x88,0x2f,0xcc,0xde, 51 | 0x8c,0x22,0xbf,0xf6,0xa0,0xa1,0xd6,0xf1 52 | }; 53 | const char prefix='s'; 54 | #elif defined(CQUARK) 55 | const u8 digest_empty[] = 56 | { 57 | 0x1c,0xb9,0x77,0x0e,0xe7,0xc2,0x5f,0xa9, 58 | 0xdc,0xe2,0xc9,0x46,0x45,0x78,0x33,0x7c, 59 | 0x69,0xc7,0xe2,0x6c,0xb4,0xf1,0xbd,0xf4, 60 | 0x48,0x69,0xf1,0xa9,0x36,0x39,0xf1,0xf3, 61 | 0x60,0xb8,0x88,0x97,0x5f,0xf9,0xff,0xee, 62 | 0x88,0x0d,0x2c,0x49,0x91,0x08,0xa2,0x7a 63 | }; 64 | const char prefix='c'; 65 | #endif 66 | 67 | printf( "%c-Quark\n", prefix ); 68 | 69 | /* hash the empty string */ 70 | quark( out, NULL, 0 ); 71 | 72 | return memcmp( out, digest_empty, sizeof( digest_empty ) ); 73 | 74 | } 75 | 76 | int main() 77 | { 78 | if ( !test_vectors() ) 79 | printf( "test vector ok\n" ); 80 | else 81 | printf( "test vector fail\n" ); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | -------------------------------------------------------------------------------- /quark.c: -------------------------------------------------------------------------------- 1 | /* 2 | Quark reference C implementation 3 | 4 | Copyright (c) 2010-2014 Jean-Philippe Aumasson 5 | 6 | To the extent possible under law, the author(s) have dedicated all copyright 7 | and related and neighboring rights to this software to the public domain 8 | worldwide. This software is distributed without any warranty. 9 | 10 | You should have received a copy of the CC0 Public Domain Dedication along with 11 | this software. If not, see . 12 | */ 13 | #include 14 | #include 15 | #include 16 | 17 | #if defined(UQUARK) 18 | #define CAPACITY 16 19 | #define RATE 1 20 | #define WIDTH 17 21 | #elif defined(DQUARK) 22 | #define CAPACITY 20 23 | #define RATE 2 24 | #define WIDTH 22 25 | #elif defined(SQUARK) 26 | #define CAPACITY 28 27 | #define RATE 4 28 | #define WIDTH 32 29 | #elif defined(CQUARK) 30 | #define CAPACITY 40 31 | #define RATE 8 32 | #define WIDTH 48 33 | #endif 34 | 35 | #define DIGEST WIDTH 36 | 37 | typedef uint64_t u64; 38 | typedef uint32_t u32; 39 | typedef uint8_t u8; 40 | 41 | typedef struct 42 | { 43 | int pos; /* number of bytes read into x from current block */ 44 | u32 x[ WIDTH*8 ]; /* one bit stored in each word */ 45 | } hashState; 46 | 47 | 48 | #if defined(UQUARK) 49 | /* 17 bytes */ 50 | u8 iv[] = {0xd8,0xda,0xca,0x44,0x41,0x4a,0x09,0x97, 51 | 0x19,0xc8,0x0a,0xa3,0xaf,0x06,0x56,0x44,0xdb 52 | }; 53 | #elif defined(DQUARK) 54 | /* 22 bytes */ 55 | u8 iv[] = {0xcc,0x6c,0x4a,0xb7,0xd1,0x1f,0xa9,0xbd, 56 | 0xf6,0xee,0xde,0x03,0xd8,0x7b,0x68,0xf9, 57 | 0x1b,0xaa,0x70,0x6c,0x20,0xe9 58 | }; 59 | #elif defined(SQUARK) 60 | /* 32 bytes */ 61 | u8 iv[] = {0x39,0x72,0x51,0xce,0xe1,0xde,0x8a,0xa7, 62 | 0x3e,0xa2,0x62,0x50,0xc6,0xd7,0xbe,0x12, 63 | 0x8c,0xd3,0xe7,0x9d,0xd7,0x18,0xc2,0x4b, 64 | 0x8a,0x19,0xd0,0x9c,0x24,0x92,0xda,0x5d 65 | }; 66 | #elif defined(CQUARK) 67 | /* 48 bytes */ 68 | u8 iv[] = {0x3b,0x45,0x03,0xec,0x76,0x62,0xc3,0xcb, 69 | 0x30,0xe0,0x08,0x37,0xec,0x8d,0x38,0xbb, 70 | 0xe5,0xff,0x5a,0xcd,0x69,0x01,0xa2,0x49, 71 | 0x57,0x50,0xf9,0x19,0x8e,0x2e,0x3b,0x58, 72 | 0x52,0xdc,0xaa,0x16,0x62,0xb7,0xda,0xd6, 73 | 0x5f,0xcb,0x5a,0x8a,0x1f,0x0d,0x5f,0xcc 74 | }; 75 | #endif 76 | 77 | void showstate( u32 *x ) 78 | { 79 | 80 | int i; 81 | u8 buf=0; 82 | 83 | for( i=0; i<8*WIDTH; ++i ) 84 | { 85 | buf ^= ( 1&x[i] )<<( 7-( i%8 ) ); 86 | 87 | if ( ( ( i%8 )==7 ) && ( i ) ) 88 | { 89 | printf( "%02x",buf ); 90 | buf=0; 91 | } 92 | } 93 | 94 | printf( "\n" ); 95 | 96 | } 97 | 98 | 99 | int permute_u( u32 *x ) 100 | { 101 | /* state of 136=2x68 bits */ 102 | #define ROUNDS_U 4*136 103 | #define N_LEN_U 68 104 | #define L_LEN_U 10 105 | 106 | u32 *X, *Y, *L; 107 | u32 h; 108 | int i; 109 | 110 | X = ( u32 * )malloc( ( N_LEN_U+ROUNDS_U )*sizeof( u32 ) ); 111 | Y = ( u32 * )malloc( ( N_LEN_U+ROUNDS_U )*sizeof( u32 ) ); 112 | L = ( u32 * )malloc( ( L_LEN_U+ROUNDS_U )*sizeof( u32 ) ); 113 | 114 | /* local copy of the state in the registers*/ 115 | for( i=0; i< N_LEN_U; ++i ) 116 | { 117 | X[i]=x[i]; 118 | Y[i]=x[i+N_LEN_U]; 119 | } 120 | 121 | /* initialize the LFSR to 11..11 */ 122 | for( i=0; i< L_LEN_U; ++i ) 123 | L[i]=0xFFFFFFFF; 124 | 125 | /* iterate rounds */ 126 | for( i=0; i< ROUNDS_U; ++i ) 127 | { 128 | 129 | /* indices up to i+59, for 8x parallelizibility*/ 130 | 131 | /* need X[i] as linear term only, for invertibility */ 132 | X[N_LEN_U+i] = X[i] ^ Y[i]; 133 | X[N_LEN_U+i] ^= X[i+9] ^ X[i+14] ^ X[i+21] ^ X[i+28] ^ 134 | X[i+33] ^ X[i+37] ^ X[i+45] ^ X[i+52] ^ X[i+55] ^ X[i+50] ^ 135 | ( X[i+59] & X[i+55] ) ^ ( X[i+37] & X[i+33] ) ^ ( X[i+15] & X[i+9] ) ^ 136 | ( X[i+55] & X[i+52] & X[i+45] ) ^ ( X[i+33] & X[i+28] & X[i+21] ) ^ 137 | ( X[i+59] & X[i+45] & X[i+28] & X[i+9] ) ^ 138 | ( X[i+55] & X[i+52] & X[i+37] & X[i+33] ) ^ 139 | ( X[i+59] & X[i+55] & X[i+21] & X[i+15] ) ^ 140 | ( X[i+59] & X[i+55] & X[i+52] & X[i+45] & X[i+37] ) ^ 141 | ( X[i+33] & X[i+28] & X[i+21] & X[i+15] & X[i+9] ) ^ 142 | ( X[i+52] & X[i+45] & X[i+37] & X[i+33] & X[i+28] & X[i+21] ); 143 | 144 | /* need Y[i] as linear term only, for invertibility */ 145 | Y[N_LEN_U+i] = Y[i]; 146 | Y[N_LEN_U+i] ^= Y[i+7] ^ Y[i+16] ^ Y[i+20] ^ Y[i+30] ^ 147 | Y[i+35] ^ Y[i+37] ^ Y[i+42] ^ Y[i+51] ^ Y[i+54] ^ Y[i+49] ^ 148 | ( Y[i+58] & Y[i+54] ) ^ ( Y[i+37] & Y[i+35] ) ^ ( Y[i+15] & Y[i+7] ) ^ 149 | ( Y[i+54] & Y[i+51] & Y[i+42] ) ^ ( Y[i+35] & Y[i+30] & Y[i+20] ) ^ 150 | ( Y[i+58] & Y[i+42] & Y[i+30] & Y[i+7] ) ^ 151 | ( Y[i+54] & Y[i+51] & Y[i+37] & Y[i+35] ) ^ 152 | ( Y[i+58] & Y[i+54] & Y[i+20] & Y[i+15] ) ^ 153 | ( Y[i+58] & Y[i+54] & Y[i+51] & Y[i+42] & Y[i+37] ) ^ 154 | ( Y[i+35] & Y[i+30] & Y[i+20] & Y[i+15] & Y[i+7] ) ^ 155 | ( Y[i+51] & Y[i+42] & Y[i+37] & Y[i+35] & Y[i+30] & Y[i+20] ); 156 | 157 | /* need L[i] as linear term only, for invertibility */ 158 | L[L_LEN_U+i] = L[i]; 159 | L[L_LEN_U+i] ^= L[i+3]; 160 | 161 | /* compute output of the h function */ 162 | h = X[i+25] ^ Y[i+59] ^ ( Y[i+3] & X[i+55] ) ^ ( X[i+46] & X[i+55] ) ^ ( X[i+55] & Y[i+59] ) ^ 163 | ( Y[i+3] & X[i+25] & X[i+46] ) ^ ( Y[i+3] & X[i+46] & X[i+55] ) ^ ( Y[i+3] & X[i+46] & Y[i+59] ) ^ 164 | ( X[i+25] & X[i+46] & Y[i+59] & L[i] ) ^ ( X[i+25] & L[i] ); 165 | h ^= X[i+1] ^ Y[i+2] ^ X[i+4] ^ Y[i+10] ^ X[i+31] ^ Y[i+43] ^ X[i+56] ^ L[i]; 166 | 167 | /* feedback of h into the registers */ 168 | X[N_LEN_U+i] ^= h; 169 | Y[N_LEN_U+i] ^= h; 170 | } 171 | 172 | /* copy final state into hashState */ 173 | for( i=0; i< N_LEN_U; ++i ) 174 | { 175 | x[i] = X[ROUNDS_U+i]; 176 | x[i+N_LEN_U] = Y[ROUNDS_U+i]; 177 | } 178 | 179 | free( X ); 180 | free( Y ); 181 | free( L ); 182 | 183 | return 0; 184 | } 185 | 186 | 187 | int permute_d( u32 *x ) 188 | { 189 | /* state of 176=2x88 bits */ 190 | #define ROUNDS_D 4*176 191 | #define N_LEN_D 88 192 | #define L_LEN_D 10 193 | 194 | u32 *X, *Y, *L; 195 | u32 h; 196 | int i; 197 | 198 | X = ( u32 * )malloc( ( N_LEN_D+ROUNDS_D )*sizeof( u32 ) ); 199 | Y = ( u32 * )malloc( ( N_LEN_D+ROUNDS_D )*sizeof( u32 ) ); 200 | L = ( u32 * )malloc( ( L_LEN_D+ROUNDS_D )*sizeof( u32 ) ); 201 | 202 | /* local copy of the state in the registers*/ 203 | for( i=0; i< N_LEN_D; ++i ) 204 | { 205 | X[i]=x[i]; 206 | Y[i]=x[i+N_LEN_D]; 207 | } 208 | 209 | /* initialize the LFSR to 11..11 */ 210 | for( i=0; i< L_LEN_D; ++i ) 211 | L[i]=0xFFFFFFFF; 212 | 213 | /* iterate rounds */ 214 | for( i=0; i< ROUNDS_D; ++i ) 215 | { 216 | 217 | /* need X[i] as linear term only, for invertibility */ 218 | X[N_LEN_D+i] = X[i] ^ Y[i]; 219 | X[N_LEN_D+i] ^= X[i+11] ^ X[i+18] ^ X[i+27] ^ X[i+36] ^ 220 | X[i+42] ^ X[i+47] ^ X[i+58] ^ X[i+67] ^ X[i+71] ^ X[i+64] ^ 221 | ( X[i+79] & X[i+71] ) ^ ( X[i+47] & X[i+42] ) ^ ( X[i+19] & X[i+11] ) ^ 222 | ( X[i+71] & X[i+67] & X[i+58] ) ^ ( X[i+42] & X[i+36] & X[i+27] ) ^ 223 | ( X[i+79] & X[i+58] & X[i+36] & X[i+11] ) ^ 224 | ( X[i+71] & X[i+67] & X[i+47] & X[i+42] ) ^ 225 | ( X[i+79] & X[i+71] & X[i+27] & X[i+19] ) ^ 226 | ( X[i+79] & X[i+71] & X[i+67] & X[i+58] & X[i+47] ) ^ 227 | ( X[i+42] & X[i+36] & X[i+27] & X[i+19] & X[i+11] ) ^ 228 | ( X[i+67] & X[i+58] & X[i+47] & X[i+42] & X[i+36] & X[i+27] ); 229 | 230 | 231 | /* need Y[i] as linear term only, for invertibility */ 232 | Y[N_LEN_D+i] = Y[i]; 233 | Y[N_LEN_D+i] ^= Y[i+9] ^ Y[i+20] ^ Y[i+25] ^ Y[i+38] ^ 234 | Y[i+44] ^ Y[i+47] ^ Y[i+54] ^ Y[i+67] ^ Y[i+69] ^ Y[i+63] ^ 235 | ( Y[i+78] & Y[i+69] ) ^ ( Y[i+47] & Y[i+44] ) ^ ( Y[i+19] & Y[i+9] ) ^ 236 | ( Y[i+69] & Y[i+67] & Y[i+54] ) ^ ( Y[i+44] & Y[i+38] & Y[i+25] ) ^ 237 | ( Y[i+78] & Y[i+54] & Y[i+38] & Y[i+9] ) ^ 238 | ( Y[i+69] & Y[i+67] & Y[i+47] & Y[i+44] ) ^ 239 | ( Y[i+78] & Y[i+69] & Y[i+25] & Y[i+19] ) ^ 240 | ( Y[i+78] & Y[i+69] & Y[i+67] & Y[i+54] & Y[i+47] ) ^ 241 | ( Y[i+44] & Y[i+38] & Y[i+25] & Y[i+19] & Y[i+9] ) ^ 242 | ( Y[i+67] & Y[i+54] & Y[i+47] & Y[i+44] & Y[i+38] & Y[i+25] ); 243 | 244 | /* need L[i] as linear term only, for invertibility */ 245 | L[L_LEN_D+i] = L[i]; 246 | L[L_LEN_D+i] ^= L[i+3]; // linear feedback here 247 | 248 | /* compute output of the h function */ 249 | h = X[i+35] ^ Y[i+79] ^ ( Y[i+4] & X[i+68] ) ^ ( X[i+57] & X[i+68] ) ^ ( X[i+68] & Y[i+79] ) ^ 250 | ( Y[i+4] & X[i+35] & X[i+57] ) ^ ( Y[i+4] & X[i+57] & X[i+68] ) ^ ( Y[i+4] & X[i+57] & Y[i+79] ) ^ 251 | ( X[i+35] & X[i+57] & Y[i+79] & L[i] ) ^ ( X[i+35] & L[i] ); 252 | h ^= X[i+1] ^ Y[i+2] ^ X[i+5] ^ Y[i+12] ^ X[i+40] ^ Y[i+55] ^ X[i+72] ^ L[i]; 253 | h ^= Y[i+24] ^ X[i+48] ^ Y[i+61]; 254 | 255 | /* feedback of h into the registers */ 256 | X[N_LEN_D+i] ^= h; 257 | Y[N_LEN_D+i] ^= h; 258 | } 259 | 260 | /* copy final state into hashState */ 261 | for( i=0; i< N_LEN_D; ++i ) 262 | { 263 | x[i] = X[ROUNDS_D+i]; 264 | x[i+N_LEN_D] = Y[ROUNDS_D+i]; 265 | } 266 | 267 | free( X ); 268 | free( Y ); 269 | free( L ); 270 | 271 | return 0; 272 | } 273 | 274 | 275 | int permute_s( u32 *x ) 276 | { 277 | /* state of 256=2x128 bits */ 278 | #define ROUNDS_S 4*256 279 | #define N_LEN_S 128 280 | #define L_LEN_S 10 281 | 282 | u32 *X, *Y, *L; 283 | u32 h; 284 | int i; 285 | 286 | X = ( u32 * )malloc( ( N_LEN_S+ROUNDS_S )*sizeof( u32 ) ); 287 | Y = ( u32 * )malloc( ( N_LEN_S+ROUNDS_S )*sizeof( u32 ) ); 288 | L = ( u32 * )malloc( ( L_LEN_S+ROUNDS_S )*sizeof( u32 ) ); 289 | 290 | /* local copy of the state in the registers*/ 291 | for( i=0; i< N_LEN_S; ++i ) 292 | { 293 | X[i]=x[i]; 294 | Y[i]=x[i+N_LEN_S]; 295 | } 296 | 297 | /* initialize the LFSR to 11..11 */ 298 | for( i=0; i< L_LEN_S; ++i ) 299 | L[i]=0xFFFFFFFF; 300 | 301 | /* iterate rounds */ 302 | for( i=0; i< ROUNDS_S; ++i ) 303 | { 304 | 305 | /* need X[i] as linear term only, for invertibility */ 306 | X[N_LEN_S+i] = X[i] ^ Y[i]; 307 | X[N_LEN_S+i] ^= X[i+16] ^ X[i+26] ^ X[i+39] ^ X[i+52] ^ 308 | X[i+61] ^ X[i+69] ^ X[i+84] ^ X[i+97] ^ X[i+103] ^ X[i+94] ^ 309 | ( X[i+111] & X[i+103] ) ^ ( X[i+69] & X[i+61] ) ^ ( X[i+28] & X[i+16] ) ^ 310 | ( X[i+103] & X[i+97] & X[i+84] ) ^ ( X[i+61] & X[i+52] & X[i+39] ) ^ 311 | ( X[i+111] & X[i+84] & X[i+52] & X[i+16] ) ^ 312 | ( X[i+103] & X[i+97] & X[i+69] & X[i+61] ) ^ 313 | ( X[i+111] & X[i+103] & X[i+39] & X[i+28] ) ^ 314 | ( X[i+111] & X[i+103] & X[i+97] & X[i+84] & X[i+69] ) ^ 315 | ( X[i+61] & X[i+52] & X[i+39] & X[i+28] & X[i+16] ) ^ 316 | ( X[i+97] & X[i+84] & X[i+69] & X[i+61] & X[i+52] & X[i+39] ); 317 | 318 | /* need Y[i] as linear term only, for invertibility */ 319 | Y[N_LEN_S+i] = Y[i]; 320 | Y[N_LEN_S+i] ^= Y[i+13] ^ Y[i+30] ^ Y[i+37] ^ Y[i+56] ^ 321 | Y[i+65] ^ Y[i+69] ^ Y[i+79] ^ Y[i+96] ^ Y[i+101] ^ Y[i+92] ^ 322 | ( Y[i+109] & Y[i+101] ) ^ ( Y[i+69] & Y[i+65] ) ^ ( Y[i+28] & Y[i+13] ) ^ 323 | ( Y[i+101] & Y[i+96] & Y[i+79] ) ^ ( Y[i+65] & Y[i+56] & Y[i+37] ) ^ 324 | ( Y[i+109] & Y[i+79] & Y[i+56] & Y[i+13] ) ^ 325 | ( Y[i+101] & Y[i+96] & Y[i+69] & Y[i+65] ) ^ 326 | ( Y[i+109] & Y[i+101] & Y[i+37] & Y[i+28] ) ^ 327 | ( Y[i+109] & Y[i+101] & Y[i+96] & Y[i+79] & Y[i+69] ) ^ 328 | ( Y[i+65] & Y[i+56] & Y[i+37] & Y[i+28] & Y[i+13] ) ^ 329 | ( Y[i+96] & Y[i+79] & Y[i+69] & Y[i+65] & Y[i+56] & Y[i+37] ); 330 | 331 | /* need L[i] as linear term only, for invertibility */ 332 | L[L_LEN_S+i] = L[i]; 333 | L[L_LEN_S+i] ^= L[i+3]; // linear feedback here 334 | 335 | /* compute output of the h function */ 336 | h = X[i+47] ^ Y[i+111] ^ ( Y[i+8] & X[i+100] ) ^ ( X[i+72] & X[i+100] ) ^ ( X[i+100] & Y[i+111] ) ^ 337 | ( Y[i+8] & X[i+47] & X[i+72] ) ^ ( Y[i+8] & X[i+72] & X[i+100] ) ^ ( Y[i+8] & X[i+72] & Y[i+111] ) ^ 338 | ( X[i+47] & X[i+72] & Y[i+111] & L[i] ) ^ ( X[i+47] & L[i] ); 339 | h ^= X[i+1] ^ Y[i+3] ^ X[i+7] ^ Y[i+18] ^ X[i+58] ^ Y[i+80] ^ X[i+105] ^ L[i]; 340 | h ^= Y[i+34] ^ Y[i+71] ^ X[i+90] ^ Y[i+91]; 341 | 342 | /* feedback of h into the registers */ 343 | X[N_LEN_S+i] ^= h; 344 | Y[N_LEN_S+i] ^= h; 345 | } 346 | 347 | /* copy final state into hashState */ 348 | for( i=0; i< N_LEN_S; ++i ) 349 | { 350 | x[i] = X[ROUNDS_S+i]; 351 | x[i+N_LEN_S] = Y[ROUNDS_S+i]; 352 | } 353 | 354 | free( X ); 355 | free( Y ); 356 | free( L ); 357 | 358 | return 0; 359 | } 360 | 361 | 362 | int permute_c( u32 *x ) 363 | { 364 | /* state of 384=2x192 bits */ 365 | #define ROUNDS_C 2*384 366 | #define N_LEN_C 192 367 | #define L_LEN_C 16 368 | 369 | u32 *X, *Y, *L; 370 | u32 h; 371 | int i; 372 | 373 | X = ( u32 * )malloc( ( N_LEN_C+ROUNDS_C )*sizeof( u32 ) ); 374 | Y = ( u32 * )malloc( ( N_LEN_C+ROUNDS_C )*sizeof( u32 ) ); 375 | L = ( u32 * )malloc( ( L_LEN_C+ROUNDS_C )*sizeof( u32 ) ); 376 | 377 | /* local copy of the state in the registers*/ 378 | for( i=0; i< N_LEN_C; ++i ) 379 | { 380 | X[i]=x[i]; 381 | Y[i]=x[i+N_LEN_C]; 382 | } 383 | 384 | /* initialize the LFSR to 11..11 */ 385 | for( i=0; i< L_LEN_C; ++i ) 386 | L[i]=0xFFFFFFFF; 387 | 388 | /* iterate rounds */ 389 | for( i=0; i< ROUNDS_C; ++i ) 390 | { 391 | 392 | X[N_LEN_C+i] = X[i] ^ Y[i]; 393 | X[N_LEN_C+i] ^= X[i+13] ^ X[i+34] ^ X[i+65] ^ X[i+77] ^ 394 | X[i+94] ^ X[i+109] ^ X[i+127] ^ X[i+145] ^ X[i+157] ^ X[i+140] ^ 395 | ( X[i+159] & X[i+157] ) ^ ( X[i+109] & X[i+94] ) ^ ( X[i+47] & X[i+13] ) ^ 396 | ( X[i+157] & X[i+145] & X[i+127] ) ^ ( X[i+94] & X[i+77] & X[i+65] ) ^ 397 | ( X[i+159] & X[i+127] & X[i+77] & X[i+13] ) ^ 398 | ( X[i+157] & X[i+145] & X[i+109] & X[i+94] ) ^ 399 | ( X[i+159] & X[i+157] & X[i+65] & X[i+47] ) ^ 400 | ( X[i+159] & X[i+157] & X[i+145] & X[i+127] & X[i+109] ) ^ 401 | ( X[i+94] & X[i+77] & X[i+65] & X[i+47] & X[i+13] ) ^ 402 | ( X[i+145] & X[i+127] & X[i+109] & X[i+94] & X[i+77] & X[i+65] ); 403 | 404 | Y[N_LEN_C+i] = Y[i]; 405 | Y[N_LEN_C+i] ^= Y[i+21] ^ Y[i+57] ^ Y[i+60] ^ Y[i+94] ^ 406 | Y[i+112] ^ Y[i+125] ^ Y[i+133] ^ Y[i+152] ^ Y[i+157] ^ Y[i+146] ^ 407 | ( Y[i+159] & Y[i+157] ) ^ ( Y[i+125] & Y[i+112] ) ^ ( Y[i+36] & Y[i+21] ) ^ 408 | ( Y[i+157] & Y[i+152] & Y[i+133] ) ^ ( Y[i+112] & Y[i+94] & Y[i+60] ) ^ 409 | ( Y[i+159] & Y[i+133] & Y[i+94] & Y[i+21] ) ^ 410 | ( Y[i+157] & Y[i+152] & Y[i+125] & Y[i+112] ) ^ 411 | ( Y[i+159] & Y[i+157] & Y[i+60] & Y[i+36] ) ^ 412 | ( Y[i+159] & Y[i+157] & Y[i+152] & Y[i+133] & Y[i+125] ) ^ 413 | ( Y[i+112] & Y[i+94] & Y[i+60] & Y[i+36] & Y[i+21] ) ^ 414 | ( Y[i+152] & Y[i+133] & Y[i+125] & Y[i+112] & Y[i+94] & Y[i+60] ); 415 | 416 | L[L_LEN_C+i] = L[i] ^ L[i+2] ^ L[i+3] ^ L[i+5]; 417 | 418 | 419 | h = X[i+25] ^ Y[i+59] ^ ( Y[i+3] & X[i+55] ) ^ ( X[i+46] & X[i+55] ) ^ ( X[i+55] & Y[i+59] ) ^ 420 | ( Y[i+3] & X[i+25] & X[i+46] ) ^ ( Y[i+3] & X[i+46] & X[i+55] ) ^ ( Y[i+3] & X[i+46] & Y[i+59] ) ^ 421 | ( X[i+25] & X[i+46] & Y[i+59] & L[i] ) ^ ( X[i+25] & L[i] ); 422 | h ^= L[i]; 423 | h ^= X[i+4] ^ X[i+28] ^ X[i+40] ^ X[i+85] ^ X[i+112] ^ X[i+141] ^ X[i+146] ^ X[i+152]; 424 | h ^= Y[i+2] ^ Y[i+33] ^ Y[i+60] ^ Y[i+62] ^ Y[i+ 87] ^ Y[i+ 99] ^ Y[i+138] ^ Y[i+148]; 425 | 426 | X[N_LEN_C+i] ^= h; 427 | Y[N_LEN_C+i] ^= h; 428 | } 429 | 430 | /* copy final state into hashState */ 431 | for( i=0; i< N_LEN_C; ++i ) 432 | { 433 | x[i] = X[ROUNDS_C+i]; 434 | x[i+N_LEN_C] = Y[ROUNDS_C+i]; 435 | } 436 | 437 | free( X ); 438 | free( Y ); 439 | free( L ); 440 | 441 | return 0; 442 | } 443 | 444 | 445 | 446 | 447 | /* permutation of the state */ 448 | static void permute( u32 *x ) 449 | { 450 | 451 | #ifdef DEBUG 452 | printf( "enter permute\n" ); 453 | showstate( x ); 454 | #endif 455 | 456 | #if defined(UQUARK) 457 | permute_u( x ); 458 | #elif defined(DQUARK) 459 | permute_d( x ); 460 | #elif defined(SQUARK) 461 | permute_s( x ); 462 | #elif defined(CQUARK) 463 | permute_c( x ); 464 | #endif 465 | 466 | #ifdef DEBUG 467 | printf( "permute done\n" ); 468 | showstate( x ); 469 | #endif 470 | 471 | } 472 | 473 | 474 | /* initialization of the IV */ 475 | int init( hashState *state ) 476 | { 477 | int i; 478 | 479 | #ifdef DEBUG 480 | printf( "enter init\n" ); 481 | #endif 482 | 483 | /* initialize state */ 484 | for ( i = 0; i < 8*WIDTH; ++i ) 485 | state->x[i] = ( iv[i/8]>>( 7-( i%8 ) ) )&1; 486 | 487 | state->pos = 0; 488 | 489 | #ifdef DEBUG 490 | printf( "init done\n" ); 491 | showstate( state->x ); 492 | #endif 493 | 494 | return 0; 495 | } 496 | 497 | 498 | int update( hashState *state, const u8 *data, int databytelen ) 499 | { 500 | /* caller promises us that previous data had integral number of bytes */ 501 | /* so state->pos is a multiple of 8 */ 502 | 503 | int i; 504 | 505 | #ifdef DEBUG 506 | printf( "enter update\n" ); 507 | #endif 508 | 509 | while ( databytelen > 0 ) 510 | { 511 | 512 | /* get next byte */ 513 | u8 u = *data; 514 | 515 | #ifdef DEBUG 516 | printf( "get byte %02x at pos %d\n", u, state->pos ); 517 | #endif 518 | 519 | /* xor state with each bit */ 520 | for( i=8*state->pos; i<8*state->pos+8; ++i ) 521 | { 522 | state->x[( 8*( WIDTH-RATE ) )+i] ^= ( u>>( i%8 ) )&1; 523 | } 524 | 525 | 526 | data += 1; 527 | databytelen -= 1; 528 | state->pos += 1; 529 | 530 | if ( state->pos == RATE ) 531 | { 532 | permute( state->x ); 533 | state->pos = 0; 534 | } 535 | } 536 | 537 | #ifdef DEBUG 538 | printf( "update done\n" ); 539 | #endif 540 | 541 | return 0; 542 | } 543 | 544 | 545 | /* finalize (padding) and return digest */ 546 | int final( hashState *state, u8 *out ) 547 | { 548 | int i; 549 | int outbytes=0; 550 | u8 u; 551 | 552 | #ifdef DEBUG 553 | printf( "enter final\n" ); 554 | #endif 555 | 556 | /* append '1' bit */ 557 | state->x[8*( WIDTH-RATE )+state->pos*8] ^= 1; 558 | 559 | /* permute to obtain first final state*/ 560 | permute( state->x ); 561 | 562 | /* zeroize output buffer */ 563 | for( i=0; ix[8*( WIDTH-RATE )+i+8*( outbytes%RATE )] &1; 574 | out[outbytes] ^= ( u << ( 7-i ) ); 575 | } 576 | 577 | #ifdef DEBUG 578 | printf( "extracted byte %02x (%d)\n",out[outbytes],outbytes ); 579 | #endif 580 | 581 | outbytes += 1; 582 | 583 | if ( outbytes == DIGEST ) 584 | break; 585 | 586 | /* if RATE bytes extracted, permute again */ 587 | if ( ! ( outbytes % RATE ) ) 588 | { 589 | permute( state->x ); 590 | } 591 | } 592 | 593 | #ifdef DEBUG 594 | printf( "final done\n" ); 595 | #endif 596 | 597 | 598 | return 0; 599 | } 600 | 601 | 602 | int quark( u8 *out, const u8 *in, u64 inlen ) 603 | { 604 | /* inlen in bytes */ 605 | 606 | hashState state; 607 | 608 | init( &state ); 609 | update( &state, in, inlen ); 610 | final( &state, out ); 611 | 612 | return 0; 613 | } 614 | 615 | 616 | --------------------------------------------------------------------------------