├── CMakeLists.txt ├── README.md ├── aes.h ├── b64.c ├── b64.h ├── block.c ├── block.h ├── fsseval.c ├── fssgen.c └── utils.c /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | PROJECT (FSS) 3 | ADD_EXECUTABLE(fss utils.c block.c) 4 | TARGET_COMPILE_OPTIONS(fss PUBLIC -maes) 5 | TARGET_LINK_LIBRARIES(fss ssl crypto) 6 | 7 | ADD_EXECUTABLE(fssgen fssgen.c block.c b64.c) 8 | TARGET_COMPILE_OPTIONS(fssgen PUBLIC -maes) 9 | TARGET_LINK_LIBRARIES(fssgen ssl crypto) 10 | 11 | ADD_EXECUTABLE(fsseval fsseval.c block.c b64.c) 12 | TARGET_COMPILE_OPTIONS(fsseval PUBLIC -maes) 13 | TARGET_LINK_LIBRARIES(fsseval ssl crypto) 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libdpf 2 | 3 | A template for 2-server 1-bit Distributed Point Function. The construction is from "Function Secret Sharing: Improvements and Extensions" from Boyle et al. 4 | 5 | Please following this link for original publication in CCS'16: 6 | https://cs.idc.ac.il/~elette/FSS-CCS.pdf 7 | 8 | We implement 2-party 1-bit DPF with early termination and full domain evaluation. The reason we only implement 1-bit is that such construction is already sufficient for PIR-read and/or PIR-write. 9 | 10 | AES-NI tools all from https://github.com/amaloz/libgarble. 11 | 12 | The project is inspired by the discussion with Frank Wang in https://github.com/frankw2/libfss, their construction is more general, rather than specifically PIR-purpose one-bit implementation. We also use their idea of fixed key (and public) cipher (with AES-NI) to accelarate and simplify the one-way function. For details, please check this paper in NSDI'17. 13 | 14 | Frank Wang, Catherine Yun, Shafi Goldwasser, Vinod Vaikuntanathan, and Matei Zaharia. "Splinter: Practical Private Queries on Public Data." NSDI 2017. https://www.usenix.org/system/files/conference/nsdi17/nsdi17-wang-frank.pdf 15 | 16 | ## How to install 17 | 18 | Install cmake and libssl-dev. use "cmake ." to generate Makefile, and then make. 19 | 20 | Note that our implementation strongly requires AES-NI. Please check whether the Flags in /proc/cpuinfo indicated "aes". 21 | 22 | We consider the machine to be at least 64-bit. 23 | -------------------------------------------------------------------------------- /aes.h: -------------------------------------------------------------------------------- 1 | /* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */ 2 | /* ==================================================================== 3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * 3. All advertising materials mentioning features or use of this 18 | * software must display the following acknowledgment: 19 | * "This product includes software developed by the OpenSSL Project 20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 | * 22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 | * endorse or promote products derived from this software without 24 | * prior written permission. For written permission, please contact 25 | * openssl-core@openssl.org. 26 | * 27 | * 5. Products derived from this software may not be called "OpenSSL" 28 | * nor may "OpenSSL" appear in their names without prior written 29 | * permission of the OpenSSL Project. 30 | * 31 | * 6. Redistributions of any form whatsoever must retain the following 32 | * acknowledgment: 33 | * "This product includes software developed by the OpenSSL Project 34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 | * 36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 | * OF THE POSSIBILITY OF SUCH DAMAGE. 48 | * ==================================================================== 49 | * 50 | */ 51 | 52 | 53 | #ifndef LIBDPF_AES_H 54 | #define LIBDPF_AES_H 55 | 56 | #include "block.h" 57 | 58 | typedef struct { block rd_key[11]; unsigned int rounds; } AES_KEY; 59 | 60 | #define EXPAND_ASSIST(v1,v2,v3,v4,shuff_const,aes_const) \ 61 | v2 = _mm_aeskeygenassist_si128(v4,aes_const); \ 62 | v3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(v3), \ 63 | _mm_castsi128_ps(v1), 16)); \ 64 | v1 = _mm_xor_si128(v1,v3); \ 65 | v3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(v3), \ 66 | _mm_castsi128_ps(v1), 140)); \ 67 | v1 = _mm_xor_si128(v1,v3); \ 68 | v2 = _mm_shuffle_epi32(v2,shuff_const); \ 69 | v1 = _mm_xor_si128(v1,v2) 70 | 71 | static inline void 72 | AES_set_encrypt_key(const block userkey, AES_KEY *restrict key) 73 | { 74 | block x0, x1, x2; 75 | block *kp = key->rd_key; 76 | kp[0] = x0 = userkey; 77 | x2 = _mm_setzero_si128(); 78 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 1); 79 | kp[1] = x0; 80 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 2); 81 | kp[2] = x0; 82 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 4); 83 | kp[3] = x0; 84 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 8); 85 | kp[4] = x0; 86 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 16); 87 | kp[5] = x0; 88 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 32); 89 | kp[6] = x0; 90 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 64); 91 | kp[7] = x0; 92 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 128); 93 | kp[8] = x0; 94 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 27); 95 | kp[9] = x0; 96 | EXPAND_ASSIST(x0, x1, x2, x0, 255, 54); 97 | kp[10] = x0; 98 | key->rounds = 10; 99 | } 100 | 101 | static inline void 102 | AES_ecb_encrypt_blks(block *restrict blks, unsigned int nblks, const AES_KEY *restrict key) 103 | { 104 | for (unsigned int i = 0; i < nblks; ++i) 105 | blks[i] = _mm_xor_si128(blks[i], key->rd_key[0]); 106 | for (unsigned int j = 1; j < key->rounds; ++j) 107 | for (unsigned int i = 0; i < nblks; ++i) 108 | blks[i] = _mm_aesenc_si128(blks[i], key->rd_key[j]); 109 | for (unsigned int i = 0; i < nblks; ++i) 110 | blks[i] = _mm_aesenclast_si128(blks[i], key->rd_key[key->rounds]); 111 | } 112 | 113 | static inline void 114 | AES_set_decrypt_key_fast(AES_KEY *restrict dkey, const AES_KEY *restrict ekey) 115 | { 116 | int j = 0; 117 | int i = ekey->rounds; 118 | #if (OCB_KEY_LEN == 0) 119 | dkey->rounds = i; 120 | #endif 121 | dkey->rd_key[i--] = ekey->rd_key[j++]; 122 | while (i) 123 | dkey->rd_key[i--] = _mm_aesimc_si128(ekey->rd_key[j++]); 124 | dkey->rd_key[i] = ekey->rd_key[j]; 125 | } 126 | 127 | static inline void 128 | AES_set_decrypt_key(block userkey, AES_KEY *restrict key) 129 | { 130 | AES_KEY temp_key; 131 | AES_set_encrypt_key(userkey, &temp_key); 132 | AES_set_decrypt_key_fast(key, &temp_key); 133 | } 134 | 135 | static inline void 136 | AES_ecb_decrypt_blks(block *restrict blks, unsigned nblks, const AES_KEY *restrict key) 137 | { 138 | unsigned i, j, rnds = key->rounds; 139 | for (i = 0; i < nblks; ++i) 140 | blks[i] = _mm_xor_si128(blks[i], key->rd_key[0]); 141 | for (j = 1; j < rnds; ++j) 142 | for (i = 0; i < nblks; ++i) 143 | blks[i] = _mm_aesdec_si128(blks[i], key->rd_key[j]); 144 | for (i = 0; i < nblks; ++i) 145 | blks[i] = _mm_aesdeclast_si128(blks[i], key->rd_key[j]); 146 | } 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /b64.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "b64.h" 4 | 5 | static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 6 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 7 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 8 | 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 9 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 10 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 11 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', 12 | '4', '5', '6', '7', '8', '9', '+', '/'}; 13 | static char *decoding_table = NULL; 14 | static int mod_table[] = {0, 2, 1}; 15 | 16 | 17 | char *base64_encode(const unsigned char *data, 18 | size_t input_length, 19 | size_t *output_length) { 20 | 21 | *output_length = 4 * ((input_length + 2) / 3); 22 | 23 | char *encoded_data = malloc(*output_length + 10); 24 | if (encoded_data == NULL) return NULL; 25 | 26 | for (int i = 0, j = 0; i < input_length;) { 27 | 28 | uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0; 29 | uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0; 30 | uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0; 31 | 32 | uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; 33 | 34 | encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; 35 | encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; 36 | encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; 37 | encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; 38 | } 39 | 40 | for (int i = 0; i < mod_table[input_length % 3]; i++) 41 | encoded_data[*output_length - 1 - i] = '='; 42 | 43 | return encoded_data; 44 | } 45 | 46 | 47 | void build_decoding_table() { 48 | 49 | decoding_table = malloc(256); 50 | 51 | for (int i = 0; i < 64; i++) 52 | decoding_table[(unsigned char) encoding_table[i]] = i; 53 | } 54 | 55 | 56 | unsigned char *base64_decode(const char *data, 57 | size_t input_length, 58 | size_t *output_length) { 59 | 60 | if (decoding_table == NULL) build_decoding_table(); 61 | 62 | if (input_length % 4 != 0) return NULL; 63 | 64 | *output_length = input_length / 4 * 3; 65 | if (data[input_length - 1] == '=') (*output_length)--; 66 | if (data[input_length - 2] == '=') (*output_length)--; 67 | 68 | unsigned char *decoded_data = malloc(*output_length); 69 | if (decoded_data == NULL) return NULL; 70 | 71 | for (int i = 0, j = 0; i < input_length;) { 72 | 73 | uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; 74 | uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; 75 | uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; 76 | uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; 77 | 78 | uint32_t triple = (sextet_a << 3 * 6) 79 | + (sextet_b << 2 * 6) 80 | + (sextet_c << 1 * 6) 81 | + (sextet_d << 0 * 6); 82 | 83 | if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; 84 | if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; 85 | if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; 86 | } 87 | 88 | return decoded_data; 89 | } 90 | 91 | 92 | 93 | 94 | void base64_cleanup() { 95 | free(decoding_table); 96 | } 97 | -------------------------------------------------------------------------------- /b64.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBDPF_B64 2 | #define LIBDPF_B64 3 | 4 | char *base64_encode(const unsigned char *data, 5 | size_t input_length, 6 | size_t *output_length); 7 | 8 | 9 | unsigned char *base64_decode(const char *data, 10 | size_t input_length, 11 | size_t *output_length); 12 | 13 | void base64_cleanup(); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /block.c: -------------------------------------------------------------------------------- 1 | #include "block.h" 2 | #include "aes.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static AES_KEY rand_aes_key; 10 | static uint64_t current_rand_index; 11 | 12 | block 13 | dpf_seed(block *seed) 14 | { 15 | block cur_seed; 16 | current_rand_index = 0; 17 | if (seed) { 18 | cur_seed = *seed; 19 | } else { 20 | if (RAND_bytes((unsigned char *) &cur_seed, 16) == 0) { 21 | fprintf(stderr, "** unable to seed securely\n"); 22 | return dpf_zero_block(); 23 | } 24 | } 25 | AES_set_encrypt_key(cur_seed, &rand_aes_key); 26 | return cur_seed; 27 | } 28 | 29 | inline block 30 | dpf_random_block(void) 31 | { 32 | block out; 33 | uint64_t *val; 34 | int i; 35 | 36 | out = dpf_zero_block(); 37 | val = (uint64_t *) &out; 38 | val[0] = current_rand_index++; 39 | out = _mm_xor_si128(out, rand_aes_key.rd_key[0]); 40 | for (i = 1; i < 10; ++i) 41 | out = _mm_aesenc_si128(out, rand_aes_key.rd_key[i]); 42 | return _mm_aesenclast_si128(out, rand_aes_key.rd_key[i]); 43 | } 44 | 45 | block * 46 | dpf_allocate_blocks(size_t nblocks) 47 | { 48 | int res; 49 | block *blks = NULL; 50 | blks = calloc(nblocks, sizeof(block)); 51 | /* res = posix_memalign((void **) &blks, 128, sizeof(block) * nblocks); */ 52 | /* if (res == 0) { */ 53 | /* return blks; */ 54 | /* } else { */ 55 | /* perror("allocate_blocks"); */ 56 | /* return NULL; */ 57 | /* } */ 58 | return blks; 59 | } 60 | 61 | 62 | void _output_bit_to_bit(uint64_t input){ 63 | for(int i = 0; i < 64; i++) 64 | { 65 | if( (1ll << i) & input) 66 | printf("1"); 67 | else 68 | printf("0"); 69 | } 70 | } 71 | 72 | void dpf_cb(block input) { 73 | uint64_t *val = (uint64_t *) &input; 74 | 75 | //printf("%016lx%016lx\n", val[0], val[1]); 76 | _output_bit_to_bit(val[0]); 77 | _output_bit_to_bit(val[1]); 78 | printf("\n"); 79 | } 80 | 81 | void dpf_cbnotnewline(block input) { 82 | uint64_t *val = (uint64_t *) &input; 83 | 84 | _output_bit_to_bit(val[0]); 85 | _output_bit_to_bit(val[1]); 86 | } 87 | -------------------------------------------------------------------------------- /block.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBDPF_BLOCK_H 2 | #define LIBDPF_BLOCK_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef __m128i block; 9 | 10 | #define dpf_xor(x,y) _mm_xor_si128(x,y) 11 | #define dpf_zero_block() _mm_setzero_si128() 12 | #define dpf_equal(x,y) (_mm_movemask_epi8(_mm_cmpeq_epi8(x,y)) == 0xffff) 13 | #define dpf_unequal(x,y) (_mm_movemask_epi8(_mm_cmpeq_epi8(x,y)) != 0xffff) 14 | 15 | #define dpf_lsb(x) (*((char *) &x) & 1) 16 | #define dpf_make_block(X,Y) _mm_set_epi64((__m64)(X), (__m64)(Y)) 17 | #define dpf_double(B) _mm_slli_epi64(B,1) 18 | 19 | #define dpf_left_shirt(v, n) \ 20 | ({ \ 21 | __m128i v1, v2; \ 22 | \ 23 | if ((n) >= 64) \ 24 | { \ 25 | v1 = _mm_slli_si128(v, 8); \ 26 | v1 = _mm_slli_epi64(v1, (n) - 64); \ 27 | } \ 28 | else \ 29 | { \ 30 | v1 = _mm_slli_epi64(v, n); \ 31 | v2 = _mm_slli_si128(v, 8); \ 32 | v2 = _mm_srli_epi64(v2, 64 - (n)); \ 33 | v1 = _mm_or_si128(v1, v2); \ 34 | } \ 35 | v1; \ 36 | }) 37 | 38 | 39 | #include 40 | 41 | block 42 | dpf_seed(block *seed); 43 | block 44 | dpf_random_block(void); 45 | block * 46 | dpf_allocate_blocks(size_t nblocks); 47 | 48 | void 49 | dpf_cb(block input); 50 | void dpf_cbnotnewline(block input); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /fsseval.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "aes.h" 4 | #include "block.h" 5 | 6 | block dpf_reverse_lsb(block input){ 7 | static long long b1 = 0; 8 | static long long b2 = 1; 9 | block xor = dpf_make_block(b1, b2); 10 | return dpf_xor(input, xor); 11 | } 12 | 13 | block dpf_set_lsb_zero(block input){ 14 | int lsb = dpf_lsb(input); 15 | 16 | if(lsb == 1){ 17 | return dpf_reverse_lsb(input); 18 | }else{ 19 | return input; 20 | } 21 | } 22 | 23 | void PRG(AES_KEY *key, block input, block* output1, block* output2, int* bit1, int* bit2){ 24 | input = dpf_set_lsb_zero(input); 25 | 26 | block stash[2]; 27 | stash[0] = input; 28 | stash[1] = dpf_reverse_lsb(input); 29 | 30 | AES_ecb_encrypt_blks(stash, 2, key); 31 | 32 | stash[0] = dpf_xor(stash[0], input); 33 | stash[1] = dpf_xor(stash[1], input); 34 | stash[1] = dpf_reverse_lsb(stash[1]); 35 | 36 | *bit1 = dpf_lsb(stash[0]); 37 | *bit2 = dpf_lsb(stash[1]); 38 | 39 | *output1 = dpf_set_lsb_zero(stash[0]); 40 | *output2 = dpf_set_lsb_zero(stash[1]); 41 | } 42 | 43 | static int getbit(int x, int n, int b){ 44 | return ((unsigned int)(x) >> (n - b)) & 1; 45 | } 46 | 47 | void GEN(AES_KEY *key, int alpha, int n, unsigned char** k0, unsigned char **k1){ 48 | int maxlayer = n - 7; 49 | //int maxlayer = n; 50 | 51 | block s[maxlayer + 1][2]; 52 | int t[maxlayer + 1 ][2]; 53 | block sCW[maxlayer]; 54 | int tCW[maxlayer][2]; 55 | 56 | s[0][0] = dpf_random_block(); 57 | s[0][1] = dpf_random_block(); 58 | t[0][0] = dpf_lsb(s[0][0]); 59 | t[0][1] = t[0][0] ^ 1; 60 | s[0][0] = dpf_set_lsb_zero(s[0][0]); 61 | s[0][1] = dpf_set_lsb_zero(s[0][1]); 62 | 63 | int i; 64 | block s0[2], s1[2]; // 0=L,1=R 65 | #define LEFT 0 66 | #define RIGHT 1 67 | int t0[2], t1[2]; 68 | for(i = 1; i<= maxlayer; i++){ 69 | PRG(key, s[i-1][0], &s0[LEFT], &s0[RIGHT], &t0[LEFT], &t0[RIGHT]); 70 | PRG(key, s[i-1][1], &s1[LEFT], &s1[RIGHT], &t1[LEFT], &t1[RIGHT]); 71 | 72 | int keep, lose; 73 | int alphabit = getbit(alpha, n, i); 74 | if(alphabit == 0){ 75 | keep = LEFT; 76 | lose = RIGHT; 77 | }else{ 78 | keep = RIGHT; 79 | lose = LEFT; 80 | } 81 | 82 | sCW[i-1] = dpf_xor(s0[lose], s1[lose]); 83 | 84 | tCW[i-1][LEFT] = t0[LEFT] ^ t1[LEFT] ^ alphabit ^ 1; 85 | tCW[i-1][RIGHT] = t0[RIGHT] ^ t1[RIGHT] ^ alphabit; 86 | 87 | if(t[i-1][0] == 1){ 88 | s[i][0] = dpf_xor(s0[keep], sCW[i-1]); 89 | t[i][0] = t0[keep] ^ tCW[i-1][keep]; 90 | }else{ 91 | s[i][0] = s0[keep]; 92 | t[i][0] = t0[keep]; 93 | } 94 | 95 | if(t[i-1][1] == 1){ 96 | s[i][1] = dpf_xor(s1[keep], sCW[i-1]); 97 | t[i][1] = t1[keep] ^ tCW[i-1][keep]; 98 | }else{ 99 | s[i][1] = s1[keep]; 100 | t[i][1] = t1[keep]; 101 | } 102 | } 103 | 104 | block finalblock; 105 | finalblock = dpf_zero_block(); 106 | finalblock = dpf_reverse_lsb(finalblock); 107 | 108 | char shift = (alpha) & 127; 109 | if(shift & 64){ 110 | finalblock = dpf_left_shirt(finalblock, 64); 111 | } 112 | if(shift & 32){ 113 | finalblock = dpf_left_shirt(finalblock, 32); 114 | } 115 | if(shift & 16){ 116 | finalblock = dpf_left_shirt(finalblock, 16); 117 | } 118 | if(shift & 8){ 119 | finalblock = dpf_left_shirt(finalblock, 8); 120 | } 121 | if(shift & 4){ 122 | finalblock = dpf_left_shirt(finalblock, 4); 123 | } 124 | if(shift & 2){ 125 | finalblock = dpf_left_shirt(finalblock, 2); 126 | } 127 | if(shift & 1){ 128 | finalblock = dpf_left_shirt(finalblock, 1); 129 | } 130 | dpf_cb(finalblock); 131 | finalblock = dpf_reverse_lsb(finalblock); 132 | 133 | finalblock = dpf_xor(finalblock, s[maxlayer][0]); 134 | finalblock = dpf_xor(finalblock, s[maxlayer][1]); 135 | 136 | unsigned char *buff0; 137 | unsigned char *buff1; 138 | buff0 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxlayer + 16); 139 | buff1 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxlayer + 16); 140 | 141 | if(buff0 == NULL || buff1 == NULL){ 142 | printf("Memory allocation failed\n"); 143 | exit(1); 144 | } 145 | 146 | buff0[0] = n; 147 | memcpy(&buff0[1], &s[0][0], 16); 148 | buff0[17] = t[0][0]; 149 | for(i = 1; i <= maxlayer; i++){ 150 | memcpy(&buff0[18 * i], &sCW[i-1], 16); 151 | buff0[18 * i + 16] = tCW[i-1][0]; 152 | buff0[18 * i + 17] = tCW[i-1][1]; 153 | } 154 | memcpy(&buff0[18 * maxlayer + 18], &finalblock, 16); 155 | 156 | buff1[0] = n; 157 | memcpy(&buff1[18], &buff0[18], 18 * (maxlayer)); 158 | memcpy(&buff1[1], &s[0][1], 16); 159 | buff1[17] = t[0][1]; 160 | memcpy(&buff1[18 * maxlayer + 18], &finalblock, 16); 161 | 162 | *k0 = buff0; 163 | *k1 = buff1; 164 | } 165 | 166 | block EVAL(AES_KEY *key, unsigned char* k, int x){ 167 | int n = k[0]; 168 | int maxlayer = n - 7; 169 | 170 | block s[maxlayer + 1]; 171 | int t[maxlayer + 1]; 172 | block sCW[maxlayer]; 173 | int tCW[maxlayer][2]; 174 | block finalblock; 175 | 176 | memcpy(&s[0], &k[1], 16); 177 | t[0] = k[17]; 178 | 179 | int i; 180 | for(i = 1; i <= maxlayer; i++){ 181 | memcpy(&sCW[i-1], &k[18 * i], 16); 182 | tCW[i-1][0] = k[18 * i + 16]; 183 | tCW[i-1][1] = k[18 * i + 17]; 184 | } 185 | 186 | memcpy(&finalblock, &k[18 * (maxlayer + 1)], 16); 187 | 188 | block sL, sR; 189 | int tL, tR; 190 | for(i = 1; i <= maxlayer; i++){ 191 | PRG(key, s[i - 1], &sL, &sR, &tL, &tR); 192 | 193 | if(t[i-1] == 1){ 194 | sL = dpf_xor(sL, sCW[i-1]); 195 | sR = dpf_xor(sR, sCW[i-1]); 196 | tL = tL ^ tCW[i-1][0]; 197 | tR = tR ^ tCW[i-1][1]; 198 | } 199 | 200 | int xbit = getbit(x, n, i); 201 | if(xbit == 0){ 202 | s[i] = sL; 203 | t[i] = tL; 204 | }else{ 205 | s[i] = sR; 206 | t[i] = tR; 207 | } 208 | } 209 | 210 | block res; 211 | res = s[maxlayer]; 212 | if(t[maxlayer] == 1){ 213 | res = dpf_reverse_lsb(res); 214 | } 215 | 216 | if(t[maxlayer] == 1){ 217 | res = dpf_xor(res, finalblock); 218 | } 219 | 220 | return res; 221 | } 222 | 223 | block* EVALFULL(AES_KEY *key, unsigned char* k){ 224 | int n = k[0]; 225 | int maxlayer = n - 7; 226 | int maxlayeritem = 1 << (n - 7); 227 | 228 | block s[2][maxlayeritem]; 229 | int t[2][maxlayeritem]; 230 | 231 | int curlayer = 1; 232 | 233 | block sCW[maxlayer]; 234 | int tCW[maxlayer][2]; 235 | block finalblock; 236 | 237 | memcpy(&s[0][0], &k[1], 16); 238 | t[0][0] = k[17]; 239 | 240 | int i, j; 241 | for(i = 1; i <= maxlayer; i++){ 242 | memcpy(&sCW[i-1], &k[18 * i], 16); 243 | tCW[i-1][0] = k[18 * i + 16]; 244 | tCW[i-1][1] = k[18 * i + 17]; 245 | } 246 | 247 | memcpy(&finalblock, &k[18 * (maxlayer + 1)], 16); 248 | 249 | block sL, sR; 250 | int tL, tR; 251 | for(i = 1; i <= maxlayer; i++){ 252 | int itemnumber = 1 << (i - 1); 253 | for(j = 0; j < itemnumber; j++){ 254 | PRG(key, s[1 - curlayer][j], &sL, &sR, &tL, &tR); 255 | 256 | if(t[1 - curlayer][j] == 1){ 257 | sL = dpf_xor(sL, sCW[i-1]); 258 | sR = dpf_xor(sR, sCW[i-1]); 259 | tL = tL ^ tCW[i-1][0]; 260 | tR = tR ^ tCW[i-1][1]; 261 | } 262 | 263 | s[curlayer][2 * j] = sL; 264 | t[curlayer][2 * j] = tL; 265 | s[curlayer][2 * j + 1] = sR; 266 | t[curlayer][2 * j + 1] = tR; 267 | } 268 | curlayer = 1 - curlayer; 269 | } 270 | 271 | int itemnumber = 1 << maxlayer; 272 | block *res = (block*) malloc(sizeof(block) * itemnumber); 273 | 274 | for(j = 0; j < itemnumber; j ++){ 275 | res[j] = s[1 - curlayer][j]; 276 | 277 | if(t[1 - curlayer][j] == 1){ 278 | res[j] = dpf_reverse_lsb(res[j]); 279 | } 280 | 281 | if(t[1 - curlayer][j] == 1){ 282 | res[j] = dpf_xor(res[j], finalblock); 283 | } 284 | } 285 | 286 | return res; 287 | } 288 | 289 | int getsize(int n){ 290 | int maxlayer = n - 7; 291 | 292 | return (18 * (maxlayer + 1) + 16); 293 | } 294 | 295 | 296 | int main(int argc, char** argv){ 297 | long long userkey1 = 597349; long long userkey2 = 121379; 298 | block userkey = dpf_make_block(userkey1, userkey2); 299 | 300 | dpf_seed(NULL); 301 | 302 | AES_KEY key; 303 | AES_set_encrypt_key(userkey, &key); 304 | 305 | if(argc != 3){ 306 | printf("format: fsseval N filename\n"); 307 | exit(0); 308 | } 309 | 310 | int n; 311 | char filename[1001]; 312 | sscanf(argv[1], "%d", &n); 313 | sscanf(argv[2], "%s", filename); 314 | 315 | unsigned char *k = (unsigned char*) malloc(getsize(n)); 316 | 317 | if(k == NULL){ 318 | printf("Failed to allocate a memory space.\n"); 319 | exit(0); 320 | } 321 | 322 | FILE *fp = fopen(filename, "rb"); 323 | 324 | if(fp == NULL){ 325 | printf("Failed to open the file.\n"); 326 | exit(0); 327 | } 328 | 329 | fread(k, getsize(n), 1, fp); 330 | fclose(fp); 331 | 332 | block *resf; 333 | resf = EVALFULL(&key, k); 334 | 335 | int j; 336 | int totalblocknumber = (1 << n) / 128; 337 | for(j = 0; j < totalblocknumber; j++){ 338 | dpf_cbnotnewline(resf[j]); 339 | } 340 | 341 | return 0; 342 | } 343 | -------------------------------------------------------------------------------- /fssgen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "b64.h" 4 | #include "aes.h" 5 | #include "block.h" 6 | 7 | block dpf_reverse_lsb(block input){ 8 | static long long b1 = 0; 9 | static long long b2 = 1; 10 | block xor = dpf_make_block(b1, b2); 11 | return dpf_xor(input, xor); 12 | } 13 | 14 | block dpf_set_lsb_zero(block input){ 15 | int lsb = dpf_lsb(input); 16 | 17 | if(lsb == 1){ 18 | return dpf_reverse_lsb(input); 19 | }else{ 20 | return input; 21 | } 22 | } 23 | 24 | void PRG(AES_KEY *key, block input, block* output1, block* output2, int* bit1, int* bit2){ 25 | input = dpf_set_lsb_zero(input); 26 | 27 | block stash[2]; 28 | stash[0] = input; 29 | stash[1] = dpf_reverse_lsb(input); 30 | 31 | AES_ecb_encrypt_blks(stash, 2, key); 32 | 33 | stash[0] = dpf_xor(stash[0], input); 34 | stash[1] = dpf_xor(stash[1], input); 35 | stash[1] = dpf_reverse_lsb(stash[1]); 36 | 37 | *bit1 = dpf_lsb(stash[0]); 38 | *bit2 = dpf_lsb(stash[1]); 39 | 40 | *output1 = dpf_set_lsb_zero(stash[0]); 41 | *output2 = dpf_set_lsb_zero(stash[1]); 42 | } 43 | 44 | static int getbit(int x, int n, int b){ 45 | return ((unsigned int)(x) >> (n - b)) & 1; 46 | } 47 | 48 | void GEN(AES_KEY *key, int alpha, int n, unsigned char** k0, unsigned char **k1){ 49 | int maxlayer = n - 7; 50 | //int maxlayer = n; 51 | 52 | block s[maxlayer + 1][2]; 53 | int t[maxlayer + 1 ][2]; 54 | block sCW[maxlayer]; 55 | int tCW[maxlayer][2]; 56 | 57 | s[0][0] = dpf_random_block(); 58 | s[0][1] = dpf_random_block(); 59 | t[0][0] = dpf_lsb(s[0][0]); 60 | t[0][1] = t[0][0] ^ 1; 61 | s[0][0] = dpf_set_lsb_zero(s[0][0]); 62 | s[0][1] = dpf_set_lsb_zero(s[0][1]); 63 | 64 | int i; 65 | block s0[2], s1[2]; // 0=L,1=R 66 | #define LEFT 0 67 | #define RIGHT 1 68 | int t0[2], t1[2]; 69 | for(i = 1; i<= maxlayer; i++){ 70 | PRG(key, s[i-1][0], &s0[LEFT], &s0[RIGHT], &t0[LEFT], &t0[RIGHT]); 71 | PRG(key, s[i-1][1], &s1[LEFT], &s1[RIGHT], &t1[LEFT], &t1[RIGHT]); 72 | 73 | int keep, lose; 74 | int alphabit = getbit(alpha, n, i); 75 | if(alphabit == 0){ 76 | keep = LEFT; 77 | lose = RIGHT; 78 | }else{ 79 | keep = RIGHT; 80 | lose = LEFT; 81 | } 82 | 83 | sCW[i-1] = dpf_xor(s0[lose], s1[lose]); 84 | 85 | tCW[i-1][LEFT] = t0[LEFT] ^ t1[LEFT] ^ alphabit ^ 1; 86 | tCW[i-1][RIGHT] = t0[RIGHT] ^ t1[RIGHT] ^ alphabit; 87 | 88 | if(t[i-1][0] == 1){ 89 | s[i][0] = dpf_xor(s0[keep], sCW[i-1]); 90 | t[i][0] = t0[keep] ^ tCW[i-1][keep]; 91 | }else{ 92 | s[i][0] = s0[keep]; 93 | t[i][0] = t0[keep]; 94 | } 95 | 96 | if(t[i-1][1] == 1){ 97 | s[i][1] = dpf_xor(s1[keep], sCW[i-1]); 98 | t[i][1] = t1[keep] ^ tCW[i-1][keep]; 99 | }else{ 100 | s[i][1] = s1[keep]; 101 | t[i][1] = t1[keep]; 102 | } 103 | } 104 | 105 | block finalblock; 106 | finalblock = dpf_zero_block(); 107 | finalblock = dpf_reverse_lsb(finalblock); 108 | 109 | char shift = (alpha) & 127; 110 | if(shift & 64){ 111 | finalblock = dpf_left_shirt(finalblock, 64); 112 | } 113 | if(shift & 32){ 114 | finalblock = dpf_left_shirt(finalblock, 32); 115 | } 116 | if(shift & 16){ 117 | finalblock = dpf_left_shirt(finalblock, 16); 118 | } 119 | if(shift & 8){ 120 | finalblock = dpf_left_shirt(finalblock, 8); 121 | } 122 | if(shift & 4){ 123 | finalblock = dpf_left_shirt(finalblock, 4); 124 | } 125 | if(shift & 2){ 126 | finalblock = dpf_left_shirt(finalblock, 2); 127 | } 128 | if(shift & 1){ 129 | finalblock = dpf_left_shirt(finalblock, 1); 130 | } 131 | 132 | finalblock = dpf_reverse_lsb(finalblock); 133 | 134 | finalblock = dpf_xor(finalblock, s[maxlayer][0]); 135 | finalblock = dpf_xor(finalblock, s[maxlayer][1]); 136 | 137 | unsigned char *buff0; 138 | unsigned char *buff1; 139 | buff0 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxlayer + 16); 140 | buff1 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxlayer + 16); 141 | 142 | if(buff0 == NULL || buff1 == NULL){ 143 | printf("Memory allocation failed\n"); 144 | exit(1); 145 | } 146 | 147 | buff0[0] = n; 148 | memcpy(&buff0[1], &s[0][0], 16); 149 | buff0[17] = t[0][0]; 150 | for(i = 1; i <= maxlayer; i++){ 151 | memcpy(&buff0[18 * i], &sCW[i-1], 16); 152 | buff0[18 * i + 16] = tCW[i-1][0]; 153 | buff0[18 * i + 17] = tCW[i-1][1]; 154 | } 155 | memcpy(&buff0[18 * maxlayer + 18], &finalblock, 16); 156 | 157 | buff1[0] = n; 158 | memcpy(&buff1[18], &buff0[18], 18 * (maxlayer)); 159 | memcpy(&buff1[1], &s[0][1], 16); 160 | buff1[17] = t[0][1]; 161 | memcpy(&buff1[18 * maxlayer + 18], &finalblock, 16); 162 | 163 | *k0 = buff0; 164 | *k1 = buff1; 165 | } 166 | 167 | block EVAL(AES_KEY *key, unsigned char* k, int x){ 168 | int n = k[0]; 169 | int maxlayer = n - 7; 170 | 171 | block s[maxlayer + 1]; 172 | int t[maxlayer + 1]; 173 | block sCW[maxlayer]; 174 | int tCW[maxlayer][2]; 175 | block finalblock; 176 | 177 | memcpy(&s[0], &k[1], 16); 178 | t[0] = k[17]; 179 | 180 | int i; 181 | for(i = 1; i <= maxlayer; i++){ 182 | memcpy(&sCW[i-1], &k[18 * i], 16); 183 | tCW[i-1][0] = k[18 * i + 16]; 184 | tCW[i-1][1] = k[18 * i + 17]; 185 | } 186 | 187 | memcpy(&finalblock, &k[18 * (maxlayer + 1)], 16); 188 | 189 | block sL, sR; 190 | int tL, tR; 191 | for(i = 1; i <= maxlayer; i++){ 192 | PRG(key, s[i - 1], &sL, &sR, &tL, &tR); 193 | 194 | if(t[i-1] == 1){ 195 | sL = dpf_xor(sL, sCW[i-1]); 196 | sR = dpf_xor(sR, sCW[i-1]); 197 | tL = tL ^ tCW[i-1][0]; 198 | tR = tR ^ tCW[i-1][1]; 199 | } 200 | 201 | int xbit = getbit(x, n, i); 202 | if(xbit == 0){ 203 | s[i] = sL; 204 | t[i] = tL; 205 | }else{ 206 | s[i] = sR; 207 | t[i] = tR; 208 | } 209 | } 210 | 211 | block res; 212 | res = s[maxlayer]; 213 | if(t[maxlayer] == 1){ 214 | res = dpf_reverse_lsb(res); 215 | } 216 | 217 | if(t[maxlayer] == 1){ 218 | res = dpf_xor(res, finalblock); 219 | } 220 | 221 | return res; 222 | } 223 | 224 | block* EVALFULL(AES_KEY *key, unsigned char* k){ 225 | int n = k[0]; 226 | int maxlayer = n - 7; 227 | int maxlayeritem = 1 << (n - 7); 228 | 229 | block s[2][maxlayeritem]; 230 | int t[2][maxlayeritem]; 231 | 232 | int curlayer = 1; 233 | 234 | block sCW[maxlayer]; 235 | int tCW[maxlayer][2]; 236 | block finalblock; 237 | 238 | memcpy(&s[0][0], &k[1], 16); 239 | t[0][0] = k[17]; 240 | 241 | int i, j; 242 | for(i = 1; i <= maxlayer; i++){ 243 | memcpy(&sCW[i-1], &k[18 * i], 16); 244 | tCW[i-1][0] = k[18 * i + 16]; 245 | tCW[i-1][1] = k[18 * i + 17]; 246 | } 247 | 248 | memcpy(&finalblock, &k[18 * (maxlayer + 1)], 16); 249 | 250 | block sL, sR; 251 | int tL, tR; 252 | for(i = 1; i <= maxlayer; i++){ 253 | int itemnumber = 1 << (i - 1); 254 | for(j = 0; j < itemnumber; j++){ 255 | PRG(key, s[1 - curlayer][j], &sL, &sR, &tL, &tR); 256 | 257 | if(t[1 - curlayer][j] == 1){ 258 | sL = dpf_xor(sL, sCW[i-1]); 259 | sR = dpf_xor(sR, sCW[i-1]); 260 | tL = tL ^ tCW[i-1][0]; 261 | tR = tR ^ tCW[i-1][1]; 262 | } 263 | 264 | s[curlayer][2 * j] = sL; 265 | t[curlayer][2 * j] = tL; 266 | s[curlayer][2 * j + 1] = sR; 267 | t[curlayer][2 * j + 1] = tR; 268 | } 269 | curlayer = 1 - curlayer; 270 | } 271 | 272 | int itemnumber = 1 << maxlayer; 273 | block *res = (block*) malloc(sizeof(block) * itemnumber); 274 | 275 | for(j = 0; j < itemnumber; j ++){ 276 | res[j] = s[1 - curlayer][j]; 277 | 278 | if(t[1 - curlayer][j] == 1){ 279 | res[j] = dpf_reverse_lsb(res[j]); 280 | } 281 | 282 | if(t[1 - curlayer][j] == 1){ 283 | res[j] = dpf_xor(res[j], finalblock); 284 | } 285 | } 286 | 287 | return res; 288 | } 289 | 290 | int getsize(unsigned char *k){ 291 | char n = k[0]; 292 | int maxlayer = n - 7; 293 | 294 | return (18 * (maxlayer + 1) + 16); 295 | } 296 | 297 | int main(int argc, char** argv){ 298 | long long userkey1 = 597349; long long userkey2 = 121379; 299 | block userkey = dpf_make_block(userkey1, userkey2); 300 | 301 | dpf_seed(NULL); 302 | 303 | AES_KEY key; 304 | AES_set_encrypt_key(userkey, &key); 305 | 306 | 307 | if(argc != 3){ 308 | printf("format: fssgen N alpha\n"); 309 | exit(0); 310 | } 311 | 312 | int n, alpha; 313 | sscanf(argv[1], "%d", &n); 314 | sscanf(argv[2], "%d", &alpha); 315 | 316 | unsigned char *k0; 317 | unsigned char *k1; 318 | 319 | GEN(&key, alpha, n, &k0, &k1); 320 | int ksize = getsize(k0); 321 | 322 | FILE* testfp = fopen("./k0", "wb"); 323 | fwrite(k0, ksize, 1, testfp); 324 | fclose(testfp); 325 | 326 | testfp = fopen("./k1", "wb"); 327 | fwrite(k1, ksize, 1, testfp); 328 | fclose(testfp); 329 | 330 | return 0; 331 | } 332 | -------------------------------------------------------------------------------- /utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "aes.h" 4 | #include "block.h" 5 | 6 | block dpf_reverse_lsb(block input){ 7 | static long long b1 = 0; 8 | static long long b2 = 1; 9 | block xor = dpf_make_block(b1, b2); 10 | return dpf_xor(input, xor); 11 | } 12 | 13 | block dpf_set_lsb_zero(block input){ 14 | int lsb = dpf_lsb(input); 15 | 16 | if(lsb == 1){ 17 | return dpf_reverse_lsb(input); 18 | }else{ 19 | return input; 20 | } 21 | } 22 | 23 | void PRG(AES_KEY *key, block input, block* output1, block* output2, int* bit1, int* bit2){ 24 | input = dpf_set_lsb_zero(input); 25 | 26 | block stash[2]; 27 | stash[0] = input; 28 | stash[1] = dpf_reverse_lsb(input); 29 | 30 | AES_ecb_encrypt_blks(stash, 2, key); 31 | 32 | stash[0] = dpf_xor(stash[0], input); 33 | stash[1] = dpf_xor(stash[1], input); 34 | stash[1] = dpf_reverse_lsb(stash[1]); 35 | 36 | *bit1 = dpf_lsb(stash[0]); 37 | *bit2 = dpf_lsb(stash[1]); 38 | 39 | *output1 = dpf_set_lsb_zero(stash[0]); 40 | *output2 = dpf_set_lsb_zero(stash[1]); 41 | } 42 | 43 | static int getbit(int x, int n, int b){ 44 | return ((unsigned int)(x) >> (n - b)) & 1; 45 | } 46 | 47 | void GEN(AES_KEY *key, int alpha, int n, unsigned char** k0, unsigned char **k1){ 48 | int maxlayer = n - 7; 49 | //int maxlayer = n; 50 | 51 | block s[maxlayer + 1][2]; 52 | int t[maxlayer + 1 ][2]; 53 | block sCW[maxlayer]; 54 | int tCW[maxlayer][2]; 55 | 56 | s[0][0] = dpf_random_block(); 57 | s[0][1] = dpf_random_block(); 58 | t[0][0] = dpf_lsb(s[0][0]); 59 | t[0][1] = t[0][0] ^ 1; 60 | s[0][0] = dpf_set_lsb_zero(s[0][0]); 61 | s[0][1] = dpf_set_lsb_zero(s[0][1]); 62 | 63 | int i; 64 | block s0[2], s1[2]; // 0=L,1=R 65 | #define LEFT 0 66 | #define RIGHT 1 67 | int t0[2], t1[2]; 68 | for(i = 1; i<= maxlayer; i++){ 69 | PRG(key, s[i-1][0], &s0[LEFT], &s0[RIGHT], &t0[LEFT], &t0[RIGHT]); 70 | PRG(key, s[i-1][1], &s1[LEFT], &s1[RIGHT], &t1[LEFT], &t1[RIGHT]); 71 | 72 | int keep, lose; 73 | int alphabit = getbit(alpha, n, i); 74 | if(alphabit == 0){ 75 | keep = LEFT; 76 | lose = RIGHT; 77 | }else{ 78 | keep = RIGHT; 79 | lose = LEFT; 80 | } 81 | 82 | sCW[i-1] = dpf_xor(s0[lose], s1[lose]); 83 | 84 | tCW[i-1][LEFT] = t0[LEFT] ^ t1[LEFT] ^ alphabit ^ 1; 85 | tCW[i-1][RIGHT] = t0[RIGHT] ^ t1[RIGHT] ^ alphabit; 86 | 87 | if(t[i-1][0] == 1){ 88 | s[i][0] = dpf_xor(s0[keep], sCW[i-1]); 89 | t[i][0] = t0[keep] ^ tCW[i-1][keep]; 90 | }else{ 91 | s[i][0] = s0[keep]; 92 | t[i][0] = t0[keep]; 93 | } 94 | 95 | if(t[i-1][1] == 1){ 96 | s[i][1] = dpf_xor(s1[keep], sCW[i-1]); 97 | t[i][1] = t1[keep] ^ tCW[i-1][keep]; 98 | }else{ 99 | s[i][1] = s1[keep]; 100 | t[i][1] = t1[keep]; 101 | } 102 | } 103 | 104 | block finalblock; 105 | finalblock = dpf_zero_block(); 106 | finalblock = dpf_reverse_lsb(finalblock); 107 | 108 | char shift = (alpha) & 127; 109 | if(shift & 64){ 110 | finalblock = dpf_left_shirt(finalblock, 64); 111 | } 112 | if(shift & 32){ 113 | finalblock = dpf_left_shirt(finalblock, 32); 114 | } 115 | if(shift & 16){ 116 | finalblock = dpf_left_shirt(finalblock, 16); 117 | } 118 | if(shift & 8){ 119 | finalblock = dpf_left_shirt(finalblock, 8); 120 | } 121 | if(shift & 4){ 122 | finalblock = dpf_left_shirt(finalblock, 4); 123 | } 124 | if(shift & 2){ 125 | finalblock = dpf_left_shirt(finalblock, 2); 126 | } 127 | if(shift & 1){ 128 | finalblock = dpf_left_shirt(finalblock, 1); 129 | } 130 | dpf_cb(finalblock); 131 | finalblock = dpf_reverse_lsb(finalblock); 132 | 133 | finalblock = dpf_xor(finalblock, s[maxlayer][0]); 134 | finalblock = dpf_xor(finalblock, s[maxlayer][1]); 135 | 136 | unsigned char *buff0; 137 | unsigned char *buff1; 138 | buff0 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxlayer + 16); 139 | buff1 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxlayer + 16); 140 | 141 | if(buff0 == NULL || buff1 == NULL){ 142 | printf("Memory allocation failed\n"); 143 | exit(1); 144 | } 145 | 146 | buff0[0] = n; 147 | memcpy(&buff0[1], &s[0][0], 16); 148 | buff0[17] = t[0][0]; 149 | for(i = 1; i <= maxlayer; i++){ 150 | memcpy(&buff0[18 * i], &sCW[i-1], 16); 151 | buff0[18 * i + 16] = tCW[i-1][0]; 152 | buff0[18 * i + 17] = tCW[i-1][1]; 153 | } 154 | memcpy(&buff0[18 * maxlayer + 18], &finalblock, 16); 155 | 156 | buff1[0] = n; 157 | memcpy(&buff1[18], &buff0[18], 18 * (maxlayer)); 158 | memcpy(&buff1[1], &s[0][1], 16); 159 | buff1[17] = t[0][1]; 160 | memcpy(&buff1[18 * maxlayer + 18], &finalblock, 16); 161 | 162 | *k0 = buff0; 163 | *k1 = buff1; 164 | } 165 | 166 | block EVAL(AES_KEY *key, unsigned char* k, int x){ 167 | int n = k[0]; 168 | int maxlayer = n - 7; 169 | 170 | block s[maxlayer + 1]; 171 | int t[maxlayer + 1]; 172 | block sCW[maxlayer]; 173 | int tCW[maxlayer][2]; 174 | block finalblock; 175 | 176 | memcpy(&s[0], &k[1], 16); 177 | t[0] = k[17]; 178 | 179 | int i; 180 | for(i = 1; i <= maxlayer; i++){ 181 | memcpy(&sCW[i-1], &k[18 * i], 16); 182 | tCW[i-1][0] = k[18 * i + 16]; 183 | tCW[i-1][1] = k[18 * i + 17]; 184 | } 185 | 186 | memcpy(&finalblock, &k[18 * (maxlayer + 1)], 16); 187 | 188 | block sL, sR; 189 | int tL, tR; 190 | for(i = 1; i <= maxlayer; i++){ 191 | PRG(key, s[i - 1], &sL, &sR, &tL, &tR); 192 | 193 | if(t[i-1] == 1){ 194 | sL = dpf_xor(sL, sCW[i-1]); 195 | sR = dpf_xor(sR, sCW[i-1]); 196 | tL = tL ^ tCW[i-1][0]; 197 | tR = tR ^ tCW[i-1][1]; 198 | } 199 | 200 | int xbit = getbit(x, n, i); 201 | if(xbit == 0){ 202 | s[i] = sL; 203 | t[i] = tL; 204 | }else{ 205 | s[i] = sR; 206 | t[i] = tR; 207 | } 208 | } 209 | 210 | block res; 211 | res = s[maxlayer]; 212 | if(t[maxlayer] == 1){ 213 | res = dpf_reverse_lsb(res); 214 | } 215 | 216 | if(t[maxlayer] == 1){ 217 | res = dpf_xor(res, finalblock); 218 | } 219 | 220 | return res; 221 | } 222 | 223 | block* EVALFULL(AES_KEY *key, unsigned char* k){ 224 | int n = k[0]; 225 | int maxlayer = n - 7; 226 | int maxlayeritem = 1 << (n - 7); 227 | 228 | block s[2][maxlayeritem]; 229 | int t[2][maxlayeritem]; 230 | 231 | int curlayer = 1; 232 | 233 | block sCW[maxlayer]; 234 | int tCW[maxlayer][2]; 235 | block finalblock; 236 | 237 | memcpy(&s[0][0], &k[1], 16); 238 | t[0][0] = k[17]; 239 | 240 | int i, j; 241 | for(i = 1; i <= maxlayer; i++){ 242 | memcpy(&sCW[i-1], &k[18 * i], 16); 243 | tCW[i-1][0] = k[18 * i + 16]; 244 | tCW[i-1][1] = k[18 * i + 17]; 245 | } 246 | 247 | memcpy(&finalblock, &k[18 * (maxlayer + 1)], 16); 248 | 249 | block sL, sR; 250 | int tL, tR; 251 | for(i = 1; i <= maxlayer; i++){ 252 | int itemnumber = 1 << (i - 1); 253 | for(j = 0; j < itemnumber; j++){ 254 | PRG(key, s[1 - curlayer][j], &sL, &sR, &tL, &tR); 255 | 256 | if(t[1 - curlayer][j] == 1){ 257 | sL = dpf_xor(sL, sCW[i-1]); 258 | sR = dpf_xor(sR, sCW[i-1]); 259 | tL = tL ^ tCW[i-1][0]; 260 | tR = tR ^ tCW[i-1][1]; 261 | } 262 | 263 | s[curlayer][2 * j] = sL; 264 | t[curlayer][2 * j] = tL; 265 | s[curlayer][2 * j + 1] = sR; 266 | t[curlayer][2 * j + 1] = tR; 267 | } 268 | curlayer = 1 - curlayer; 269 | } 270 | 271 | int itemnumber = 1 << maxlayer; 272 | block *res = (block*) malloc(sizeof(block) * itemnumber); 273 | 274 | for(j = 0; j < itemnumber; j ++){ 275 | res[j] = s[1 - curlayer][j]; 276 | 277 | if(t[1 - curlayer][j] == 1){ 278 | res[j] = dpf_reverse_lsb(res[j]); 279 | } 280 | 281 | if(t[1 - curlayer][j] == 1){ 282 | res[j] = dpf_xor(res[j], finalblock); 283 | } 284 | } 285 | 286 | return res; 287 | } 288 | 289 | int main(){ 290 | long long userkey1 = 597349; long long userkey2 = 121379; 291 | block userkey = dpf_make_block(userkey1, userkey2); 292 | 293 | dpf_seed(NULL); 294 | 295 | AES_KEY key; 296 | AES_set_encrypt_key(userkey, &key); 297 | 298 | unsigned char *k0; 299 | unsigned char *k1; 300 | 301 | GEN(&key, 26943, 16, &k0, &k1); 302 | 303 | block res1; 304 | block res2; 305 | 306 | res1 = EVAL(&key, k0, 0); 307 | res2 = EVAL(&key, k1, 0); 308 | dpf_cb(res1); 309 | dpf_cb(res2); 310 | dpf_cb(dpf_xor(res1, res2)); 311 | 312 | res1 = EVAL(&key, k0, 128); 313 | res2 = EVAL(&key, k1, 128); 314 | dpf_cb(res1); 315 | dpf_cb(res2); 316 | dpf_cb(dpf_xor(res1, res2)); 317 | 318 | block *resf0, *resf1; 319 | resf0 = EVALFULL(&key, k0); 320 | resf1 = EVALFULL(&key, k1); 321 | 322 | int j; 323 | for(j = 0; j < 512; j++){ 324 | printf("Group %d\n", j); 325 | 326 | dpf_cb(resf0[j]); 327 | dpf_cb(resf1[j]); 328 | dpf_cb(dpf_xor(resf0[j], resf1[j])); 329 | } 330 | 331 | return 0; 332 | } 333 | --------------------------------------------------------------------------------