├── LICENSE ├── README.md ├── cpp ├── Makefile ├── Makefile.inc ├── accel │ ├── Accel.cpp │ ├── Accel.h │ ├── AccelSchedule.cpp │ ├── AccelSchedule.h │ ├── AccelTest.cpp │ ├── AccelTest.h │ ├── Dense.cpp │ ├── Dense.h │ ├── Makefile │ ├── README.md │ ├── accel_test_bnn.cpp │ ├── accel_test_layer.cpp │ ├── accel_test_random.cpp │ ├── hls.tcl │ ├── opt.tcl │ ├── parse_vivado.py │ └── sdsoc_build │ │ ├── Makefile │ │ ├── libhf_minizip │ │ ├── libaes.a │ │ ├── libminizip.a │ │ └── libz.a │ │ └── sds.tcl ├── minizip │ ├── CMakeLists.txt │ ├── ChangeLog │ ├── LICENSE │ ├── Makefile │ ├── Makefile.am │ ├── README.md │ ├── aes │ │ ├── Makefile │ │ ├── aes.h │ │ ├── aes_via_ace.h │ │ ├── aescrypt.c │ │ ├── aeskey.c │ │ ├── aesopt.h │ │ ├── aestab.c │ │ ├── aestab.h │ │ ├── brg_endian.h │ │ ├── brg_types.h │ │ ├── entropy.c │ │ ├── entropy.h │ │ ├── fileenc.c │ │ ├── fileenc.h │ │ ├── hmac.c │ │ ├── hmac.h │ │ ├── prng.c │ │ ├── prng.h │ │ ├── pwd2key.c │ │ ├── pwd2key.h │ │ ├── sha1.c │ │ └── sha1.h │ ├── configure.ac │ ├── crypt.h │ ├── ioapi.c │ ├── ioapi.h │ ├── ioapi_buf.c │ ├── ioapi_buf.h │ ├── ioapi_mem.c │ ├── ioapi_mem.h │ ├── iowin32.c │ ├── iowin32.h │ ├── libaes.a │ ├── libminizip.a │ ├── miniunz.c │ ├── miniunz.vcproj │ ├── minizip.c │ ├── minizip.pc.in │ ├── minizip.sln │ ├── minizip.vcproj │ ├── unzip.c │ ├── unzip.h │ ├── zip.c │ └── zip.h └── utils │ ├── Common.cpp │ ├── Common.h │ ├── DataIO.cpp │ ├── DataIO.h │ ├── Debug.h │ ├── Makefile │ ├── ParamIO.cpp │ ├── ParamIO.h │ ├── SArray.h │ ├── Timer.cpp │ ├── Timer.h │ ├── Typedefs.h │ ├── ZipIO.cpp │ ├── ZipIO.h │ └── open_zip.cpp ├── p15-zhao.pdf ├── params └── rnn_parameters.zip ├── settings64.sh └── setup.sh /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2017, Cornell University 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the copyright holder nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The codes implement LSTM, GRU RNN models with two rounding methods, including Binarization and Ternarization on FPGA. 2 | -------------------------------------------------------------------------------- /cpp/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean 2 | all: 3 | $(MAKE) -C minizip 4 | $(MAKE) -C utils 5 | $(MAKE) -C accel 6 | 7 | clean: 8 | $(MAKE) -C minizip clean 9 | $(MAKE) -C utils clean 10 | $(MAKE) -C accel clean 11 | -------------------------------------------------------------------------------- /cpp/Makefile.inc: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-O3 -std=gnu++11 -g 3 | MINIZIP_LDFLAGS=-lminizip -laes -lz 4 | LDFLAGS=$(MINIZIP_LDFLAGS) 5 | 6 | AR=ar rcs 7 | -------------------------------------------------------------------------------- /cpp/accel/Accel.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_ACCEL_H 2 | #define ACCEL_ACCEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include // include this before sds_lib.h for size_t 8 | 9 | #include "Typedefs.h" 10 | #include "Debug.h" 11 | #include "Common.h" 12 | 13 | /*#ifdef __SDSCC__ 14 | #include "sds_lib.h" 15 | #define MEM_ALLOC(size) sds_alloc(size) 16 | #define MEM_FREE(ptr) sds_free(ptr) 17 | #else 18 | #define MEM_ALLOC(size) malloc(size) 19 | #define MEM_FREE(ptr) free(ptr) 20 | #endif*/ 21 | 22 | //------------------------------------------------------------------- 23 | // Constants 24 | //------------------------------------------------------------------- 25 | 26 | // ML: define the param of Recurrent Neural Network 27 | const unsigned HID_SIZE = 128; 28 | const unsigned DATA_SIZE = 16; 29 | const unsigned DATA_PER_WORD = 4; 30 | const unsigned VOCAB_SIZE = 64; 31 | // 32 | 33 | const unsigned WORD_SIZE = 64; 34 | 35 | const unsigned WT_L = (128 + 128)* 4 * 128; // parameter to control wt mem size 36 | const unsigned BIAS_L = 128 * 4; // ML: parameter to control bias memsize 37 | 38 | 39 | const unsigned WT_WORDS = WT_L / WORD_SIZE; // ML: beyond the mem on chip? 40 | const unsigned BIAS_WORDS = BIAS_L / WORD_SIZE; 41 | 42 | 43 | // ML: mem of input data and output data 44 | const unsigned DMEM_WORDS = 64/DATA_PER_WORD; 45 | const unsigned DMEM_O_WORDS = 64/DATA_PER_WORD; 46 | 47 | 48 | //------------------------------------------------------------------- 49 | // Typedefs 50 | //------------------------------------------------------------------- 51 | enum RLayerTyprEnum {LAYER_RNN1, LAYER_RNN2, LAYER_LAST}; 52 | // 53 | typedef ap_int Word; 54 | 55 | typedef ap_uint<16> Address; 56 | /*typedef ap_int<12> ConvSum; 57 | typedef ap_int<5> ConvOut; 58 | typedef ap_uint<10> IdxType; 59 | typedef ap_fixed<16,4> C1Comp; // ML: -h/k be quantized to be 16 bits fixed-point on the fpconv layer 60 | typedef ap_int<16> NormComp; // ML: -h/k be quantized to be 16 bits int 61 | typedef ap_int<16> DenseSum; 62 | typedef ap_fixed<16,12> DenseNorm; 63 | 64 | typedef ap_fixed<20,2, AP_RND> C1InputType; // ML: input pixel are 20-bit fixed-point 65 | typedef ap_fixed<24,6, AP_RND> C1ConvType;*/ 66 | 67 | 68 | typedef ap_fixed<16,8> DATA; // ML: can do the exp operation 69 | 70 | 71 | //------------------------------------------------------------------- 72 | // Accelerator synthesizable top-level function 73 | //------------------------------------------------------------------- 74 | /*#pragma SDS data copy(dmem_i[0:input_words], dmem_o[0:output_words]) 75 | #pragma SDS data access_pattern(dmem_i:SEQUENTIAL, dmem_o:SEQUENTIAL) 76 | #pragma SDS data access_pattern(wt_i:SEQUENTIAL, kh_i:SEQUENTIAL) 77 | #pragma SDS data mem_attribute(dmem_i:PHYSICAL_CONTIGUOUS, dmem_o:PHYSICAL_CONTIGUOUS) 78 | #pragma SDS data mem_attribute(wt_i:PHYSICAL_CONTIGUOUS, kh_i:PHYSICAL_CONTIGUOUS) 79 | #pragma SDS data data_mover(dmem_i:AXIDMA_SIMPLE, dmem_o:AXIDMA_SIMPLE) 80 | #pragma SDS data data_mover(wt_i:AXIDMA_SIMPLE, kh_i:AXIDMA_SIMPLE) 81 | void top( 82 | Word wt_i[WT_WORDS], 83 | Word kh_i[KH_WORDS], 84 | Word dmem_i[DMEM_WORDS], 85 | Word dmem_o[DMEM_O_WORDS], 86 | const Address n_inputs, 87 | const Address n_outputs, 88 | const Address input_words, 89 | const Address output_words, 90 | const ap_uint<3> layer_mode, // [0]='new layer', [2:1]='conv1,conv,dense' 91 | const ap_uint<1> dmem_mode, // 0 means dmem[0] is input 92 | const ap_uint<2> width_mode, // 0=8'b, 1=16'b, 2=32'b 93 | const ap_uint<2> norm_mode // 0='do nothing', 1='do norm', 2='do pool' 94 | );*/ 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /cpp/accel/AccelSchedule.cpp: -------------------------------------------------------------------------------- 1 | #include "AccelSchedule.h" 2 | #include "AccelTest.h" 3 | #include "Timer.h" 4 | 5 | static Timer timers[N_LAYERS] = { 6 | "xl-FC", 7 | "xl-RNN2", 8 | "xl-RNN1", 9 | }; 10 | 11 | // ----------------------------------------------------------------------- 12 | // Each layer may need multiple invocations of the accelerator due to 13 | // limited on-chip storage of weights. 14 | // 15 | // This function computes the number of invocations needed and splits 16 | // the weights for each invocation. 17 | // 18 | // We make the following assumptions now: 19 | // 1. Only 1 output image per invocation 20 | // 2. wt_mem is large enough to hold the weights for at least 1 image 21 | // ----------------------------------------------------------------------- 22 | void compute_accel_schedule( 23 | Word* wt, 24 | Word* b, 25 | unsigned n_inputs, 26 | unsigned n_outputs, 27 | const ap_uint<2> layer_type, // 0=rnn1, 1=rnn2, 2=dense 28 | AccelSchedule &schedule, 29 | unsigned layer_idx 30 | ) { 31 | assert (wt != NULL); 32 | assert (b != NULL); 33 | 34 | ap_uint<3> layer_mode = 0; 35 | layer_mode(2,1) = layer_type(1,0); 36 | 37 | unsigned idx = 0; 38 | 39 | schedule.resize(1); 40 | 41 | layer_mode[0] = 1; 42 | 43 | // add a new invocation to the schedule 44 | schedule[idx].n_inputs = n_inputs; // ML: n_input has been modified 45 | schedule[idx].n_outputs = n_outputs; 46 | schedule[idx].layer_mode = layer_mode; 47 | 48 | 49 | unsigned o = 0; // ML: we assume there is no image batch 50 | 51 | Word* wt_i = schedule[idx].wt; 52 | if (layer_type < 2) { 53 | load_weights(wt, wt_i, o, n_inputs+n_outputs, 4*n_outputs); // ML: the weights are loaded on the wt_i 54 | } 55 | else { 56 | load_weights(wt, wt_i, o, n_inputs, n_outputs); 57 | } 58 | 59 | Word* b_i = schedule[idx].b; 60 | if (layer_type < 2) { 61 | load_bias(b, b_i, o, 4*n_outputs); 62 | } else { 63 | load_bias(b, b_i, o, n_outputs); 64 | } 65 | } 66 | 67 | 68 | 69 | // ----------------------------------------------------------------------- 70 | // load n_in*n_out single bit weights into accelerator 71 | // o is which output bit we are starting from 72 | // ----------------------------------------------------------------------- 73 | void load_weights(Word* wt, Word* wt_o, 74 | unsigned o, unsigned n_in, unsigned n_out 75 | ) { 76 | assert(n_in % WORD_SIZE == 0); 77 | // load in Word-sized chunks 78 | for (unsigned i = 0; i < n_in*n_out/WORD_SIZE; ++i) { 79 | wt_o[i] = wt[o*n_in/WORD_SIZE + i]; 80 | } 81 | } 82 | 83 | // ----------------------------------------------------------------------- 84 | // load n_out sets of kh params into accelerator 85 | // ----------------------------------------------------------------------- 86 | void load_bias(Word* b, Word b_i[], unsigned o, unsigned n_out) { 87 | for (unsigned i = 0; i < n_out / WORD_SIZE; ++i) { 88 | b_i[i] = b[o + i]; 89 | } 90 | } 91 | 92 | 93 | -------------------------------------------------------------------------------- /cpp/accel/AccelSchedule.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_ACCEL_SCHEDULE_H 2 | #define ACCEL_ACCEL_SCHEDULE_H 3 | 4 | #include 5 | #include "Accel.h" 6 | 7 | // Contains all info needed to invoke the accelerator once except 8 | // input/output data and its size which is handled separately 9 | struct AccelInfo { 10 | Word* wt; 11 | Word* b; 12 | unsigned n_inputs; 13 | unsigned n_outputs; 14 | ap_uint<3> layer_mode; // [0]='new layer', [2:1]='rnn1,rnn2,dense' 15 | 16 | 17 | AccelInfo() { 18 | wt = new Word[WT_WORDS]; 19 | b = new Word[BIAS_WORDS]; 20 | } 21 | 22 | ~AccelInfo() { 23 | delete[] wt; 24 | delete[] b; 25 | } 26 | }; 27 | 28 | typedef std::vector AccelSchedule; 29 | 30 | void compute_accel_schedule( 31 | Word* wt, 32 | Word* b, 33 | unsigned n_inputs, 34 | unsigned n_outputs, 35 | const ap_uint<2> layer_type, // 0=rnn1, 1=rnn2, 2=dense 36 | AccelSchedule &schedule, 37 | unsigned layer_idx 38 | ); 39 | 40 | 41 | void load_weights(Word* wt, Word* wt_o, 42 | unsigned o, unsigned n_in, unsigned n_out); 43 | 44 | void load_bias(Word* b, Word b_i[], unsigned o, unsigned n_out); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /cpp/accel/AccelTest.cpp: -------------------------------------------------------------------------------- 1 | #include "AccelTest.h" 2 | #include "AccelSchedule.h" 3 | #include 4 | #include 5 | 6 | //------------------------------------------------------------------------ 7 | // Helper functions 8 | //------------------------------------------------------------------------ 9 | 10 | bool layer_is_rnn(unsigned layer_idx) { 11 | assert(layer_idx != 0 && layer_idx <= N_LAYERS); 12 | return T_tab[layer_idx-1] == LAYER_RNN1 || T_tab[layer_idx-1] == LAYER_RNN2; 13 | } 14 | 15 | bool layer_is_last(unsigned layer_idx) { 16 | assert(layer_idx != 0 && layer_idx <= N_LAYERS); 17 | return T_tab[layer_idx-1] == LAYER_LAST; 18 | } 19 | 20 | // Simple log function, only works for powers of 2 21 | unsigned log2(unsigned x) { 22 | unsigned res = 0; 23 | while (x != 1) { 24 | x = x >> 1; 25 | res += 1; 26 | } 27 | return res; 28 | } 29 | 30 | //------------------------------------------------------------------------ 31 | // Binarize weights and pack them into Words 32 | //------------------------------------------------------------------------ 33 | 34 | void set_rnn_weight_array(Word* w, const float* wts_in, const float* wts_hid, unsigned layer_idx, unsigned weight_idx) { 35 | const unsigned M = M_tab[layer_idx-1]; 36 | const unsigned N = N_tab[layer_idx-1]; 37 | unsigned w_idx = 0; 38 | for (unsigned n = 0; n < N; ++n) { 39 | for (unsigned m = 0; m < M + N; m+=WORD_SIZE) { 40 | Word wrd = 0; 41 | if (m < M) { 42 | for (unsigned b = 0; b < WORD_SIZE; ++b) { 43 | wrd[b] = ((wts_in[(m+b)*N+n] < 0) ? 0 : 1); 44 | } 45 | } else { 46 | for (unsigned b = 0; b < WORD_SIZE; ++b) { 47 | wrd[b] = ((wts_hid[(m-M+b)*N+n] < 0) ? 0 : 1); 48 | } 49 | } 50 | w[weight_idx*(M+N)*N/WORD_SIZE + w_idx] = wrd; 51 | ++w_idx; 52 | } 53 | } 54 | } 55 | 56 | void set_rnn_bias_array(Word* b, const float* bias, unsigned layer_idx, unsigned weight_idx) { 57 | const unsigned N = N_tab[layer_idx-1]; 58 | unsigned b_idx = 0; 59 | Word wrd = 0; 60 | for (unsigned n = 0; n < N; n+=WORD_SIZE) { 61 | for (unsigned b = 0; b < WORD_SIZE; ++b) { 62 | wrd[b] = ((bias[n + b] < 0) ? 0 : 1); 63 | } 64 | b[weight_idx*N/WORD_SIZE + b_idx] = wrd; 65 | ++b_idx; 66 | } 67 | } 68 | 69 | 70 | 71 | void set_dense_weight_array(Word* w, const float* wts, unsigned layer_idx) { 72 | const unsigned M = M_tab[layer_idx-1]; 73 | const unsigned N = N_tab[layer_idx-1]; 74 | unsigned w_idx = 0; 75 | for (unsigned n = 0; n < N; ++n) { 76 | for (unsigned m = 0; m < M; m+=WORD_SIZE) { 77 | Word wrd = 0; 78 | for (unsigned b = 0; b < WORD_SIZE; ++b) { 79 | wrd[b] = ((wts[(m+b)*N+n] < 0) ? 0 : 1); 80 | } 81 | w[w_idx] = wrd; 82 | ++w_idx; 83 | } 84 | } 85 | } 86 | 87 | void set_dense_bias_array(Word* b, const float* bias, unsigned layer_idx) { 88 | const unsigned N = N_tab[layer_idx-1]; 89 | unsigned b_idx = 0; 90 | Word wrd = 0; 91 | for (unsigned n = 0; n < N; n+= WORD_SIZE) { 92 | for (unsigned b = 0; b < WORD_SIZE; ++b) { 93 | wrd[b] = ((bias[n + b] < 0) ? 0 : 1); 94 | } 95 | b[b_idx] = wrd; 96 | ++b_idx; 97 | } 98 | } 99 | 100 | // ML: char to index(Word type) 101 | void set_char_to_word(Word* data, char in) { 102 | for (unsigned i = 0; i < VOCAB_SIZE/DATA_PER_WORD; ++i) { 103 | data[i] = 0; 104 | } 105 | for (unsigned i = 0; i <= VOCAB_SIZE; ++i) { 106 | if (vocab[i] == in) { 107 | DATA start_seed = 1; 108 | data[i/DATA_PER_WORD]((i%DATA_PER_WORD+1)*16-1,(i%DATA_PER_WORD)*16) = start_seed(15,0); 109 | break; 110 | } 111 | } 112 | } 113 | 114 | 115 | /* 116 | //------------------------------------------------------------------------ 117 | // Helper test function for the accelerator conv layers 118 | //------------------------------------------------------------------------ 119 | void test_conv_layer( 120 | Word* weights, 121 | Word* kh, 122 | Word* data_i, 123 | Word* data_o, 124 | Word* conv_ref, 125 | Word* bin_ref, 126 | const unsigned M, 127 | const unsigned N, 128 | const unsigned Si, 129 | const ap_uint<1> conv_mode, // 0=conv1, 1=conv 130 | const ap_uint<1> max_pool 131 | ) { 132 | printf ("#### Testing convolution with %u inputs, width %u ####\n", M, Si); 133 | unsigned So = max_pool ? Si/2 : Si; 134 | unsigned input_words = conv_mode==0 ? Si*Si : M*Si*Si/WORD_SIZE; 135 | unsigned output_words = N*So*So/WORD_SIZE; 136 | if (output_words < 1) output_words = 1; 137 | assert (input_words <= DMEM_WORDS); 138 | //assert (output_words <= DMEM_O_WORDS); 139 | 140 | DB(3, 141 | printf ("*data*:\n"); 142 | print_bits3d(data_i, 0, 1, Si, 6,Si); 143 | printf ("*params*:\n"); 144 | print_params3d(weights, 0, 15); 145 | ) 146 | 147 | AccelSchedule sched; 148 | compute_accel_schedule( 149 | weights, kh, 150 | M, N, Si, 151 | conv_mode.to_int(), 152 | max_pool, 153 | sched 154 | ); 155 | 156 | run_accel_schedule( 157 | data_i, data_o, 158 | 0, // layer_idx 159 | input_words, 160 | output_words, 161 | 0, // dmem_mode 162 | sched 163 | ); 164 | 165 | // print results 166 | printf ("*bin out*:\n"); 167 | print_bits3d(data_o, 0, 1, So, 8,So); 168 | printf ("*bin ref*:\n"); 169 | print_bits3d(bin_ref, 0, 1, So, 8,So); 170 | 171 | // Compare bin results 172 | printf ("## Checking results ##\n"); 173 | unsigned n_err = 0; 174 | for (unsigned n = 0; n < N; ++n) { 175 | for (unsigned r = 0; r < So; ++r) { 176 | for (unsigned c = 0; c < So; ++c) { 177 | if (get_bit(data_o, n*So*So+r*So+c) != get_bit(bin_ref, n*So*So+r*So+c)) { 178 | n_err++; 179 | //printf ("bin out != ref at n=%d, (%d,%d)\n", n, r,c); 180 | //if (n_err > 64) exit(-1); 181 | } 182 | } 183 | } 184 | } 185 | float err_rate = float(n_err) / (N*So*So)*100; 186 | printf ("Error rate: %7.4f%%\n", err_rate); 187 | assert(err_rate < 1.0); 188 | } 189 | 190 | //------------------------------------------------------------------------ 191 | // Helper test function for the accelerator dense layers 192 | //------------------------------------------------------------------------ 193 | void test_dense_layer( 194 | Word* weights, 195 | Word* kh, 196 | Word* data_i, 197 | Word* data_o, 198 | Word* bin_ref, 199 | const unsigned M, // pixels 200 | const unsigned N // pixels 201 | ) { 202 | printf ("#### Testing dense layer with %u inputs, %u outputs ####\n", M, N); 203 | DB(3, 204 | printf ("*data*:\n"); 205 | print_bits(data_i, 0, 16, 8, 16); 206 | printf ("*params*:\n"); 207 | print_bits(weights, 0, 16, 8, 16); 208 | ) 209 | 210 | AccelSchedule sched; 211 | compute_accel_schedule( 212 | weights, kh, 213 | M, N, 1, 214 | 2, // layer_mode 215 | 0, // norm_mode 216 | sched 217 | ); 218 | 219 | run_accel_schedule( 220 | data_i, data_o, 221 | 0, // layer_idx 222 | M/WORD_SIZE, 223 | N/WORD_SIZE, 224 | 0, // dmem_mode 225 | sched 226 | ); 227 | 228 | // print results 229 | printf ("*bin out*:\n"); 230 | print_bits(data_o, 0, 16, 8, 16); 231 | printf ("*bin ref*:\n"); 232 | print_bits(bin_ref, 0, 16, 8, 16); 233 | 234 | // Compare bin results 235 | printf ("## Checking results ##\n"); 236 | unsigned n_err = 0; 237 | for (unsigned n = 0; n < N; ++n) { 238 | if (get_bit(data_o, n) != get_bit(bin_ref, n)) { 239 | n_err++; 240 | } 241 | } 242 | float err_rate = float(n_err)/N * 100; 243 | printf ("Error rate: %7.4f%%\n", err_rate); 244 | assert(err_rate < 1.0); 245 | }*/ 246 | -------------------------------------------------------------------------------- /cpp/accel/AccelTest.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_ACCEL_TEST_H 2 | #define ACCEL_ACCEL_TEST_H 3 | 4 | #include 5 | #include "Typedefs.h" 6 | #include "Accel.h" 7 | //#include "AccelPrint.h" 8 | #include 9 | 10 | // ML: num of layer of RNN 11 | const unsigned N_LAYERS = 3; 12 | // ML: num of weight arrays of every gate in rnn layer 13 | const unsigned N_W_LAYERS = 4; 14 | 15 | 16 | const unsigned M_tab[] = { 64, 128, 128}; // input num 17 | const unsigned N_tab[] = {128, 128, 64}; // output num 18 | const unsigned T_tab[] = { 0, 1, 2}; // type of 19 | const unsigned widx_tab[] = { 0, 1, 3, 4, 6, 7, 9, 10, 14, 15, 17, 18, 20, 21, 23, 24, 28}; // idx of each weight array in zip arc 20 | const unsigned bidx_tab[] = { 2, 5, 8, 11, 16, 19, 22, 25, 29}; // idx of each bias array in zip arc 21 | 22 | // num of elements in vocab 23 | const char vocab[] = {'\n', ' ', '!', '$', '&', '\'', ',', '-', '.', ':', ';', '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 24 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 25 | 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 26 | 'v', 'w', 'x', 'y', 'z'}; 27 | 28 | // layer_idx goes from 1 to 9 29 | bool layer_is_rnn(unsigned layer_idx); 30 | bool layer_is_last(unsigned layer_idx); 31 | 32 | // Simple log function, only works for powers of 2 33 | unsigned log2(unsigned x); 34 | 35 | //------------------------------------------------------------------------ 36 | // Set an array of ap_int's using some data, used to binarize test 37 | // inputs and outputs 38 | //------------------------------------------------------------------------ 39 | template 40 | void set_bit_array(T1 array[], const T2* data, unsigned size) { 41 | for (unsigned i = 0; i < size; ++i) { 42 | set_bit(array, i, (data[i]>=0) ? Bit(0) : Bit(-1)); 43 | } 44 | } 45 | 46 | //------------------------------------------------------------------------ 47 | // Functions used to preprocess params and inputs 48 | //------------------------------------------------------------------------ 49 | 50 | void set_rnn_weight_array(Word* w, const float* wts_in, const float* wts_hid, unsigned layer_idx, unsigned weight_idx); 51 | void set_rnn_bias_array(Word* b, const float* bias, unsigned layer_idx, unsigned weight_idx); 52 | void set_dense_weight_array(Word* w, const float* wts, unsigned layer_idx); 53 | void set_dense_bias_array(Word* b, const float* bias, unsigned layer_idx); 54 | void set_char_to_word(Word* data, char in); 55 | 56 | /* 57 | void set_bnorm_array(Word* kh, const float* k, const float* h, unsigned layer_idx); 58 | void set_bnorm_array1(Word* kh, const float* k, const float* h, unsigned layer_idx, unsigned N); 59 | void set_bnorm_array2(Word* kh, const float* k, const float* h, unsigned N); 60 | 61 | void binarize_input_images(Word* dmem_i, const float* inputs, unsigned S); 62 | 63 | //------------------------------------------------------------------------ 64 | // Padded convolution (used for golden reference) 65 | //------------------------------------------------------------------------ 66 | void padded_conv(Word in[], Word w[], Word out[], unsigned M, unsigned S); 67 | 68 | //------------------------------------------------------------------------ 69 | // Helper test function for the accelerator 70 | // This function calls the accelerator, then runs a check of the results 71 | // against conv_ref (if not NULL) and bin_ref. 72 | //------------------------------------------------------------------------ 73 | void test_conv_layer( 74 | Word* weights, 75 | Word* kh, 76 | Word* data_i, 77 | Word* data_o, 78 | Word* conv_ref, 79 | Word* bin_ref, 80 | const unsigned M, 81 | const unsigned N, 82 | const unsigned S, 83 | const ap_uint<1> conv_mode=1, 84 | const ap_uint<1> max_pool=0 85 | ); 86 | 87 | void test_dense_layer( 88 | Word* weights, 89 | Word* kh, 90 | Word* data_i, 91 | Word* data_o, 92 | Word* bin_ref, 93 | const unsigned M, // pixels 94 | const unsigned N // pixels 95 | );*/ 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /cpp/accel/Dense.cpp: -------------------------------------------------------------------------------- 1 | #include "Dense.h" 2 | #include "Timer.h" 3 | 4 | 5 | const static Word m1("0x5555555555555555", 16); 6 | const static Word m2("0x3333333333333333", 16); 7 | const static Word m4("0x0f0f0f0f0f0f0f0f", 16); 8 | const static Word h01("0x0101010101010101", 16); 9 | static Timer t_dense("dense"); 10 | static Timer t_last ("last"); 11 | 12 | // ----------------------------------------------------------------------- 13 | // Performs dense dot product on M input bits, n*M is the weight offset 14 | // ----------------------------------------------------------------------- 15 | // ML: the size of in[] is like 1*M and the size of w is n*M where M%word_size = 0 16 | // ML: a call of dotproduct_m can compute a dotproduct using index of n 17 | DATA sigmoid( 18 | const DATA in 19 | ) { 20 | DATA out; 21 | out = 1/(1+hls::exp((ap_fixed<16,8>) in)); 22 | return out; 23 | } 24 | 25 | DATA tanh( 26 | const DATA in 27 | ) { 28 | DATA out; 29 | out = (hls::exp((ap_fixed<16,8>) in) - hls::exp((ap_fixed<16,8>) -in)) / (hls::exp((ap_fixed<16,8>) in) + hls::exp((ap_fixed<16,8>) -in)); 30 | return out; 31 | } 32 | 33 | 34 | DATA dotproduct_m( 35 | const Word in[2*HID_SIZE], 36 | const Word w[WT_WORDS], 37 | const unsigned M, 38 | const unsigned n 39 | ) { 40 | assert (M % WORD_SIZE == 0); 41 | DATA sum = 0; 42 | static Word wt_wrd; 43 | 44 | // Loop across in the inputs in batches of WORD_SIZE 45 | for (unsigned m = 0; m < M; m+=WORD_SIZE) { 46 | 47 | DATA in_wrd[WORD_SIZE]; 48 | for (unsigned i = 0; i < WORD_SIZE; i+=DATA_PER_WORD) { 49 | in_wrd[i](15,0) = in[(m + i)/4](15,0); 50 | in_wrd[i+1](15,0) = in[(m + i)/4](31,16); 51 | in_wrd[i+2](15,0) = in[(m + i)/4](47,32); 52 | in_wrd[i+3](15,0) = in[(m + i)/4](63,48); 53 | } 54 | wt_wrd = w[(n*M+m)/WORD_SIZE]; 55 | 56 | for (unsigned i = 0; i < WORD_SIZE; ++i) { 57 | if (wt_wrd[i] > 0) 58 | sum += in_wrd[i]; 59 | else 60 | sum -= in_wrd[i]; 61 | } 62 | } 63 | return sum; 64 | } 65 | 66 | // ----------------------------------------------------------------------- 67 | // Internal dense layer 68 | // ----------------------------------------------------------------------- 69 | // ML: k, h is the coefficient of BNN! 70 | // ML: the size of in is M/DATA_PER_WORD = M/4 words; the size of out is N/DATA_PER_WORD! 71 | 72 | 73 | 74 | void dense_layer( 75 | Word data_i[DMEM_WORDS], 76 | Word data_o[DMEM_O_WORDS], 77 | unsigned layer_idx, 78 | const bool inputs_words, 79 | const Address n_inputs, 80 | const Address n_outputs, 81 | Word wt[WT_WORDS], 82 | Word b[BIAS_WORDS] 83 | ) { 84 | //t_dense.start(); 85 | static Word dmem[5][HID_SIZE/DATA_PER_WORD] = {0}; // ML: sequence: input/output, hid1, cell1, hid2, cell2 86 | 87 | 88 | 89 | Address M = n_inputs; 90 | Address N = n_outputs; 91 | 92 | //ap_uint<1> d_i_idx = dmem_mode; 93 | //ap_uint<1> d_o_idx = ~dmem_mode; 94 | 95 | static Word in[2*HID_SIZE/DATA_PER_WORD]; 96 | static DATA gate[4][HID_SIZE]; // ML: input, forget, cell(tanh), output 97 | 98 | if (layer_idx < 2) { 99 | LOOP_DMEM_I: 100 | for (unsigned i = 0; i < M+N; i+= DATA_PER_WORD) { 101 | if ((i < M) && (layer_idx == 0) && (inputs_words != 0) ) { 102 | in[i/DATA_PER_WORD] = data_i[i/DATA_PER_WORD]; 103 | } 104 | else if ((i < M) && (layer_idx == 0) && (inputs_words == 0)) { 105 | in[i/DATA_PER_WORD] = dmem[0][i/DATA_PER_WORD]; 106 | } 107 | else if ((i < M) && (layer_idx == 1)) { 108 | in[i/DATA_PER_WORD] = dmem[1][i/DATA_PER_WORD]; 109 | } 110 | else if ((i >= M) && (layer_idx == 0)) { 111 | in[i/DATA_PER_WORD] = dmem[1][(i-M)/DATA_PER_WORD]; 112 | } 113 | else{ 114 | in[i/DATA_PER_WORD] = dmem[3][(i-M)/DATA_PER_WORD]; 115 | } 116 | } 117 | } else { 118 | LOOP_DMEM_II: 119 | for (unsigned i = 0; i < M; i+= DATA_PER_WORD) { 120 | in[i/DATA_PER_WORD] = dmem[3][i/DATA_PER_WORD]; 121 | } 122 | } 123 | 124 | static Word wt_i[WT_WORDS] = {0}; 125 | static Word b_i[BIAS_WORDS] = {0}; 126 | 127 | LOOP_WT_I: 128 | for (unsigned j = 0; j < WT_WORDS; ++j) 129 | wt_i[j] = wt[j]; 130 | LOOP_B_I: 131 | for (unsigned j = 0; j < BIAS_WORDS; ++j) 132 | b_i[j] = b[j]; 133 | 134 | 135 | if (layer_idx == LAYER_LAST){ 136 | LOOP_DENSE_O: 137 | for (unsigned n = 0; n < N; n+=WORD_SIZE) { 138 | Word out_wrd[WORD_SIZE/DATA_PER_WORD] = {0}; 139 | LOOP_DENSE_I: 140 | for (unsigned nb = 0; nb < WORD_SIZE; ++nb) { 141 | DATA sum = dotproduct_m(in, wt_i, M, n+nb); 142 | out_wrd[nb/DATA_PER_WORD]((nb%DATA_PER_WORD+1)*16-1, (nb%DATA_PER_WORD)*16) = sum(15,0); 143 | } 144 | LOOP_DMEM_O: 145 | for (unsigned i = 0; i < WORD_SIZE / DATA_PER_WORD; ++i){ 146 | data_o[n/DATA_PER_WORD + i] = out_wrd[i]; 147 | dmem[0][n/DATA_PER_WORD + i] = out_wrd[i]; // ML: dont need another data buffer? 148 | } 149 | 150 | } 151 | } else { 152 | LOOP_RNN_O: 153 | for (unsigned n = 0; n < 4*N; n+=WORD_SIZE) { 154 | //Word out_wrd[WORD_SIZE/DATA_PER_WORD] = {0}; 155 | LOOP_RNN_I: 156 | for (unsigned nb = 0; nb < WORD_SIZE; ++nb) { 157 | DATA sum = dotproduct_m(in, wt_i, M+N, n+nb); 158 | //out_wrd[nb/DATA_PER_WORD]((nb%DATA_PER_WORD+1)*16-1, (nb%DATA_PER_WORD)*16-1) = sum(15,0); 159 | unsigned gate_idx = (n + nb) / N; 160 | unsigned gate_off = (n + nb) % N; 161 | unsigned idx = (n+nb)/DATA_PER_WORD; 162 | unsigned off = (n+nb)%DATA_PER_WORD; 163 | DATA bias; 164 | bias(15,0) = b_i[idx]((off+1)*16-1, (off*16)); 165 | gate[gate_idx][gate_off](15,0) = sum(15,0) + bias; 166 | } 167 | 168 | } 169 | 170 | LOOP_ACT: 171 | for (unsigned n = 0; n < 4*N; n++) { 172 | unsigned gate_idx = n / N; 173 | unsigned gate_off = n % N; 174 | DATA temp; 175 | 176 | if (gate_idx != 2) { 177 | temp = sigmoid(gate[gate_idx][gate_off]); 178 | gate[gate_idx][gate_off] = temp; 179 | } 180 | else { 181 | temp = tanh(gate[gate_idx][gate_off]); 182 | gate[gate_idx][gate_off] = temp; 183 | } 184 | } 185 | 186 | LOOP_DMEM: 187 | for (unsigned n = 0; n < N; n++) { 188 | DATA cell; 189 | DATA cell_pre; 190 | DATA hidden; 191 | unsigned idx = n / DATA_PER_WORD; 192 | unsigned offset = n % DATA_PER_WORD; 193 | cell_pre(15,0) = dmem[(layer_idx+1)*2][idx]((offset+1)*16-1, (offset)*16); 194 | // ML: new cell state 195 | cell = gate[1][n] * cell_pre + gate[0][n]*gate[2][n]; 196 | hidden = gate[3][n] * tanh(cell); 197 | dmem[(layer_idx+1)*2][idx]((offset+1)*16-1, offset*16) = cell(15,0); 198 | dmem[(layer_idx+1)*2 - 1][idx]((offset+1)*16-1, offset*16) = hidden(15,0); 199 | } 200 | 201 | 202 | } 203 | 204 | 205 | //t_dense.stop(); 206 | } 207 | 208 | -------------------------------------------------------------------------------- /cpp/accel/Dense.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_DENSE_H 2 | #define ACCEL_DENSE_H 3 | 4 | #include 5 | #include 6 | #include "Debug.h" 7 | #include "Typedefs.h" 8 | #include "Accel.h" 9 | #include "AccelSchedule.h" 10 | 11 | /*void dense_layer_cpu( 12 | const Word* w, 13 | const float* k_data, 14 | const float* h_data, 15 | const Word* data_i, 16 | Word* data_o, 17 | const unsigned M, 18 | const unsigned N 19 | );*/ 20 | #ifdef __SDSCC__ 21 | #include "sds_lib.h" 22 | #define MEM_ALLOC(size) sds_alloc(size) 23 | #define MEM_FREE(ptr) sds_free(ptr) 24 | #else 25 | #define MEM_ALLOC(size) malloc(size) 26 | #define MEM_FREE(ptr) free(ptr) 27 | #endif 28 | 29 | #pragma SDS data copy(data_i[0:16], data_o[0:16]) 30 | #pragma SDS data access_pattern(data_i:SEQUENTIAL, data_o:SEQUENTIAL) 31 | #pragma SDS data mem_attribute(data_i:PHYSICAL_CONTIGUOUS, data_o:PHYSICAL_CONTIGUOUS) 32 | #pragma SDS data data_mover(data_i:AXIDMA_SIMPLE, data_o:AXIDMA_SIMPLE) 33 | #pragma SDS data access_pattern(wt:SEQUENTIAL, b:SEQUENTIAL) 34 | #pragma SDS data mem_attribute(wt:PHYSICAL_CONTIGUOUS, b:PHYSICAL_CONTIGUOUS) 35 | #pragma SDS data data_mover(wt:AXIDMA_SIMPLE, b:AXIDMA_SIMPLE) 36 | void dense_layer( 37 | Word data_i[DMEM_WORDS], 38 | Word data_o[DMEM_O_WORDS], 39 | unsigned layer_idx, 40 | const bool inputs_words, 41 | const Address n_inputs, 42 | const Address n_outputs, 43 | Word wt[WT_WORDS], 44 | Word b[BIAS_WORDS] 45 | ); 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /cpp/accel/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | CFLAGS:=-I../utils $(CFLAGS) 4 | LDFLAGS:=-L../utils -L../minizip -lCraftUtils $(LDFLAGS) 5 | 6 | # HDR are pure headers 7 | HDR= 8 | # OBJ must include a .cpp and .h with same name 9 | OBJ=Accel.o AccelSchedule.o AccelTest.o Dense.o 10 | EXE=accel_test_bnn.exe 11 | #accel_test_layer.exe accel_test_random.exe 12 | 13 | all: $(EXE) 14 | 15 | # Rule for object files, each object must have a header 16 | $(OBJ): %.o: %.cpp %.h 17 | $(CXX) -c $< -o $@ $(CFLAGS) 18 | 19 | %.o: %.cpp 20 | $(CXX) -c $< -o $@ $(CFLAGS) 21 | 22 | # Rule for executables 23 | $(EXE): %.exe: %.o $(OBJ) 24 | g++ $^ -o $@ $(CFLAGS) $(LDFLAGS) 25 | 26 | .PHONY: hls clean hlsclean 27 | hls: 28 | vivado_hls hls.tcl 29 | 30 | hlsclean: 31 | rm -rf hls.prj vivado_hls.log 32 | 33 | clean: hlsclean 34 | rm -f *.o *.exe 35 | -------------------------------------------------------------------------------- /cpp/accel/README.md: -------------------------------------------------------------------------------- 1 | * Accel.h: the synthesizable accelerator code 2 | * AccelSchedule.h: driver functions for calling the accel to execute BNN layers 3 | * AccelTest.h: functions and helpers for writing test programs for the accel; many preproccessing function of data and parameters 4 | * AccelPrint.h: printing functions for weights and etc 5 | -------------------------------------------------------------------------------- /cpp/accel/accel_test_bnn.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "Accel.h" 6 | #include "AccelSchedule.h" 7 | #include "AccelTest.h" 8 | #include "Dense.h" 9 | #include "ZipIO.h" 10 | #include "ParamIO.h" 11 | #include "DataIO.h" 12 | #include "Timer.h" 13 | 14 | int main(int argc, char** argv) { 15 | if (argc < 2) { 16 | printf ("Give number of character to produce as 1st arg\n"); 17 | printf ("Give the initial srting as 2nd arg optional\n"); 18 | return 0; 19 | } 20 | const unsigned n_char = std::stoi(argv[1]); 21 | bool Init = false; 22 | char* str_init = NULL; 23 | 24 | if (argc == 3) { 25 | Init = true; 26 | str_init = argv[2]; // *ML: cant loas text with ' ' 27 | printf("* Initial string is %s\n", str_init); 28 | } 29 | // print some config numbers 30 | printf ("* WT_WORDS = %u\n", WT_WORDS); 31 | printf ("* BIAS_WORDS = %u\n", BIAS_WORDS); 32 | 33 | // Load input data 34 | //printf ("## Loading input data ##\n"); 35 | // ML: hidden state can be initialized by a given string 36 | 37 | // Load parameters 38 | printf ("## Loading parameters ##\n"); 39 | Params params(get_root_dir() + "/params/rnn_parameters.zip"); 40 | 41 | // --------------------------------------------------------------------- 42 | // allocate and binarize all weights 43 | // --------------------------------------------------------------------- 44 | Word* wt[N_LAYERS]; 45 | Word* b[N_LAYERS]; 46 | 47 | for (unsigned l = 0; l < N_LAYERS; ++l) { 48 | const unsigned M = M_tab[l]; 49 | const unsigned N = N_tab[l]; 50 | 51 | if (layer_is_rnn(l+1)) { 52 | wt[l] = new Word[(M+N)*4*N / WORD_SIZE]; 53 | b[l] = new Word[4*N / WORD_SIZE]; 54 | } 55 | else { 56 | wt[l] = new Word[M*N / WORD_SIZE]; // ML: RNN layers 57 | b[l] = new Word[N / WORD_SIZE]; 58 | } 59 | if (layer_is_rnn(l+1)) { 60 | for (unsigned w_l = 0; w_l < N_W_LAYERS; ++w_l) { 61 | // ML: set in_to weight and hid_to weight 62 | const float* weights_in = params.float_data(widx_tab[l*N_W_LAYERS*2 + 2*w_l]); 63 | const float* weights_hid = params.float_data(widx_tab[l*N_W_LAYERS*2 + 2*w_l +1]); 64 | set_rnn_weight_array(wt[l], weights_in, weights_hid, l+1, w_l); 65 | // ML: set bias 66 | const float* bias = params.float_data(bidx_tab[l*N_W_LAYERS + w_l]); 67 | set_rnn_bias_array(b[l], bias, l+1, w_l); 68 | } 69 | } else { 70 | 71 | const float* weights = params.float_data(widx_tab[16]); 72 | set_dense_weight_array(wt[l], weights, l+1); 73 | const float* bias = params.float_data(bidx_tab[8]); 74 | set_dense_bias_array(b[l], bias, l+1); 75 | } 76 | 77 | 78 | } 79 | 80 | // --------------------------------------------------------------------- 81 | // // compute accelerator schedule (divides up weights) 82 | // --------------------------------------------------------------------- 83 | AccelSchedule layer_sched[N_LAYERS]; 84 | for (unsigned l = 0; l < N_LAYERS; ++l) { 85 | compute_accel_schedule( 86 | wt[l], b[l], 87 | M_tab[l], N_tab[l], T_tab[l], 88 | layer_sched[l], l 89 | ); 90 | } 91 | 92 | // allocate memories for data i/o for the accelerator 93 | Word* data_i = (Word*) MEM_ALLOC( DMEM_WORDS * sizeof(Word) ); // ML: need to be modified! 94 | Word* data_o = (Word*) MEM_ALLOC( DMEM_O_WORDS * sizeof(Word) ); 95 | if (!data_i || !data_o) { 96 | fprintf (stderr, "**** ERROR: Alloc failed in %s\n", __FILE__); 97 | return (-2); 98 | } 99 | 100 | unsigned n_errors = 0; 101 | 102 | printf("## Initialing the RNN\n"); 103 | 104 | if (Init) { 105 | unsigned i = 0; 106 | while (str_init[i] != '\0') { 107 | set_char_to_word(data_i, str_init[i]); 108 | 109 | for (unsigned l = 1; l <= 3; ++l) { 110 | const unsigned M = M_tab[l-1]; 111 | const unsigned N = N_tab[l-1]; 112 | 113 | 114 | dense_layer( 115 | data_i, data_o, 116 | l-1, 117 | (l==1) ? 1 : 0, // input_words 118 | layer_sched[l-1][0].n_inputs, 119 | layer_sched[l-1][0].n_outputs, 120 | layer_sched[l-1][0].wt, 121 | layer_sched[l-1][0].b 122 | ); 123 | } 124 | i++; 125 | } 126 | } 127 | 128 | printf ("## Running RNN for %d characters\n", n_char); 129 | 130 | //-------------------------------------------------------------- 131 | // Run RNN 132 | //-------------------------------------------------------------- 133 | 134 | // ML: load an arbitrary input character [1, 0. 0, ..., 0] 135 | for (unsigned i = 0; i < VOCAB_SIZE/DATA_PER_WORD; ++i) { 136 | if (i == 0) { 137 | data_i[i] = 0; 138 | DATA start_seed = 1; 139 | data_i[i](15,0) = start_seed(15,0); 140 | } else { 141 | data_i[i] = 0; 142 | } 143 | } 144 | 145 | for (unsigned n = 0; n < n_char; ++n) { 146 | 147 | //------------------------------------------------------------ 148 | // Execute RNN layers 149 | //------------------------------------------------------------ 150 | for (unsigned l = 1; l <= 3; ++l) { 151 | const unsigned M = M_tab[l-1]; 152 | const unsigned N = N_tab[l-1]; 153 | 154 | dense_layer( 155 | data_i, data_o, 156 | l-1, 157 | (n==0 && l==1 && (~Init)) ? 1 : 0, // input_words 158 | layer_sched[l-1][0].n_inputs, 159 | layer_sched[l-1][0].n_outputs, 160 | layer_sched[l-1][0].wt, 161 | layer_sched[l-1][0].b 162 | ); 163 | } 164 | 165 | //------------------------------------------------------------ 166 | // Execute the prediciton 167 | //------------------------------------------------------------ 168 | int prediction = 0; 169 | int max = -512; // ML: may shoulb be less 170 | 171 | 172 | for (unsigned i = 0; i < VOCAB_SIZE; i++) { 173 | DATA temp; 174 | int add = i / DATA_PER_WORD; 175 | int off = i % DATA_PER_WORD; 176 | temp(15,0) = data_o[add]((off+1)*16-1,off*16); 177 | if (temp.to_int() > max) { 178 | max = temp; 179 | prediction = i; 180 | } 181 | } 182 | 183 | 184 | 185 | assert(prediction >= 0 && prediction <= 63); 186 | 187 | std::cout< 2 | #include 3 | 4 | #include "Accel.h" 5 | #include "AccelSchedule.h" 6 | #include "AccelTest.h" 7 | #include "Dense.h" 8 | #include "ZipIO.h" 9 | #include "ParamIO.h" 10 | #include "DataIO.h" 11 | 12 | int main(int argc, char** argv) { 13 | #ifdef HLS_COMPILE 14 | const unsigned l = 2; 15 | #else 16 | if (argc < 2) { 17 | printf ("Requires layer number as the first argument\n"); 18 | exit(-1); 19 | } 20 | const unsigned l = atoi(argv[1]); 21 | #endif 22 | 23 | assert (l < N_LAYERS); 24 | 25 | const unsigned lconv = 6; // last conv 26 | 27 | const unsigned Si = S_tab[l-1]; 28 | const unsigned So = S_tab[l]; 29 | const unsigned M = M_tab[l-1]; 30 | const unsigned N = N_tab[l-1]; 31 | const unsigned wt_size = (layer_is_conv(l)) ? WTS_TO_WORDS(M*N) : M*N/WORD_SIZE; 32 | const unsigned kh_size = N/KH_PER_WORD; 33 | 34 | Word* wt = new Word[wt_size]; 35 | Word* kh = new Word[kh_size]; 36 | Word* data_i = (Word*) MEM_ALLOC( DMEM_WORDS * sizeof(Word) ); 37 | Word* data_o = (Word*) MEM_ALLOC( N*So*So/WORD_SIZE * sizeof(Word) ); 38 | if (!wt || !kh || !data_i || !data_o) { 39 | fprintf (stderr, "**** ERROR: Alloc failed in %s\n", __FILE__); 40 | return (-2); 41 | } 42 | for (unsigned i = 0; i < wt_size; ++i) 43 | wt[i] = 0; 44 | for (unsigned i = 0; i < kh_size; ++i) 45 | kh[i] = 0; 46 | 47 | printf ("## Testing Layer %u with %u outputs ##\n", l, N); 48 | 49 | // Load reference output from zip and set data_i 50 | printf ("## Loading test data ##\n"); 51 | if (l == 1) { 52 | Cifar10TestInputs X(1); 53 | binarize_input_images(data_i, X.data, Si); 54 | } else { 55 | const float* input_maps = new float[M*Si*Si]; 56 | std::string l_type = layer_is_conv(l) ? "/data/cpp_conv" : "/data/cpp_dense"; 57 | unsigned l_num = layer_is_conv(l) ? l-1 : l-L_CONV-1; 58 | std::string input_file = get_root_dir() + l_type + std::to_string(l_num) + "_maps.zip"; 59 | unzip_to_array(input_file, input_maps); 60 | set_bit_array(data_i, input_maps, M*Si*Si); 61 | delete[] input_maps; 62 | } 63 | 64 | // Binarize weights 65 | printf ("## Loading parameters ##\n"); 66 | Params params(get_root_dir() + "/params/cifar10_parameters_nb.zip"); 67 | const float* weights = params.float_data(widx_tab[l-1]); 68 | set_weight_array(wt, weights, l); 69 | 70 | // Binarize batch-norm parameters 71 | const float* k = params.float_data(kidx_tab[l-1]); 72 | const float* h = params.float_data(hidx_tab[l-1]); 73 | set_bnorm_array(kh, k, h, l); 74 | 75 | // Load binary ref 76 | Word* bin_ref = new Word[N*So*So/WORD_SIZE]; 77 | if (layer_is_last(l)) { 78 | bin_ref[0] = 3; 79 | } else { 80 | const float* output_maps = new float[N*So*So]; 81 | std::string l_type = layer_is_conv(l) ? "/data/cpp_conv" : "/data/cpp_dense"; 82 | unsigned l_num = layer_is_conv(l) ? l : l-L_CONV; 83 | std::string output_file = get_root_dir() + l_type + std::to_string(l_num) + "_maps.zip"; 84 | unzip_to_array(output_file, output_maps); 85 | set_bit_array(bin_ref, output_maps, N*So*So); 86 | delete[] output_maps; 87 | } 88 | 89 | // Perform test 90 | if (layer_is_conv(l)) { 91 | test_conv_layer( 92 | wt, kh, data_i, data_o, 93 | NULL, bin_ref, 94 | M, N, Si, 95 | (l==1) ? 0 : 1, // conv_mode 96 | pool_tab[l-1] // max_pool 97 | ); 98 | } else { 99 | test_dense_layer( 100 | wt, kh, data_i, data_o, 101 | bin_ref, 102 | M, N 103 | ); 104 | } 105 | 106 | printf ("Tests passed!\n"); 107 | 108 | delete[] bin_ref; 109 | MEM_FREE( data_o ); 110 | MEM_FREE( data_i ); 111 | delete[] kh; 112 | delete[] wt; 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /cpp/accel/accel_test_random.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "Accel.h" 5 | #include "AccelSchedule.h" 6 | #include "AccelTest.h" 7 | 8 | // used to generate test data 9 | unsigned simple_hash(unsigned x) { 10 | unsigned temp = (((x)*(x+3)*(x+11)) % 47); 11 | return temp ^ (temp >> 2) ^ (temp >> 4) ^ (temp >> 6) & 1; 12 | } 13 | 14 | //------------------------------------------------------------------------ 15 | // Helper test function for the accelerator, random data 16 | //------------------------------------------------------------------------ 17 | void test_conv_layer_random( 18 | const unsigned S, 19 | Word* wt, 20 | Word* kh 21 | ) { 22 | const unsigned M = CONVOLVERS*PIX_PER_PHASE / (S*S); 23 | 24 | // Generate the input data 25 | assert (M*S*S <= DMEM_WORDS*WORD_SIZE); 26 | Word* data_i = (Word*) MEM_ALLOC( DMEM_WORDS * sizeof(Word) ); 27 | for (unsigned m = 0; m < M; ++m) { 28 | for (unsigned r = 0; r < S; ++r) { 29 | for (unsigned c = 0; c < S; ++c) { 30 | set_bit(data_i, m*S*S+r*S+c, simple_hash(m*S*S+r*S+c)); 31 | } } } 32 | 33 | assert (S*S <= DMEM_O_WORDS*WORD_SIZE); 34 | Word* data_o = (Word*) MEM_ALLOC( DMEM_O_WORDS * sizeof(Word) ); 35 | 36 | DB(2, 37 | printf ("*data*:\n"); 38 | print_bits3d(data_i, 0, 2, S, 8,S); 39 | printf ("*params*:\n"); 40 | print_bits3d(wt, 0, 2, K, K,K); 41 | ); 42 | 43 | // Compute conv reference 44 | Word conv_ref[S*S]; 45 | padded_conv(data_i, wt, conv_ref, M, S); 46 | // Compute bin reference 47 | Word khword = kh[0]; 48 | NormComp nc; nc(15,0) = khword(15,0); 49 | Word bin_ref[S*S]; 50 | for (unsigned i = 0; i < S*S; ++i) { 51 | Bit b = (conv_ref[i] < nc) ? -1 : 0; 52 | set_bit(bin_ref, i, b); 53 | } 54 | 55 | test_conv_layer( 56 | wt, kh, data_i, data_o, conv_ref, bin_ref, 57 | M, 1, S 58 | ); 59 | 60 | MEM_FREE( data_i ); 61 | MEM_FREE( data_o ); 62 | } 63 | 64 | //------------------------------------------------------------------------ 65 | // Main 66 | //------------------------------------------------------------------------ 67 | int main() { 68 | const unsigned N = 1; 69 | 70 | Word* wt = new Word[WT_WORDS]; 71 | Word* kh = new Word[KH_WORDS]; 72 | 73 | // initialize the kernel weights 74 | for (unsigned m = 0; m < WT_WORDS; ++m) { 75 | for (unsigned i = 0; i < WORD_SIZE; ++i) 76 | set_bit(wt, m*WORD_SIZE+i, simple_hash(m*WORD_SIZE+i)); 77 | } 78 | // initialize the batch-norm params 79 | for (unsigned n = 0; n < N; ++n) { 80 | NormComp nc = 10 + 10*n; 81 | 82 | int off = n % KH_PER_WORD; 83 | 84 | Word w = kh[n/KH_PER_WORD]; 85 | w((off+1)*16-1, off*16) = nc(15,0); 86 | kh[n/KH_PER_WORD] = w; 87 | } 88 | 89 | test_conv_layer_random( 8, wt, kh); 90 | test_conv_layer_random(16, wt, kh); 91 | test_conv_layer_random(32, wt, kh); 92 | 93 | delete[] wt; 94 | delete[] kh; 95 | 96 | printf ("Tests passed!\n"); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /cpp/accel/hls.tcl: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # hls.tcl 3 | #========================================================================= 4 | 5 | set top "top" 6 | set cflags "-DHLS_COMPILE -O3 -std=c++0x -I../utils" 7 | set tbflags "-DHLS_COMPILE -O3 -std=c++0x -I../utils -lminizip -laes -lz" 8 | set utils "../utils/Common.cpp ../utils/DataIO.cpp ../utils/ParamIO.cpp ../utils/ZipIO.cpp" 9 | 10 | open_project hls.prj 11 | 12 | set_top $top 13 | 14 | add_files Accel.cpp -cflags $cflags 15 | add_files -tb accel_test_random.cpp -cflags $tbflags 16 | add_files -tb AccelSchedule.cpp -cflags $cflags 17 | add_files -tb AccelTest.cpp -cflags $cflags 18 | #add_files -tb AccelPrint.cpp -cflags $cflags 19 | #add_files -tb InputConv.cpp -cflags $tbflags 20 | add_files -tb Dense.cpp -cflags $tbflags 21 | add_files -tb $utils -cflags $tbflags 22 | 23 | open_solution "solution1" -reset 24 | 25 | set_part {xc7z020clg484-1} 26 | create_clock -period 5 27 | 28 | config_rtl -reset state 29 | 30 | # Apply optimizations 31 | source opt.tcl 32 | 33 | csim_design 34 | 35 | csynth_design 36 | cosim_design -rtl verilog -trace_level all 37 | 38 | #export_design -evaluate verilog 39 | 40 | exit 41 | -------------------------------------------------------------------------------- /cpp/accel/opt.tcl: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # opt.tcl 3 | #========================================================================= 4 | set_directive_pipeline dense_layer/LOOP_DMEM_I 5 | set_directive_pipeline dense_layer/LOOP_DMEM_II 6 | set_directive_pipeline dense_layer/LOOP_WT_I 7 | set_directive_pipeline dense_layer/LOOP_B_I 8 | set_directive_pipeline dense_layer/LOOP_DMEM_O 9 | 10 | set_directive_loop_tripcount -min 48 -max 64 dense_layer/LOOP_DMEM_I 11 | set_directive_loop_tripcount -min 32 -max 32 dense_layer/LOOP_DMEM_II 12 | 13 | #set_directive_unroll dense_layer/LOOP_WT_I 14 | #set_directive_unroll dense_layer/LOOP_B_I 15 | 16 | set_directive_pipeline dense_layer/LOOP_DENSE_I 17 | set_directive_loop_tripcount -min 1 -max 2 dense_layer/LOOP_DENSE_O 18 | 19 | set_directive_loop_tripcount -min 8 -max 8 dense_layer/LOOP_RNN_O 20 | set_directive_pipeline dense_layer/LOOP_RNN_I 21 | 22 | set_directive_loop_tripcount -min 512 -max 512 dense_layer/LOOP_ACT 23 | set_directive_pipeline dense_layer/LOOP_ACT 24 | 25 | set_directive_loop_tripcount -min 128 -max 128 dense_layer/LOOP_DMEM 26 | set_directive_pipeline dense_layer/LOOP_DMEM 27 | 28 | 29 | set_directive_array_partition dense_layer dmem -dim 1 -type complete 30 | set_directive_array_partition dense_layer in -dim 0 -type complete 31 | set_directive_array_partition dense_layer gate -dim 0 -type complete 32 | 33 | 34 | 35 | #========================================================================= 36 | -------------------------------------------------------------------------------- /cpp/accel/parse_vivado.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os, re, glob, sys 4 | import xml.etree.ElementTree as ET 5 | 6 | #------------------------------------------------------------------------- 7 | # Helper functions 8 | #------------------------------------------------------------------------- 9 | # get all the immediate directories 10 | def get_immediate_subdirs(dir): 11 | return filter(os.path.isdir, [os.path.join(dir,f) for f in os.listdir(dir)]) 12 | 13 | # Safely change directories. Uncommet prints for debugging 14 | def changedir(dir): 15 | #print >>sys.stderr, "Entering", dir 16 | if not os.path.exists(dir): 17 | #print >>sys.stderr, "Path", dir, "does not exist" 18 | return 0 19 | os.chdir(dir) 20 | return 1 21 | 22 | # Find text on an xml node 23 | def find_text(node, string): 24 | newnode = node.find(string) 25 | if not newnode is None: 26 | return newnode.text 27 | else: 28 | #print >>sys.stderr, "Could not find", string 29 | return "-not found-" 30 | 31 | #------------------------------------------------------------------------- 32 | # Parse resource 33 | #------------------------------------------------------------------------- 34 | def parse_impl_xml(file): 35 | tree = ET.parse(file) 36 | root = tree.getroot() 37 | 38 | # area report 39 | area_report = root.find("AreaReport") 40 | resources = area_report.find("Resources") 41 | slice = resources.find("SLICE").text 42 | lut = resources.find("LUT").text 43 | ff = resources.find("FF").text 44 | srl = resources.find("SRL").text 45 | bram = resources.find("BRAM").text 46 | dsp = resources.find("DSP").text 47 | 48 | # timing report 49 | timing_report = root.find("TimingReport") 50 | target_cp = timing_report.find("TargetClockPeriod").text 51 | actual_cp = timing_report.find("AchievedClockPeriod").text 52 | 53 | return dict([("Slice",slice), ("LUT",lut), ("FF",ff), \ 54 | ("SRL",srl), ("BRAM",bram), ("DSP",dsp), \ 55 | ("Target-CP",target_cp), ("Actual-CP",actual_cp)]) 56 | 57 | def parse_impl(): 58 | TopLevel = os.getcwd() 59 | res_dir = "impl/report/verilog/" 60 | if not changedir(res_dir): 61 | print >>sys.stderr, "**** Cannot find", res_dir, "in", TopLevel 62 | return 0 63 | 64 | files = glob.glob("*.xml") 65 | if len(files) != 1: 66 | files.sort(key=len) 67 | #print >>sys.stderr, "Found", len(files), "xml files in" 68 | #print >>sys.stderr, "\t", TopLevel++"/"+res_dir 69 | #print >>sys.stderr, "expected 1" 70 | #return 0 71 | 72 | print "Parsing", files[0] 73 | results = parse_impl_xml(files[0]) 74 | os.chdir(TopLevel) 75 | return results 76 | 77 | #------------------------------------------------------------------------- 78 | # Parse resource 79 | #------------------------------------------------------------------------- 80 | def parse_syn_xml(file): 81 | tree = ET.parse(file) 82 | root = tree.getroot() 83 | 84 | name = root.find("UserAssignments").find("TopModelName").text 85 | ver = root.find("ReportVersion").find("Version").text 86 | device = root.find("UserAssignments").find("Part").text 87 | summary = root.find("PerformanceEstimates").find("SummaryOfOverallLatency") 88 | # these may not exist if design is not pipelined 89 | avg_lat = find_text(summary,"Average-caseLatency") 90 | worst_lat = find_text(summary,"Worst-caseLatency") 91 | actual_II = find_text(summary,"PipelineInitiationInterval") 92 | depth = find_text(summary,"PipelineDepth") 93 | 94 | timing = root.find("PerformanceEstimates").find("SummaryOfTimingAnalysis") 95 | period = timing.find("EstimatedClockPeriod").text 96 | 97 | res = root.find("AreaEstimates").find("Resources") 98 | lut = res.find("LUT").text 99 | ff = res.find("FF").text 100 | bram = res.find("BRAM_18K").text 101 | 102 | return dict([("Name",name), ("Version",ver), ("Device",device), \ 103 | ("Avg-Lat",avg_lat), ("Worst-Lat",worst_lat), ("Actual-II",actual_II), ("Depth",depth), \ 104 | ("Est-CLK",period), ("Est-LUT",lut), ("Est-FF",ff), ("Est-BRAM",bram)]) 105 | 106 | def parse_syn(): 107 | TopLevel = os.getcwd() 108 | dir = "syn/report/" 109 | if not changedir(dir): 110 | print >>sys.stderr, "**** Cannot find", dir, "in", TopLevel 111 | return 0 112 | 113 | files = glob.glob("*.xml") 114 | if len(files) != 1: 115 | if re.match(".*\/rs", TopLevel): 116 | files = ["rs_decode_csynth.xml"] 117 | else: 118 | files.sort(key=len) 119 | #print >>sys.stderr, "Found", len(files), "xml files in" 120 | #print >>sys.stderr, "\t", TopLevel+"/"+dir 121 | #print >>sys.stderr, "expected 1" 122 | #return 0 123 | 124 | print "Parsing", files[0] 125 | results = parse_syn_xml(files[0]) 126 | os.chdir(TopLevel) 127 | return results 128 | 129 | #------------------------------------------------------------------------- 130 | # Parse sim 131 | #------------------------------------------------------------------------- 132 | def parse_sim(soln_dir): 133 | TopLevel = os.getcwd() 134 | dir = "sim/report/" 135 | if not changedir(soln_dir+"/"+dir): 136 | print >>sys.stderr, "**** Cannot find", dir, "in", TopLevel+"/"+soln_dir 137 | return 0 138 | 139 | files = glob.glob("*cosim.rpt") 140 | if len(files) != 1: 141 | files.sort(key=len) 142 | 143 | print "Parsing", files[0] 144 | f = open(files[0], 'r') 145 | data = [] 146 | 147 | for line in f: 148 | if re.match("\|\W+Verilog\|\W+Pass\|", line): 149 | m = re.search("\|\W+(\d+)\|\W+(\d+)\|\W+(\d+)\|", line) 150 | if m: 151 | data = [m.group(1), m.group(2), m.group(3)] 152 | 153 | f.close() 154 | 155 | if len(data) == 0: 156 | print "Cannot find Verilog sim results" 157 | os.chdir(TopLevel) 158 | return data 159 | 160 | #------------------------------------------------------------------------- 161 | # Parse both the impl report and the syn report 162 | #------------------------------------------------------------------------- 163 | def parse_impl_and_syn(soln_dir): 164 | SolnLevel = os.getcwd() 165 | data = dict([]) 166 | success = False 167 | 168 | if changedir(soln_dir): 169 | # parse the syn xml file 170 | syn = parse_syn() 171 | if syn: 172 | data = dict(data.items()+syn.items()) 173 | success = True 174 | 175 | # parse the impl xml file 176 | impl = parse_impl() 177 | if impl: 178 | data = dict(data.items()+impl.items()) 179 | success = True 180 | 181 | cosim = parse_sim 182 | 183 | else: 184 | print >>sys.stderr, "Cannot find solution", soln_dir 185 | return 0 186 | 187 | os.chdir(SolnLevel) 188 | 189 | if not success: 190 | return 0 191 | return data; 192 | 193 | #------------------------------------------------------------------------- 194 | # Function to process a single HLS project directory 195 | #------------------------------------------------------------------------- 196 | def process_project(prj_dir): 197 | TopLevel = os.getcwd() 198 | 199 | # enter the project directory 200 | if not changedir(prj_dir): 201 | print >>sys.stderr, "Cannot find project", prj_dir 202 | exit(-1) 203 | 204 | # search for solution subdirs 205 | solutions = get_immediate_subdirs('.') 206 | 207 | # for each solution, parse the data 208 | for sol in solutions: 209 | data = parse_impl_and_syn(sol) 210 | sdata = parse_sim(sol) 211 | 212 | if data: 213 | print "\nSolution: ", sol 214 | print_data(data) 215 | 216 | if sdata: 217 | print "\n** Sim. Report **" 218 | print "Min:", sdata[0] 219 | print "Avg:", sdata[1] 220 | print "Max:", sdata[2] 221 | 222 | os.chdir(TopLevel) 223 | 224 | #------------------------------------------------------------------------- 225 | # Print dictionary data 226 | #------------------------------------------------------------------------- 227 | def print_dict(d, key): 228 | if key in d: 229 | print "%-12s: %-30s" % (key, d[key]) 230 | else: 231 | print "%-12s: %-30s" % (key, "-not found-") 232 | 233 | def print_data(d): 234 | print "** Syn. Report **" 235 | print_dict(d, "Name") 236 | print_dict(d, "Version") 237 | print_dict(d, "Device") 238 | print_dict(d, "Avg-Lat") 239 | print_dict(d, "Worst-Lat") 240 | print_dict(d, "Actual-II") 241 | print_dict(d, "Depth") 242 | print_dict(d, "Est-CLK") 243 | print_dict(d, "Est-LUT") 244 | print_dict(d, "Est-FF") 245 | print_dict(d, "Est-BRAM") 246 | print "" 247 | print "** Impl. Report **" 248 | print_dict(d, "Target-CP") 249 | print_dict(d, "Actual-CP") 250 | print_dict(d, "Slice") 251 | print_dict(d, "LUT") 252 | print_dict(d, "FF") 253 | print_dict(d, "SRL") 254 | print_dict(d, "BRAM") 255 | print_dict(d, "DSP") 256 | 257 | #------------------------------------------------------------------------- 258 | # Main function 259 | #------------------------------------------------------------------------- 260 | def main(): 261 | if len(sys.argv) == 1: 262 | print >>sys.stderr, "Usage: parse_vivado.py " 263 | else: 264 | dir = sys.argv[1] 265 | process_project(dir) 266 | print "" 267 | 268 | if __name__ == "__main__": 269 | main() 270 | 271 | #print >>sys.stderr, "Current directory: ", os.getcwd(), "\n" 272 | #print "name,", "version,", "device," 273 | #print "target_cp\t", "actual_cp\t", "latency\t", \ 274 | # "slice\t", "lut\t", "ff\t", "srl\t" \ 275 | # "binvars\t", "intvars\t", "constraints\t", "runtime(s)\t" 276 | 277 | #Dirs = get_immediate_subdirs(".") 278 | 279 | -------------------------------------------------------------------------------- /cpp/accel/sdsoc_build/Makefile: -------------------------------------------------------------------------------- 1 | include ../../Makefile.inc 2 | 3 | CFLAGS:=-DHLS_COMPILE -I../../utils $(CFLAGS) 4 | SLDFLAGS:=-DHLS_COMPILE -L. -lSdsCraftUtils -L./libhf_minizip -lminizip -laes -lz 5 | 6 | SDSFLAGS=-sds-pf zed -dmclkid 1 -sds-hw dense_layer Dense.cpp -clkid 1 -hls-tcl sds.tcl -sds-end 7 | CXX=sds++ $(SDSFLAGS) 8 | 9 | # HDR are pure headers 10 | HDR= 11 | # OBJ must include a .cpp and .h with same name 12 | UTILS=Common.o Timer.o DataIO.o ParamIO.o ZipIO.o 13 | LIBUTILS=libSdsCraftUtils.a 14 | OBJ=Accel.o AccelSchedule.o AccelTest.o Dense.o 15 | EXE=accel_test_bnn.exe 16 | 17 | all: $(EXE) 18 | 19 | # Rule for object files, each object must have a header 20 | $(OBJ): %.o: ../%.cpp ../%.h 21 | $(CXX) -c $< -o $@ $(CFLAGS) 22 | 23 | $(UTILS): %.o: ../../utils/%.cpp ../../utils/%.h 24 | $(CXX) -c $< -o $@ $(CFLAGS) 25 | 26 | %.o: ../%.cpp 27 | $(CXX) -c $< -o $@ $(CFLAGS) 28 | 29 | # Rule for utils library built by SDSoc 30 | $(LIBUTILS): $(UTILS) 31 | $(AR) $@ $^ 32 | 33 | # Rule for executables 34 | $(EXE): %.exe: %.o $(OBJ) $(LIBUTILS) 35 | $(CXX) $^ -o $@ $(CFLAGS) $(SLDFLAGS) 36 | 37 | .PHONY: clean 38 | clean: 39 | rm -f *.o *.exe *.bit 40 | rm -rf _sds sd_card 41 | -------------------------------------------------------------------------------- /cpp/accel/sdsoc_build/libhf_minizip/libaes.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinLiAmoy/rnn-fpga/7f485719b87d1021a16944bba68c1d43c28ea794/cpp/accel/sdsoc_build/libhf_minizip/libaes.a -------------------------------------------------------------------------------- /cpp/accel/sdsoc_build/libhf_minizip/libminizip.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinLiAmoy/rnn-fpga/7f485719b87d1021a16944bba68c1d43c28ea794/cpp/accel/sdsoc_build/libhf_minizip/libminizip.a -------------------------------------------------------------------------------- /cpp/accel/sdsoc_build/libhf_minizip/libz.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinLiAmoy/rnn-fpga/7f485719b87d1021a16944bba68c1d43c28ea794/cpp/accel/sdsoc_build/libhf_minizip/libz.a -------------------------------------------------------------------------------- /cpp/accel/sdsoc_build/sds.tcl: -------------------------------------------------------------------------------- 1 | set rootdir $::env(CRAFT_BNN_ROOT) 2 | source $rootdir/cpp/accel/opt.tcl 3 | 4 | set_directive_interface -mode ap_fifo "dense_layer" wt 5 | set_directive_interface -mode ap_fifo "dense_layer" b 6 | set_directive_interface -mode ap_fifo "dense_layer" data_i 7 | set_directive_interface -mode ap_fifo "dense_layer" data_o 8 | 9 | #set_directive_interface -mode bram "top" wt_i 10 | #set_directive_interface -mode bram "top" kh_i 11 | #set_directive_resource -core RAM_1P "top" wt_i 12 | #set_directive_resource -core RAM_1P "top" kh_i 13 | -------------------------------------------------------------------------------- /cpp/minizip/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #*************************************************************************** 2 | # Copyright: Matthias Schmieder, 3 | # E-Mail: schmieder.matthias@gmail.com 4 | # Year: 2016 5 | #*************************************************************************** 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | 9 | # Set a consistent MACOSX_RPATH default across all CMake versions. 10 | # When CMake 2.8.12 is required, change this default to 1. 11 | # When CMake 3.0.0 is required, remove this block (see CMP0042). 12 | if(NOT DEFINED CMAKE_MACOSX_RPATH) 13 | set(CMAKE_MACOSX_RPATH 0) 14 | endif() 15 | 16 | project("minizip") 17 | 18 | # set cmake debug postfix to d 19 | set(CMAKE_DEBUG_POSTFIX "d") 20 | 21 | # Ensure correct version of zlib is referenced 22 | set(ZLIB_ROOT ${DEF_ZLIB_ROOT} CACHE PATH "Parent directory of zlib installation") 23 | find_package(ZLIB REQUIRED) 24 | if(ZLIB_FOUND) 25 | include_directories(${ZLIB_INCLUDE_DIRS}) 26 | endif() 27 | 28 | set(MINIZIP_SRC "ioapi.c" 29 | "ioapi_buf.c" 30 | "ioapi_mem.c" 31 | "unzip.c" 32 | "zip.c") 33 | 34 | set(MINIZIP_PUBLIC_HEADERS "crypt.h" 35 | "ioapi.h" 36 | "ioapi_buf.h" 37 | "ioapi_mem.h" 38 | "unzip.h" 39 | "zip.h") 40 | 41 | if(WIN32) 42 | list(APPEND MINIZIP_SRC "iowin32.c") 43 | list(APPEND MINIZIP_PUBLIC_HEADERS "iowin32.h") 44 | endif() 45 | 46 | # create minizip library 47 | add_library(minizip ${MINIZIP_SRC} ${MINIZIP_PUBLIC_HEADERS}) 48 | 49 | option(USE_AES "enables building of aes library" ON) 50 | if(USE_AES) 51 | set(AES_SRC 52 | aes/aescrypt.c 53 | aes/aeskey.c 54 | aes/aestab.c 55 | aes/entropy.c 56 | aes/fileenc.c 57 | aes/hmac.c 58 | aes/prng.c 59 | aes/pwd2key.c 60 | aes/sha1.c) 61 | 62 | set(AES_PUBLIC_HEADERS 63 | aes/aes.h 64 | aes/aes_via_ace.h 65 | aes/aesopt.h 66 | aes/aestab.h 67 | aes/brg_endian.h 68 | aes/brg_types.h 69 | aes/entropy.h 70 | aes/fileenc.h 71 | aes/hmac.h 72 | aes/prng.h 73 | aes/pwd2key.h 74 | aes/sha1.h) 75 | 76 | add_library(aes ${AES_SRC} ${AES_PUBLIC_HEADERS}) 77 | 78 | set_target_properties(aes minizip 79 | PROPERTIES 80 | COMPILE_DEFINITIONS "O -DHAVE_AES") 81 | 82 | target_link_libraries(minizip aes) 83 | 84 | install(TARGETS aes EXPORT zlib-exports 85 | INCLUDES DESTINATION "include" 86 | RUNTIME DESTINATION "bin" 87 | LIBRARY DESTINATION "lib" 88 | ARCHIVE DESTINATION "lib") 89 | 90 | install(FILES ${AES_PUBLIC_HEADERS} 91 | DESTINATION "include/minizip/aes") 92 | endif() 93 | 94 | install(TARGETS minizip EXPORT zlib-exports 95 | INCLUDES DESTINATION "include" 96 | RUNTIME DESTINATION "bin" 97 | LIBRARY DESTINATION "lib" 98 | ARCHIVE DESTINATION "lib") 99 | 100 | install(EXPORT zlib-exports 101 | DESTINATION "cmake" 102 | NAMESPACE "MINIZIP::") 103 | 104 | install(FILES ${MINIZIP_PUBLIC_HEADERS} 105 | DESTINATION "include/minizip") 106 | 107 | option (BUILD_TEST "enabled building of executables minizip and miniunz. Requires ZLIB!" OFF) 108 | if(BUILD_TEST) 109 | add_executable(miniunz_exec miniunz.c) 110 | target_link_libraries(miniunz_exec minizip ZLIB::ZLIB) 111 | 112 | add_executable(minizip_exec minizip.c) 113 | target_link_libraries(minizip_exec minizip ZLIB::ZLIB) 114 | 115 | install(TARGETS miniunz_exec minizip_exec 116 | RUNTIME DESTINATION "bin") 117 | endif() 118 | 119 | -------------------------------------------------------------------------------- /cpp/minizip/ChangeLog: -------------------------------------------------------------------------------- 1 | More changes since 1.1 2 | - Added support for AE-2 zip files 3 | - Fixed error in AE-1 not testing CRC32 4 | 5 | Credits 6 | 7 | Steven Christy 8 | 9 | Changes since 1.1 10 | - Added PKZIP spanning support 11 | - Added AES encryption support 12 | - Added I/O buffering 13 | - Clean up & changed unzLocateFile to support custom comparison function 14 | - Clean up, removed zipRemoveExtraInfoBlock 15 | 16 | Credits 17 | 18 | Nathan Moinvaziri 19 | 20 | Change in 1.1 21 | - Added ZIP64 support for unzip ( by Even Rouault ) 22 | - Added ZIP64 support for zip ( by Mathias Svensson ) 23 | - Reverted some changed that Even Rouault did. 24 | - Bunch of patches received from Gulles Vollant that he received for MiniZip from various users. 25 | - Added unzip patch for BZIP Compression method (patch create by Daniel Borca) 26 | - Added BZIP Compress method for zip 27 | - Did some refactoring and code cleanup 28 | 29 | Credits 30 | 31 | Gilles Vollant - Original MiniZip author 32 | Even Rouault - ZIP64 unzip Support 33 | 34 | 2007-2008 35 | - Addition of cpl_unzGetCurrentFileZStreamPos 36 | - Decoration of symbol names unz* -> cpl_unz* 37 | - Remove old C style function prototypes 38 | - Add unzip support for ZIP64 39 | 40 | Daniel Borca - BZip Compression method support in unzip 41 | Mathias Svensson - ZIP64 zip support ( http://result42.com ) 42 | 43 | Oct-2009 unzip.c 44 | - Removed cpl_* from symbol names 45 | - Fixed problem if uncompressed size was > 4G and compressed size was <4G 46 | should only read the compressed/uncompressed size from the Zip64 format if 47 | the size from normal header was 0xffffffff 48 | - Applied some bug fixes from patches received from Gilles Vollant 49 | - Applied support to unzip files with compression method BZIP2 (bzip2 lib is required) 50 | Patch created by Daniel Borca 51 | 52 | Oct-2009 zip.c 53 | - Remove old C style function prototypes 54 | - Added Zip64 Support when creating new file archives 55 | - Did some code cleanup and refactoring to get better overview of some functions. 56 | - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data 57 | It is used when recreting zip archive with RAW when deleting items from a zip. 58 | ZIP64 data is automaticly added to items that needs it, and existing ZIP64 59 | data need to be removed. 60 | - Added support for BZIP2 as compression mode (bzip2 lib is required) 61 | 62 | Oct-2009 ioapi.x 63 | - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. 64 | - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. 65 | More if/def section may be needed to support other platforms 66 | - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. 67 | (but you should use iowin32.c for windows instead) 68 | 69 | Change in 1.01e (12 feb 05) 70 | - Fix in zipOpen2 for globalcomment (Rolf Kalbermatter) 71 | - Fix possible memory leak in unzip.c (Zoran Stevanovic) 72 | 73 | Change in 1.01b (20 may 04) 74 | - Integrate patch from Debian package (Mark Brown) 75 | - Add tools mztools from Xavier Roche 76 | 77 | Change in 1.01 (8 may 04) 78 | - Fix buffer overrun risk in unzip.c (Xavier Roche) 79 | - Fix a minor buffer insecurity in minizip.c (Mike Whittaker) 80 | 81 | Change in 1.00: (10 sept 03) 82 | - Rename to 1.00 83 | - Cosmetic code change 84 | 85 | Change in 0.22: (19 May 03) 86 | - Crypting support (unless you define NOCRYPT) 87 | - Append file in existing zipfile 88 | 89 | Change in 0.21: (10 Mar 03) 90 | - Bug fixes 91 | 92 | Change in 0.17: (27 Jan 02) 93 | - Bug fixes 94 | 95 | Change in 0.16: (19 Jan 02) 96 | - Support of ioapi for virtualize zip file access 97 | 98 | Change in 0.15: (19 Mar 98) 99 | - Fix memory leak in minizip.c 100 | 101 | Change in 0.14: (10 Mar 98) 102 | - Fix bugs in minizip.c sample for zipping big file 103 | - Fix problem in month in date handling 104 | - Fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for comment handling 105 | 106 | Change in 0.13: (6 Mar 98) 107 | - Fix bugs in zip.c 108 | - Add real minizip sample 109 | 110 | Change in 0.12: (4 Mar 98) 111 | - Add zip.c and zip.h for creates .zip file 112 | - Fix change_file_date in miniunz.c for Unix (Jean-loup Gailly) 113 | - Fix miniunz.c for file without specific record for directory 114 | 115 | Change in 0.11: (3 Mar 98) 116 | - Fix bug in unzGetCurrentFileInfo for get extra field and comment 117 | - Enhance miniunz sample, remove the bad unztst.c sample 118 | 119 | Change in 0.10: (2 Mar 98) 120 | - Fix bug in unzReadCurrentFile 121 | - Rename unzip* to unz* function and structure 122 | - Remove Windows-like hungary notation variable name 123 | - Modify some structure in unzip.h 124 | - Add somes comment in source 125 | - Remove unzipGetcCurrentFile function 126 | - Replace ZUNZEXPORT by ZEXPORT 127 | - Add unzGetLocalExtrafield for get the local extrafield info 128 | - Add a new sample, miniunz.c 129 | 130 | Change in 0.4: (25 Feb 98) 131 | - Suppress the type unzipFileInZip. 132 | Only on file in the zipfile can be open at the same time 133 | - Fix somes typo in code 134 | - Added tm_unz structure in unzip_file_info (date/time in readable format) 135 | 136 | Change unknown? 137 | - Added unzGetOffset (RX '2004) 138 | - Added unzGetFilePos & unzGoToFilePos (Ryan Haksi) 139 | - Added unzGetCurrentFileZStreamPos64 (GDAL) 140 | 141 | -------------------------------------------------------------------------------- /cpp/minizip/LICENSE: -------------------------------------------------------------------------------- 1 | Condition of use and distribution are the same as zlib: 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgement in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /cpp/minizip/Makefile: -------------------------------------------------------------------------------- 1 | CC=cc 2 | CFLAGS=-O -I../.. -DHAVE_AES 3 | ARFLAGS=rv 4 | 5 | UNZ_OBJS = miniunz.o unzip.o ioapi.o libaes.a 6 | ZIP_OBJS = minizip.o zip.o ioapi.o libaes.a 7 | TEST_FILES = test.zip readme.old readme.txt 8 | 9 | .c.o: 10 | $(CC) -c $(CFLAGS) $*.c 11 | 12 | all: miniunz minizip libminizip.a libaes.a 13 | 14 | libaes.a: 15 | cd aes; $(MAKE) $(MFLAGS) 16 | 17 | libminizip.a: miniunz.o unzip.o minizip.o zip.o ioapi.o 18 | $(ECHO) $(AR) $(ARFLAGS) ./libminizip.a $? 19 | $(AR) $(ARFLAGS) ./libminizip.a $? 20 | ranlib ./libminizip.a 21 | 22 | miniunz: $(UNZ_OBJS) libaes.a 23 | $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS) -lz 24 | 25 | minizip: $(ZIP_OBJS) libaes.a 26 | $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) -lz 27 | 28 | .PHONY: test clean 29 | 30 | test: miniunz minizip 31 | @rm -f $(TEST_FILES) 32 | @cp README.md readme.txt 33 | @touch -t 200712301223.44 readme.txt 34 | ./minizip test.zip readme.txt 35 | ./miniunz -l test.zip 36 | mv readme.txt readme.old 37 | ./miniunz test.zip 38 | @diff -q README.md readme.txt || echo "Test failed: files differ" 39 | @[[ "$$(stat -c %Y readme.txt)" = "$$(stat -c %Y readme.old)" ]] || echo "Test failed: timestamp not preserved" 40 | @rm -f $(TEST_FILES) 41 | 42 | clean: 43 | /bin/rm -f *.o *~ minizip miniunz $(TEST_FILES) 44 | $(MAKE) -C aes clean 45 | -------------------------------------------------------------------------------- /cpp/minizip/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES = libminizip.la 2 | 3 | if COND_DEMOS 4 | bin_PROGRAMS = miniunzip minizip 5 | endif 6 | 7 | zlib_top_srcdir = $(top_srcdir)/../.. 8 | zlib_top_builddir = $(top_builddir)/../.. 9 | 10 | AM_CPPFLAGS = -I$(zlib_top_srcdir) 11 | AM_LDFLAGS = -L$(zlib_top_builddir) 12 | 13 | if WIN32 14 | iowin32_src = iowin32.c 15 | iowin32_h = iowin32.h 16 | endif 17 | 18 | libminizip_la_SOURCES = \ 19 | ioapi.c \ 20 | unzip.c \ 21 | zip.c \ 22 | ${iowin32_src} 23 | 24 | libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz 25 | 26 | minizip_includedir = $(includedir)/minizip 27 | minizip_include_HEADERS = \ 28 | crypt.h \ 29 | ioapi.h \ 30 | unzip.h \ 31 | zip.h \ 32 | ${iowin32_h} 33 | 34 | pkgconfigdir = $(libdir)/pkgconfig 35 | pkgconfig_DATA = minizip.pc 36 | 37 | EXTRA_PROGRAMS = miniunzip minizip 38 | 39 | miniunzip_SOURCES = miniunz.c 40 | miniunzip_LDADD = libminizip.la 41 | 42 | minizip_SOURCES = minizip.c 43 | minizip_LDADD = libminizip.la -lz 44 | -------------------------------------------------------------------------------- /cpp/minizip/README.md: -------------------------------------------------------------------------------- 1 | Minizip zlib contribution that includes: 2 | 3 | - AES encryption 4 | - I/O buffering 5 | - PKWARE disk spanning 6 | - Visual Studio 2008 project files 7 | 8 | It also has the latest bug fixes that having been found all over the internet including the minizip forum and zlib developer's mailing list. 9 | 10 | *AES Encryption* 11 | 12 | + Requires #define HAVE_AES 13 | + Requires AES library files 14 | 15 | When zipping with a password it will always use AES 256-bit encryption. 16 | When unzipping it will use AES decryption only if necessary. 17 | 18 | *I/O Buffering* 19 | 20 | Improves I/O performance by buffering read and write operations. 21 | ``` 22 | zlib_filefunc64_def filefunc64 = {0}; 23 | ourbuffer_t buffered = {0}; 24 | 25 | fill_win32_filefunc64(&buffered->filefunc64); 26 | fill_buffer_filefunc64(&filefunc64, buffered); 27 | 28 | unzOpen2_64(filename, &filefunc64) 29 | ``` 30 | 31 | *PKWARE disk spanning* 32 | 33 | To create an archive with multiple disks use zipOpen3_64 supplying a disk_size value in bytes. 34 | 35 | ``` 36 | extern zipFile ZEXPORT zipOpen3_64 OF((const void *pathname, int append, 37 | ZPOS64_T disk_size, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)); 38 | ``` 39 | The central directory is the only data stored in the .zip and doesn't follow disk_size restrictions. 40 | 41 | When unzipping it will automatically determine when in needs to span disks. 42 | 43 | *I/O Memory* 44 | 45 | To unzip from a zip file in memory use fill_memory_filefunc and supply a proper ourmemory_t structure. 46 | ``` 47 | zlib_filefunc_def filefunc32 = {0}; 48 | ourmemory_t unzmem = {0}; 49 | 50 | unzmem.size = bufsize; 51 | unzmem.base = (char *)malloc(unzmem.size); 52 | memcpy(unzmem.base, buffer, unzmem.size); 53 | 54 | fill_memory_filefunc(&filefunc32, &unzmem); 55 | 56 | unzOpen2("__notused__", &filefunc32); 57 | ``` 58 | 59 | To create a zip file in memory use fill_memory_filefunc and supply a proper ourmemory_t structure. It is important 60 | not to forget to free zipmem->base when finished. If grow is set, zipmem->base will expand to fit the size of the zip. 61 | If grow is not set be sure to fill out zipmem.base and zipmem.size. 62 | 63 | ``` 64 | zlib_filefunc_def filefunc32 = {0}; 65 | ourmemory_t zipmem = {0}; 66 | 67 | zipmem.grow = 1; 68 | 69 | fill_memory_filefunc(&filefunc32, &zipmem); 70 | 71 | zipOpen3("__notused__", APPEND_STATUS_CREATE, 0, 0, &filefunc32); 72 | ``` 73 | 74 | *BZIP2* 75 | 76 | + Requires #define HAVE_BZIP2 77 | + Requires BZIP2 library 78 | 79 | *Windows RT* 80 | 81 | + Requires #define IOWIN32_USING_WINRT_API 82 | -------------------------------------------------------------------------------- /cpp/minizip/aes/Makefile: -------------------------------------------------------------------------------- 1 | CC=cc 2 | CFLAGS=-O -DHAVE_AES 3 | OBJS=aescrypt.o aeskey.o aestab.o entropy.o fileenc.o hmac.o prng.o pwd2key.o sha1.o 4 | ARFLAGS=rv 5 | RANLIB=ranlib 6 | 7 | .c.o: 8 | $(CC) -c $(CFLAGS) $*.c 9 | 10 | libaes.a: $(OBJS) 11 | $(ECHO) $(AR) $(ARFLAGS) ../libaes.a $? 12 | $(AR) $(ARFLAGS) ../libaes.a $? 13 | $(RANLIB) ../libaes.a 14 | 15 | all: libaes.a 16 | 17 | .PHONY: clean 18 | 19 | clean: 20 | rm -f *.o *.a 21 | -------------------------------------------------------------------------------- /cpp/minizip/aes/aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | The redistribution and use of this software (with or without changes) 6 | is allowed without the payment of fees or royalties provided that: 7 | 8 | source code distributions include the above copyright notice, this 9 | list of conditions and the following disclaimer; 10 | 11 | binary distributions include the above copyright notice, this list 12 | of conditions and the following disclaimer in their documentation. 13 | 14 | This software is provided 'as is' with no explicit or implied warranties 15 | in respect of its operation, including, but not limited to, correctness 16 | and fitness for purpose. 17 | --------------------------------------------------------------------------- 18 | Issue Date: 20/12/2007 19 | 20 | This file contains the definitions required to use AES in C. See aesopt.h 21 | for optimisation details. 22 | */ 23 | 24 | #ifndef _AES_H 25 | #define _AES_H 26 | 27 | #include 28 | 29 | /* This include is used to find 8 & 32 bit unsigned integer types */ 30 | #include "brg_types.h" 31 | 32 | #if defined(__cplusplus) 33 | extern "C" 34 | { 35 | #endif 36 | 37 | #define AES_128 /* if a fast 128 bit key scheduler is needed */ 38 | #define AES_192 /* if a fast 192 bit key scheduler is needed */ 39 | #define AES_256 /* if a fast 256 bit key scheduler is needed */ 40 | #define AES_VAR /* if variable key size scheduler is needed */ 41 | #define AES_MODES /* if support is needed for modes */ 42 | 43 | /* The following must also be set in assembler files if being used */ 44 | 45 | #define AES_ENCRYPT /* if support for encryption is needed */ 46 | #define AES_DECRYPT /* if support for decryption is needed */ 47 | #define AES_REV_DKS /* define to reverse decryption key schedule */ 48 | 49 | #define AES_BLOCK_SIZE 16 /* the AES block size in bytes */ 50 | #define N_COLS 4 /* the number of columns in the state */ 51 | 52 | /* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ 53 | /* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */ 54 | /* or 44, 52 or 60 32-bit words. */ 55 | 56 | #if defined( AES_VAR ) || defined( AES_256 ) 57 | #define KS_LENGTH 60 58 | #elif defined( AES_192 ) 59 | #define KS_LENGTH 52 60 | #else 61 | #define KS_LENGTH 44 62 | #endif 63 | 64 | #define AES_RETURN INT_RETURN 65 | 66 | /* the character array 'inf' in the following structures is used */ 67 | /* to hold AES context information. This AES code uses cx->inf.b[0] */ 68 | /* to hold the number of rounds multiplied by 16. The other three */ 69 | /* elements can be used by code that implements additional modes */ 70 | 71 | typedef union 72 | { uint_32t l; 73 | uint_8t b[4]; 74 | } aes_inf; 75 | 76 | typedef struct 77 | { uint_32t ks[KS_LENGTH]; 78 | aes_inf inf; 79 | } aes_encrypt_ctx; 80 | 81 | typedef struct 82 | { uint_32t ks[KS_LENGTH]; 83 | aes_inf inf; 84 | } aes_decrypt_ctx; 85 | 86 | /* This routine must be called before first use if non-static */ 87 | /* tables are being used */ 88 | 89 | AES_RETURN aes_init(void); 90 | 91 | /* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */ 92 | /* those in the range 128 <= key_len <= 256 are given in bits */ 93 | 94 | #if defined( AES_ENCRYPT ) 95 | 96 | #if defined( AES_128 ) || defined( AES_VAR) 97 | AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); 98 | #endif 99 | 100 | #if defined( AES_192 ) || defined( AES_VAR) 101 | AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); 102 | #endif 103 | 104 | #if defined( AES_256 ) || defined( AES_VAR) 105 | AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); 106 | #endif 107 | 108 | #if defined( AES_VAR ) 109 | AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); 110 | #endif 111 | 112 | AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); 113 | 114 | #endif 115 | 116 | #if defined( AES_DECRYPT ) 117 | 118 | #if defined( AES_128 ) || defined( AES_VAR) 119 | AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); 120 | #endif 121 | 122 | #if defined( AES_192 ) || defined( AES_VAR) 123 | AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); 124 | #endif 125 | 126 | #if defined( AES_256 ) || defined( AES_VAR) 127 | AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); 128 | #endif 129 | 130 | #if defined( AES_VAR ) 131 | AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); 132 | #endif 133 | 134 | AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); 135 | 136 | #endif 137 | 138 | #if defined( AES_MODES ) 139 | 140 | /* Multiple calls to the following subroutines for multiple block */ 141 | /* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */ 142 | /* long messages incremantally provided that the context AND the iv */ 143 | /* are preserved between all such calls. For the ECB and CBC modes */ 144 | /* each individual call within a series of incremental calls must */ 145 | /* process only full blocks (i.e. len must be a multiple of 16) but */ 146 | /* the CFB, OFB and CTR mode calls can handle multiple incremental */ 147 | /* calls of any length. Each mode is reset when a new AES key is */ 148 | /* set but ECB and CBC operations can be reset without setting a */ 149 | /* new key by setting a new IV value. To reset CFB, OFB and CTR */ 150 | /* without setting the key, aes_mode_reset() must be called and the */ 151 | /* IV must be set. NOTE: All these calls update the IV on exit so */ 152 | /* this has to be reset if a new operation with the same IV as the */ 153 | /* previous one is required (or decryption follows encryption with */ 154 | /* the same IV array). */ 155 | 156 | AES_RETURN aes_test_alignment_detection(unsigned int n); 157 | 158 | AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, 159 | int len, const aes_encrypt_ctx cx[1]); 160 | 161 | AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, 162 | int len, const aes_decrypt_ctx cx[1]); 163 | 164 | AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, 165 | int len, unsigned char *iv, const aes_encrypt_ctx cx[1]); 166 | 167 | AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, 168 | int len, unsigned char *iv, const aes_decrypt_ctx cx[1]); 169 | 170 | AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]); 171 | 172 | AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, 173 | int len, unsigned char *iv, aes_encrypt_ctx cx[1]); 174 | 175 | AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, 176 | int len, unsigned char *iv, aes_encrypt_ctx cx[1]); 177 | 178 | #define aes_ofb_encrypt aes_ofb_crypt 179 | #define aes_ofb_decrypt aes_ofb_crypt 180 | 181 | AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, 182 | int len, unsigned char *iv, aes_encrypt_ctx cx[1]); 183 | 184 | typedef void cbuf_inc(unsigned char *cbuf); 185 | 186 | #define aes_ctr_encrypt aes_ctr_crypt 187 | #define aes_ctr_decrypt aes_ctr_crypt 188 | 189 | AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, 190 | int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]); 191 | 192 | #endif 193 | 194 | #if defined(__cplusplus) 195 | } 196 | #endif 197 | 198 | #endif 199 | -------------------------------------------------------------------------------- /cpp/minizip/aes/aestab.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | The redistribution and use of this software (with or without changes) 6 | is allowed without the payment of fees or royalties provided that: 7 | 8 | source code distributions include the above copyright notice, this 9 | list of conditions and the following disclaimer; 10 | 11 | binary distributions include the above copyright notice, this list 12 | of conditions and the following disclaimer in their documentation. 13 | 14 | This software is provided 'as is' with no explicit or implied warranties 15 | in respect of its operation, including, but not limited to, correctness 16 | and fitness for purpose. 17 | --------------------------------------------------------------------------- 18 | Issue Date: 20/12/2007 19 | 20 | This file contains the code for declaring the tables needed to implement 21 | AES. The file aesopt.h is assumed to be included before this header file. 22 | If there are no global variables, the definitions here can be used to put 23 | the AES tables in a structure so that a pointer can then be added to the 24 | AES context to pass them to the AES routines that need them. If this 25 | facility is used, the calling program has to ensure that this pointer is 26 | managed appropriately. In particular, the value of the t_dec(in,it) item 27 | in the table structure must be set to zero in order to ensure that the 28 | tables are initialised. In practice the three code sequences in aeskey.c 29 | that control the calls to aes_init() and the aes_init() routine itself will 30 | have to be changed for a specific implementation. If global variables are 31 | available it will generally be preferable to use them with the precomputed 32 | FIXED_TABLES option that uses static global tables. 33 | 34 | The following defines can be used to control the way the tables 35 | are defined, initialised and used in embedded environments that 36 | require special features for these purposes 37 | 38 | the 't_dec' construction is used to declare fixed table arrays 39 | the 't_set' construction is used to set fixed table values 40 | the 't_use' construction is used to access fixed table values 41 | 42 | 256 byte tables: 43 | 44 | t_xxx(s,box) => forward S box 45 | t_xxx(i,box) => inverse S box 46 | 47 | 256 32-bit word OR 4 x 256 32-bit word tables: 48 | 49 | t_xxx(f,n) => forward normal round 50 | t_xxx(f,l) => forward last round 51 | t_xxx(i,n) => inverse normal round 52 | t_xxx(i,l) => inverse last round 53 | t_xxx(l,s) => key schedule table 54 | t_xxx(i,m) => key schedule table 55 | 56 | Other variables and tables: 57 | 58 | t_xxx(r,c) => the rcon table 59 | */ 60 | 61 | #if !defined( _AESTAB_H ) 62 | #define _AESTAB_H 63 | 64 | #if defined(__cplusplus) 65 | extern "C" { 66 | #endif 67 | 68 | #define t_dec(m,n) t_##m##n 69 | #define t_set(m,n) t_##m##n 70 | #define t_use(m,n) t_##m##n 71 | 72 | #if defined(FIXED_TABLES) 73 | # if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ )) 74 | /* make tables far data to avoid using too much DGROUP space (PG) */ 75 | # define CONST const far 76 | # else 77 | # define CONST const 78 | # endif 79 | #else 80 | # define CONST 81 | #endif 82 | 83 | #if defined(DO_TABLES) 84 | # define EXTERN 85 | #else 86 | # define EXTERN extern 87 | #endif 88 | 89 | #if defined(_MSC_VER) && defined(TABLE_ALIGN) 90 | #define ALIGN __declspec(align(TABLE_ALIGN)) 91 | #else 92 | #define ALIGN 93 | #endif 94 | 95 | #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 ) 96 | # define XP_DIR __cdecl 97 | #else 98 | # define XP_DIR 99 | #endif 100 | 101 | #if defined(DO_TABLES) && defined(FIXED_TABLES) 102 | #define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) 103 | #define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) } 104 | EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0); 105 | #else 106 | #define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] 107 | #define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] 108 | EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH]; 109 | #endif 110 | 111 | #if defined( SBX_SET ) 112 | d_1(uint_8t, t_dec(s,box), sb_data, h0); 113 | #endif 114 | #if defined( ISB_SET ) 115 | d_1(uint_8t, t_dec(i,box), isb_data, h0); 116 | #endif 117 | 118 | #if defined( FT1_SET ) 119 | d_1(uint_32t, t_dec(f,n), sb_data, u0); 120 | #endif 121 | #if defined( FT4_SET ) 122 | d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3); 123 | #endif 124 | 125 | #if defined( FL1_SET ) 126 | d_1(uint_32t, t_dec(f,l), sb_data, w0); 127 | #endif 128 | #if defined( FL4_SET ) 129 | d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3); 130 | #endif 131 | 132 | #if defined( IT1_SET ) 133 | d_1(uint_32t, t_dec(i,n), isb_data, v0); 134 | #endif 135 | #if defined( IT4_SET ) 136 | d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3); 137 | #endif 138 | 139 | #if defined( IL1_SET ) 140 | d_1(uint_32t, t_dec(i,l), isb_data, w0); 141 | #endif 142 | #if defined( IL4_SET ) 143 | d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3); 144 | #endif 145 | 146 | #if defined( LS1_SET ) 147 | #if defined( FL1_SET ) 148 | #undef LS1_SET 149 | #else 150 | d_1(uint_32t, t_dec(l,s), sb_data, w0); 151 | #endif 152 | #endif 153 | 154 | #if defined( LS4_SET ) 155 | #if defined( FL4_SET ) 156 | #undef LS4_SET 157 | #else 158 | d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3); 159 | #endif 160 | #endif 161 | 162 | #if defined( IM1_SET ) 163 | d_1(uint_32t, t_dec(i,m), mm_data, v0); 164 | #endif 165 | #if defined( IM4_SET ) 166 | d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3); 167 | #endif 168 | 169 | #if defined(__cplusplus) 170 | } 171 | #endif 172 | 173 | #endif 174 | -------------------------------------------------------------------------------- /cpp/minizip/aes/brg_endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | The redistribution and use of this software (with or without changes) 6 | is allowed without the payment of fees or royalties provided that: 7 | 8 | source code distributions include the above copyright notice, this 9 | list of conditions and the following disclaimer; 10 | 11 | binary distributions include the above copyright notice, this list 12 | of conditions and the following disclaimer in their documentation. 13 | 14 | This software is provided 'as is' with no explicit or implied warranties 15 | in respect of its operation, including, but not limited to, correctness 16 | and fitness for purpose. 17 | --------------------------------------------------------------------------- 18 | Issue Date: 20/12/2007 19 | */ 20 | 21 | #ifndef _BRG_ENDIAN_H 22 | #define _BRG_ENDIAN_H 23 | 24 | #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ 25 | #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ 26 | 27 | /* Include files where endian defines and byteswap functions may reside */ 28 | #if defined( __sun ) 29 | # include 30 | #elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) 31 | # include 32 | #elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ 33 | defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) 34 | # include 35 | #elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) 36 | # if !defined( __MINGW32__ ) && !defined( _AIX ) 37 | # include 38 | # if !defined( __BEOS__ ) 39 | # include 40 | # endif 41 | # endif 42 | #endif 43 | 44 | /* Now attempt to set the define for platform byte order using any */ 45 | /* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ 46 | /* seem to encompass most endian symbol definitions */ 47 | 48 | #if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) 49 | # if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN 50 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 51 | # elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN 52 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 53 | # endif 54 | #elif defined( BIG_ENDIAN ) 55 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 56 | #elif defined( LITTLE_ENDIAN ) 57 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 58 | #endif 59 | 60 | #if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) 61 | # if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN 62 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 63 | # elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN 64 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 65 | # endif 66 | #elif defined( _BIG_ENDIAN ) 67 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 68 | #elif defined( _LITTLE_ENDIAN ) 69 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 70 | #endif 71 | 72 | #if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) 73 | # if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN 74 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 75 | # elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN 76 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 77 | # endif 78 | #elif defined( __BIG_ENDIAN ) 79 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 80 | #elif defined( __LITTLE_ENDIAN ) 81 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 82 | #endif 83 | 84 | #if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) 85 | # if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ 86 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 87 | # elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ 88 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 89 | # endif 90 | #elif defined( __BIG_ENDIAN__ ) 91 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 92 | #elif defined( __LITTLE_ENDIAN__ ) 93 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 94 | #endif 95 | 96 | /* if the platform byte order could not be determined, then try to */ 97 | /* set this define using common machine defines */ 98 | #if !defined(PLATFORM_BYTE_ORDER) 99 | 100 | #if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ 101 | defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ 102 | defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ 103 | defined( vax ) || defined( vms ) || defined( VMS ) || \ 104 | defined( __VMS ) || defined( _M_X64 ) 105 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 106 | 107 | #elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ 108 | defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ 109 | defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ 110 | defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ 111 | defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ 112 | defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ 113 | defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) 114 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 115 | 116 | #elif 0 /* **** EDIT HERE IF NECESSARY **** */ 117 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 118 | #elif 0 /* **** EDIT HERE IF NECESSARY **** */ 119 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 120 | #else 121 | # error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order 122 | #endif 123 | 124 | #endif 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /cpp/minizip/aes/brg_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | The redistribution and use of this software (with or without changes) 6 | is allowed without the payment of fees or royalties provided that: 7 | 8 | source code distributions include the above copyright notice, this 9 | list of conditions and the following disclaimer; 10 | 11 | binary distributions include the above copyright notice, this list 12 | of conditions and the following disclaimer in their documentation. 13 | 14 | This software is provided 'as is' with no explicit or implied warranties 15 | in respect of its operation, including, but not limited to, correctness 16 | and fitness for purpose. 17 | --------------------------------------------------------------------------- 18 | Issue Date: 20/12/2007 19 | 20 | The unsigned integer types defined here are of the form uint_t where 21 | is the length of the type; for example, the unsigned 32-bit type is 22 | 'uint_32t'. These are NOT the same as the 'C99 integer types' that are 23 | defined in the inttypes.h and stdint.h headers since attempts to use these 24 | types have shown that support for them is still highly variable. However, 25 | since the latter are of the form uint_t, a regular expression search 26 | and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t') 27 | can be used to convert the types used here to the C99 standard types. 28 | */ 29 | 30 | #ifndef _BRG_TYPES_H 31 | #define _BRG_TYPES_H 32 | 33 | #if defined(__cplusplus) 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) 40 | # include 41 | # define ptrint_t intptr_t 42 | #elif defined( __ECOS__ ) 43 | # define intptr_t unsigned int 44 | # define ptrint_t intptr_t 45 | #elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) 46 | # include 47 | # define ptrint_t intptr_t 48 | #else 49 | # define ptrint_t int 50 | #endif 51 | 52 | #ifndef BRG_UI8 53 | # define BRG_UI8 54 | # if UCHAR_MAX == 255u 55 | typedef unsigned char uint_8t; 56 | # else 57 | # error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h 58 | # endif 59 | #endif 60 | 61 | #ifndef BRG_UI16 62 | # define BRG_UI16 63 | # if USHRT_MAX == 65535u 64 | typedef unsigned short uint_16t; 65 | # else 66 | # error Please define uint_16t as a 16-bit unsigned short type in brg_types.h 67 | # endif 68 | #endif 69 | 70 | #ifndef BRG_UI32 71 | # define BRG_UI32 72 | # if UINT_MAX == 4294967295u 73 | # define li_32(h) 0x##h##u 74 | typedef unsigned int uint_32t; 75 | # elif ULONG_MAX == 4294967295u 76 | # define li_32(h) 0x##h##ul 77 | typedef unsigned long uint_32t; 78 | # elif defined( _CRAY ) 79 | # error This code needs 32-bit data types, which Cray machines do not provide 80 | # else 81 | # error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h 82 | # endif 83 | #endif 84 | 85 | #ifndef BRG_UI64 86 | # if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) 87 | # define BRG_UI64 88 | # define li_64(h) 0x##h##ui64 89 | typedef unsigned __int64 uint_64t; 90 | # elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */ 91 | # define BRG_UI64 92 | # define li_64(h) 0x##h##ui64 93 | typedef unsigned __int64 uint_64t; 94 | # elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful 95 | # define BRG_UI64 96 | # define li_64(h) 0x##h##ull 97 | typedef unsigned long long uint_64t; 98 | # elif defined( __MVS__ ) 99 | # define BRG_UI64 100 | # define li_64(h) 0x##h##ull 101 | typedef unsigned int long long uint_64t; 102 | # elif defined( UINT_MAX ) && UINT_MAX > 4294967295u 103 | # if UINT_MAX == 18446744073709551615u 104 | # define BRG_UI64 105 | # define li_64(h) 0x##h##u 106 | typedef unsigned int uint_64t; 107 | # endif 108 | # elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u 109 | # if ULONG_MAX == 18446744073709551615ul 110 | # define BRG_UI64 111 | # define li_64(h) 0x##h##ul 112 | typedef unsigned long uint_64t; 113 | # endif 114 | # elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u 115 | # if ULLONG_MAX == 18446744073709551615ull 116 | # define BRG_UI64 117 | # define li_64(h) 0x##h##ull 118 | typedef unsigned long long uint_64t; 119 | # endif 120 | # elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u 121 | # if ULONG_LONG_MAX == 18446744073709551615ull 122 | # define BRG_UI64 123 | # define li_64(h) 0x##h##ull 124 | typedef unsigned long long uint_64t; 125 | # endif 126 | # endif 127 | #endif 128 | 129 | #if !defined( BRG_UI64 ) 130 | # if defined( NEED_UINT_64T ) 131 | # error Please define uint_64t as an unsigned 64 bit type in brg_types.h 132 | # endif 133 | #endif 134 | 135 | #ifndef RETURN_VALUES 136 | # define RETURN_VALUES 137 | # if defined( DLL_EXPORT ) 138 | # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) 139 | # define VOID_RETURN __declspec( dllexport ) void __stdcall 140 | # define INT_RETURN __declspec( dllexport ) int __stdcall 141 | # elif defined( __GNUC__ ) 142 | # define VOID_RETURN __declspec( __dllexport__ ) void 143 | # define INT_RETURN __declspec( __dllexport__ ) int 144 | # else 145 | # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers 146 | # endif 147 | # elif defined( DLL_IMPORT ) 148 | # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) 149 | # define VOID_RETURN __declspec( dllimport ) void __stdcall 150 | # define INT_RETURN __declspec( dllimport ) int __stdcall 151 | # elif defined( __GNUC__ ) 152 | # define VOID_RETURN __declspec( __dllimport__ ) void 153 | # define INT_RETURN __declspec( __dllimport__ ) int 154 | # else 155 | # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers 156 | # endif 157 | # elif defined( __WATCOMC__ ) 158 | # define VOID_RETURN void __cdecl 159 | # define INT_RETURN int __cdecl 160 | # else 161 | # define VOID_RETURN void 162 | # define INT_RETURN int 163 | # endif 164 | #endif 165 | 166 | /* These defines are used to detect and set the memory alignment of pointers. 167 | Note that offsets are in bytes. 168 | 169 | ALIGN_OFFSET(x,n) return the positive or zero offset of 170 | the memory addressed by the pointer 'x' 171 | from an address that is aligned on an 172 | 'n' byte boundary ('n' is a power of 2) 173 | 174 | ALIGN_FLOOR(x,n) return a pointer that points to memory 175 | that is aligned on an 'n' byte boundary 176 | and is not higher than the memory address 177 | pointed to by 'x' ('n' is a power of 2) 178 | 179 | ALIGN_CEIL(x,n) return a pointer that points to memory 180 | that is aligned on an 'n' byte boundary 181 | and is not lower than the memory address 182 | pointed to by 'x' ('n' is a power of 2) 183 | */ 184 | 185 | #define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1)) 186 | #define ALIGN_FLOOR(x,n) ((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1))) 187 | #define ALIGN_CEIL(x,n) ((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1))) 188 | 189 | /* These defines are used to declare buffers in a way that allows 190 | faster operations on longer variables to be used. In all these 191 | defines 'size' must be a power of 2 and >= 8. NOTE that the 192 | buffer size is in bytes but the type length is in bits 193 | 194 | UNIT_TYPEDEF(x,size) declares a variable 'x' of length 195 | 'size' bits 196 | 197 | BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize' 198 | bytes defined as an array of variables 199 | each of 'size' bits (bsize must be a 200 | multiple of size / 8) 201 | 202 | UNIT_CAST(x,size) casts a variable to a type of 203 | length 'size' bits 204 | 205 | UPTR_CAST(x,size) casts a pointer to a pointer to a 206 | varaiable of length 'size' bits 207 | */ 208 | 209 | #define UI_TYPE(size) uint_##size##t 210 | #define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x 211 | #define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)] 212 | #define UNIT_CAST(x,size) ((UI_TYPE(size) )(x)) 213 | #define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x)) 214 | 215 | #if defined(__cplusplus) 216 | } 217 | #endif 218 | 219 | #endif 220 | -------------------------------------------------------------------------------- /cpp/minizip/aes/entropy.c: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #else 4 | #include 5 | #include 6 | #include 7 | #endif 8 | 9 | #if defined(__cplusplus) 10 | extern "C" 11 | { 12 | #endif 13 | 14 | #ifdef _WIN32 15 | int entropy_fun(unsigned char buf[], unsigned int len) 16 | { 17 | HCRYPTPROV provider; 18 | unsigned __int64 pentium_tsc[1]; 19 | unsigned int i; 20 | int result = 0; 21 | 22 | 23 | if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 24 | { 25 | result = CryptGenRandom(provider, len, buf); 26 | CryptReleaseContext(provider, 0); 27 | if (result) 28 | return len; 29 | } 30 | 31 | QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc); 32 | 33 | for(i = 0; i < 8 && i < len; ++i) 34 | buf[i] = ((unsigned char*)pentium_tsc)[i]; 35 | 36 | return i; 37 | } 38 | #else 39 | int entropy_fun(unsigned char buf[], unsigned int len) 40 | { 41 | int frand = open("/dev/random", O_RDONLY); 42 | int rlen = 0; 43 | if (frand != -1) 44 | { 45 | rlen = read(frand, buf, len); 46 | close(frand); 47 | } 48 | return rlen; 49 | } 50 | #endif 51 | 52 | #if defined(__cplusplus) 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /cpp/minizip/aes/entropy.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _ENTROPY_FUN_H 3 | #define _ENTROPY_FUN_H 4 | 5 | #if defined(__cplusplus) 6 | extern "C" 7 | { 8 | #endif 9 | 10 | int entropy_fun(unsigned char buf[], unsigned int len); 11 | 12 | #if defined(__cplusplus) 13 | } 14 | #endif 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /cpp/minizip/aes/fileenc.c: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. 4 | All rights reserved. 5 | 6 | LICENSE TERMS 7 | 8 | The free distribution and use of this software in both source and binary 9 | form is allowed (with or without changes) provided that: 10 | 11 | 1. distributions of this source code include the above copyright 12 | notice, this list of conditions and the following disclaimer; 13 | 14 | 2. distributions in binary form include the above copyright 15 | notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other associated materials; 17 | 18 | 3. the copyright holder's name is not used to endorse products 19 | built using this software without specific written permission. 20 | 21 | ALTERNATIVELY, provided that this notice is retained in full, this product 22 | may be distributed under the terms of the GNU General Public License (GPL), 23 | in which case the provisions of the GPL apply INSTEAD OF those given above. 24 | 25 | DISCLAIMER 26 | 27 | This software is provided 'as is' with no explicit or implied warranties 28 | in respect of its properties, including, but not limited to, correctness 29 | and/or fitness for purpose. 30 | ------------------------------------------------------------------------- 31 | Issue Date: 24/01/2003 32 | 33 | This file implements password based file encryption and authentication 34 | using AES in CTR mode, HMAC-SHA1 authentication and RFC2898 password 35 | based key derivation. 36 | 37 | */ 38 | 39 | #include 40 | 41 | #include "fileenc.h" 42 | 43 | #if defined(__cplusplus) 44 | extern "C" 45 | { 46 | #endif 47 | 48 | /* subroutine for data encryption/decryption */ 49 | /* this could be speeded up a lot by aligning */ 50 | /* buffers and using 32 bit operations */ 51 | 52 | static void encr_data(unsigned char data[], unsigned long d_len, fcrypt_ctx cx[1]) 53 | { unsigned long i = 0, pos = cx->encr_pos; 54 | 55 | while(i < d_len) 56 | { 57 | if(pos == AES_BLOCK_SIZE) 58 | { unsigned int j = 0; 59 | /* increment encryption nonce */ 60 | while(j < 8 && !++cx->nonce[j]) 61 | ++j; 62 | /* encrypt the nonce to form next xor buffer */ 63 | aes_encrypt(cx->nonce, cx->encr_bfr, cx->encr_ctx); 64 | pos = 0; 65 | } 66 | 67 | data[i++] ^= cx->encr_bfr[pos++]; 68 | } 69 | 70 | cx->encr_pos = pos; 71 | } 72 | 73 | int fcrypt_init( 74 | int mode, /* the mode to be used (input) */ 75 | const unsigned char pwd[], /* the user specified password (input) */ 76 | unsigned int pwd_len, /* the length of the password (input) */ 77 | const unsigned char salt[], /* the salt (input) */ 78 | #ifdef PASSWORD_VERIFIER 79 | unsigned char pwd_ver[PWD_VER_LENGTH], /* 2 byte password verifier (output) */ 80 | #endif 81 | fcrypt_ctx cx[1]) /* the file encryption context (output) */ 82 | { unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH]; 83 | 84 | if(pwd_len > MAX_PWD_LENGTH) 85 | return PASSWORD_TOO_LONG; 86 | 87 | if(mode < 1 || mode > 3) 88 | return BAD_MODE; 89 | 90 | cx->mode = mode; 91 | cx->pwd_len = pwd_len; 92 | 93 | /* derive the encryption and authentication keys and the password verifier */ 94 | derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS, 95 | kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH); 96 | 97 | /* initialise the encryption nonce and buffer pos */ 98 | cx->encr_pos = AES_BLOCK_SIZE; 99 | /* if we need a random component in the encryption */ 100 | /* nonce, this is where it would have to be set */ 101 | memset(cx->nonce, 0, AES_BLOCK_SIZE * sizeof(unsigned char)); 102 | 103 | /* initialise for encryption using key 1 */ 104 | aes_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx); 105 | 106 | /* initialise for authentication using key 2 */ 107 | hmac_sha_begin(cx->auth_ctx); 108 | hmac_sha_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx); 109 | 110 | #ifdef PASSWORD_VERIFIER 111 | memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH); 112 | #endif 113 | 114 | return GOOD_RETURN; 115 | } 116 | 117 | /* perform 'in place' encryption and authentication */ 118 | 119 | void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]) 120 | { 121 | encr_data(data, data_len, cx); 122 | hmac_sha_data(data, data_len, cx->auth_ctx); 123 | } 124 | 125 | /* perform 'in place' authentication and decryption */ 126 | 127 | void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]) 128 | { 129 | hmac_sha_data(data, data_len, cx->auth_ctx); 130 | encr_data(data, data_len, cx); 131 | } 132 | 133 | /* close encryption/decryption and return the MAC value */ 134 | 135 | int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1]) 136 | { 137 | hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx); 138 | return MAC_LENGTH(cx->mode); /* return MAC length in bytes */ 139 | } 140 | 141 | #if defined(__cplusplus) 142 | } 143 | #endif 144 | -------------------------------------------------------------------------------- /cpp/minizip/aes/fileenc.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. 4 | All rights reserved. 5 | 6 | LICENSE TERMS 7 | 8 | The free distribution and use of this software in both source and binary 9 | form is allowed (with or without changes) provided that: 10 | 11 | 1. distributions of this source code include the above copyright 12 | notice, this list of conditions and the following disclaimer; 13 | 14 | 2. distributions in binary form include the above copyright 15 | notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other associated materials; 17 | 18 | 3. the copyright holder's name is not used to endorse products 19 | built using this software without specific written permission. 20 | 21 | ALTERNATIVELY, provided that this notice is retained in full, this product 22 | may be distributed under the terms of the GNU General Public License (GPL), 23 | in which case the provisions of the GPL apply INSTEAD OF those given above. 24 | 25 | DISCLAIMER 26 | 27 | This software is provided 'as is' with no explicit or implied warranties 28 | in respect of its properties, including, but not limited to, correctness 29 | and/or fitness for purpose. 30 | --------------------------------------------------------------------------- 31 | Issue Date: 24/01/2003 32 | 33 | This file contains the header file for fileenc.c, which implements password 34 | based file encryption and authentication using AES in CTR mode, HMAC-SHA1 35 | authentication and RFC2898 password based key derivation. 36 | */ 37 | 38 | #ifndef _FENC_H 39 | #define _FENC_H 40 | 41 | #include "aes.h" 42 | #include "hmac.h" 43 | #include "pwd2key.h" 44 | 45 | #define PASSWORD_VERIFIER 46 | 47 | #define MAX_KEY_LENGTH 32 48 | #define MAX_PWD_LENGTH 128 49 | #define MAX_SALT_LENGTH 16 50 | #define KEYING_ITERATIONS 1000 51 | 52 | #ifdef PASSWORD_VERIFIER 53 | #define PWD_VER_LENGTH 2 54 | #else 55 | #define PWD_VER_LENGTH 0 56 | #endif 57 | 58 | #define GOOD_RETURN 0 59 | #define PASSWORD_TOO_LONG -100 60 | #define BAD_MODE -101 61 | 62 | /* 63 | Field lengths (in bytes) versus File Encryption Mode (0 < mode < 4) 64 | 65 | Mode Key Salt MAC Overhead 66 | 1 16 8 10 18 67 | 2 24 12 10 22 68 | 3 32 16 10 26 69 | 70 | The following macros assume that the mode value is correct. 71 | */ 72 | 73 | #define KEY_LENGTH(mode) (8 * (mode & 3) + 8) 74 | #define SALT_LENGTH(mode) (4 * (mode & 3) + 4) 75 | #define MAC_LENGTH(mode) (10) 76 | 77 | /* the context for file encryption */ 78 | 79 | #if defined(__cplusplus) 80 | extern "C" 81 | { 82 | #endif 83 | 84 | typedef struct 85 | { unsigned char nonce[AES_BLOCK_SIZE]; /* the CTR nonce */ 86 | unsigned char encr_bfr[AES_BLOCK_SIZE]; /* encrypt buffer */ 87 | aes_encrypt_ctx encr_ctx[1]; /* encryption context */ 88 | hmac_ctx auth_ctx[1]; /* authentication context */ 89 | unsigned int encr_pos; /* block position (enc) */ 90 | unsigned int pwd_len; /* password length */ 91 | unsigned int mode; /* File encryption mode */ 92 | } fcrypt_ctx; 93 | 94 | /* initialise file encryption or decryption */ 95 | 96 | int fcrypt_init( 97 | int mode, /* the mode to be used (input) */ 98 | const unsigned char pwd[], /* the user specified password (input) */ 99 | unsigned int pwd_len, /* the length of the password (input) */ 100 | const unsigned char salt[], /* the salt (input) */ 101 | #ifdef PASSWORD_VERIFIER 102 | unsigned char pwd_ver[PWD_VER_LENGTH], /* 2 byte password verifier (output) */ 103 | #endif 104 | fcrypt_ctx cx[1]); /* the file encryption context (output) */ 105 | 106 | /* perform 'in place' encryption or decryption and authentication */ 107 | 108 | void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]); 109 | void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]); 110 | 111 | /* close encryption/decryption and return the MAC value */ 112 | /* the return value is the length of the MAC */ 113 | 114 | int fcrypt_end(unsigned char mac[], /* the MAC value (output) */ 115 | fcrypt_ctx cx[1]); /* the context (input) */ 116 | 117 | #if defined(__cplusplus) 118 | } 119 | #endif 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /cpp/minizip/aes/hmac.c: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The free distribution and use of this software in both source and binary 8 | form is allowed (with or without changes) provided that: 9 | 10 | 1. distributions of this source code include the above copyright 11 | notice, this list of conditions and the following disclaimer; 12 | 13 | 2. distributions in binary form include the above copyright 14 | notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other associated materials; 16 | 17 | 3. the copyright holder's name is not used to endorse products 18 | built using this software without specific written permission. 19 | 20 | ALTERNATIVELY, provided that this notice is retained in full, this product 21 | may be distributed under the terms of the GNU General Public License (GPL), 22 | in which case the provisions of the GPL apply INSTEAD OF those given above. 23 | 24 | DISCLAIMER 25 | 26 | This software is provided 'as is' with no explicit or implied warranties 27 | in respect of its properties, including, but not limited to, correctness 28 | and/or fitness for purpose. 29 | --------------------------------------------------------------------------- 30 | Issue Date: 26/08/2003 31 | 32 | This is an implementation of HMAC, the FIPS standard keyed hash function 33 | */ 34 | 35 | #include "hmac.h" 36 | #include "brg_types.h" 37 | 38 | #if defined(__cplusplus) 39 | extern "C" 40 | { 41 | #endif 42 | 43 | /* initialise the HMAC context to zero */ 44 | void hmac_sha_begin(hmac_ctx cx[1]) 45 | { 46 | memset(cx, 0, sizeof(hmac_ctx)); 47 | } 48 | 49 | /* input the HMAC key (can be called multiple times) */ 50 | int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]) 51 | { 52 | if(cx->klen == HMAC_IN_DATA) /* error if further key input */ 53 | return HMAC_BAD_MODE; /* is attempted in data mode */ 54 | 55 | if(cx->klen + key_len > HASH_INPUT_SIZE) /* if the key has to be hashed */ 56 | { 57 | if(cx->klen <= HASH_INPUT_SIZE) /* if the hash has not yet been */ 58 | { /* started, initialise it and */ 59 | sha_begin(cx->ctx); /* hash stored key characters */ 60 | sha_hash(cx->key, cx->klen, cx->ctx); 61 | } 62 | 63 | sha_hash(key, key_len, cx->ctx); /* hash long key data into hash */ 64 | } 65 | else /* otherwise store key data */ 66 | memcpy(cx->key + cx->klen, key, key_len); 67 | 68 | cx->klen += key_len; /* update the key length count */ 69 | return HMAC_OK; 70 | } 71 | 72 | /* input the HMAC data (can be called multiple times) - */ 73 | /* note that this call terminates the key input phase */ 74 | void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]) 75 | { unsigned int i; 76 | 77 | if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */ 78 | { 79 | if(cx->klen > HASH_INPUT_SIZE) /* if key is being hashed */ 80 | { /* complete the hash and */ 81 | sha_end(cx->key, cx->ctx); /* store the result as the */ 82 | cx->klen = HASH_OUTPUT_SIZE; /* key and set new length */ 83 | } 84 | 85 | /* pad the key if necessary */ 86 | memset(cx->key + cx->klen, 0, HASH_INPUT_SIZE - cx->klen); 87 | 88 | /* xor ipad into key value */ 89 | for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i) 90 | ((uint_32t*)cx->key)[i] ^= 0x36363636; 91 | 92 | /* and start hash operation */ 93 | sha_begin(cx->ctx); 94 | sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx); 95 | 96 | /* mark as now in data mode */ 97 | cx->klen = HMAC_IN_DATA; 98 | } 99 | 100 | /* hash the data (if any) */ 101 | if(data_len) 102 | sha_hash(data, data_len, cx->ctx); 103 | } 104 | 105 | /* compute and output the MAC value */ 106 | void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]) 107 | { unsigned char dig[HASH_OUTPUT_SIZE]; 108 | unsigned int i; 109 | 110 | /* if no data has been entered perform a null data phase */ 111 | if(cx->klen != HMAC_IN_DATA) 112 | hmac_sha_data((const unsigned char*)0, 0, cx); 113 | 114 | sha_end(dig, cx->ctx); /* complete the inner hash */ 115 | 116 | /* set outer key value using opad and removing ipad */ 117 | for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i) 118 | ((uint_32t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c; 119 | 120 | /* perform the outer hash operation */ 121 | sha_begin(cx->ctx); 122 | sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx); 123 | sha_hash(dig, HASH_OUTPUT_SIZE, cx->ctx); 124 | sha_end(dig, cx->ctx); 125 | 126 | /* output the hash value */ 127 | for(i = 0; i < mac_len; ++i) 128 | mac[i] = dig[i]; 129 | } 130 | 131 | /* 'do it all in one go' subroutine */ 132 | void hmac_sha(const unsigned char key[], unsigned long key_len, 133 | const unsigned char data[], unsigned long data_len, 134 | unsigned char mac[], unsigned long mac_len) 135 | { hmac_ctx cx[1]; 136 | 137 | hmac_sha_begin(cx); 138 | hmac_sha_key(key, key_len, cx); 139 | hmac_sha_data(data, data_len, cx); 140 | hmac_sha_end(mac, mac_len, cx); 141 | } 142 | 143 | #if defined(__cplusplus) 144 | } 145 | #endif 146 | -------------------------------------------------------------------------------- /cpp/minizip/aes/hmac.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The free distribution and use of this software in both source and binary 8 | form is allowed (with or without changes) provided that: 9 | 10 | 1. distributions of this source code include the above copyright 11 | notice, this list of conditions and the following disclaimer; 12 | 13 | 2. distributions in binary form include the above copyright 14 | notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other associated materials; 16 | 17 | 3. the copyright holder's name is not used to endorse products 18 | built using this software without specific written permission. 19 | 20 | ALTERNATIVELY, provided that this notice is retained in full, this product 21 | may be distributed under the terms of the GNU General Public License (GPL), 22 | in which case the provisions of the GPL apply INSTEAD OF those given above. 23 | 24 | DISCLAIMER 25 | 26 | This software is provided 'as is' with no explicit or implied warranties 27 | in respect of its properties, including, but not limited to, correctness 28 | and/or fitness for purpose. 29 | --------------------------------------------------------------------------- 30 | Issue Date: 26/08/2003 31 | 32 | This is an implementation of HMAC, the FIPS standard keyed hash function 33 | */ 34 | 35 | #ifndef _HMAC_H 36 | #define _HMAC_H 37 | 38 | #include 39 | 40 | #if defined(__cplusplus) 41 | extern "C" 42 | { 43 | #endif 44 | 45 | #define USE_SHA1 46 | 47 | #if !defined(USE_SHA1) && !defined(USE_SHA256) 48 | #error define USE_SHA1 or USE_SHA256 to set the HMAC hash algorithm 49 | #endif 50 | 51 | #ifdef USE_SHA1 52 | 53 | #include "sha1.h" 54 | 55 | #define HASH_INPUT_SIZE SHA1_BLOCK_SIZE 56 | #define HASH_OUTPUT_SIZE SHA1_DIGEST_SIZE 57 | #define sha_ctx sha1_ctx 58 | #define sha_begin sha1_begin 59 | #define sha_hash sha1_hash 60 | #define sha_end sha1_end 61 | 62 | #endif 63 | 64 | #ifdef USE_SHA256 65 | 66 | #include "sha2.h" 67 | 68 | #define HASH_INPUT_SIZE SHA256_BLOCK_SIZE 69 | #define HASH_OUTPUT_SIZE SHA256_DIGEST_SIZE 70 | #define sha_ctx sha256_ctx 71 | #define sha_begin sha256_begin 72 | #define sha_hash sha256_hash 73 | #define sha_end sha256_end 74 | 75 | #endif 76 | 77 | #define HMAC_OK 0 78 | #define HMAC_BAD_MODE -1 79 | #define HMAC_IN_DATA 0xffffffff 80 | 81 | typedef struct 82 | { unsigned char key[HASH_INPUT_SIZE]; 83 | sha_ctx ctx[1]; 84 | unsigned long klen; 85 | } hmac_ctx; 86 | 87 | void hmac_sha_begin(hmac_ctx cx[1]); 88 | 89 | int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]); 90 | 91 | void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]); 92 | 93 | void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]); 94 | 95 | void hmac_sha(const unsigned char key[], unsigned long key_len, 96 | const unsigned char data[], unsigned long data_len, 97 | unsigned char mac[], unsigned long mac_len); 98 | 99 | #if defined(__cplusplus) 100 | } 101 | #endif 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /cpp/minizip/aes/prng.c: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. 4 | All rights reserved. 5 | 6 | LICENSE TERMS 7 | 8 | The free distribution and use of this software in both source and binary 9 | form is allowed (with or without changes) provided that: 10 | 11 | 1. distributions of this source code include the above copyright 12 | notice, this list of conditions and the following disclaimer; 13 | 14 | 2. distributions in binary form include the above copyright 15 | notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other associated materials; 17 | 18 | 3. the copyright holder's name is not used to endorse products 19 | built using this software without specific written permission. 20 | 21 | ALTERNATIVELY, provided that this notice is retained in full, this product 22 | may be distributed under the terms of the GNU General Public License (GPL), 23 | in which case the provisions of the GPL apply INSTEAD OF those given above. 24 | 25 | DISCLAIMER 26 | 27 | This software is provided 'as is' with no explicit or implied warranties 28 | in respect of its properties, including, but not limited to, correctness 29 | and/or fitness for purpose. 30 | --------------------------------------------------------------------------- 31 | Issue Date: 24/01/2003 32 | 33 | This file implements a random data pool based on the use of an external 34 | entropy function. It is based on the ideas advocated by Peter Gutmann in 35 | his work on pseudo random sequence generators. It is not a 'paranoid' 36 | random sequence generator and no attempt is made to protect the pool 37 | from prying eyes either by memory locking or by techniques to obscure 38 | its location in memory. 39 | */ 40 | 41 | #include 42 | #include "prng.h" 43 | 44 | #if defined(__cplusplus) 45 | extern "C" 46 | { 47 | #endif 48 | 49 | /* mix a random data pool using the SHA1 compression function (as */ 50 | /* suggested by Peter Gutmann in his paper on random pools) */ 51 | 52 | static void prng_mix(unsigned char buf[]) 53 | { unsigned int i, len; 54 | sha1_ctx ctx[1]; 55 | 56 | /*lint -e{663} unusual array to pointer conversion */ 57 | for(i = 0; i < PRNG_POOL_SIZE; i += SHA1_DIGEST_SIZE) 58 | { 59 | /* copy digest size pool block into SHA1 hash block */ 60 | memcpy(ctx->hash, buf + (i ? i : PRNG_POOL_SIZE) 61 | - SHA1_DIGEST_SIZE, SHA1_DIGEST_SIZE); 62 | 63 | /* copy data from pool into the SHA1 data buffer */ 64 | len = PRNG_POOL_SIZE - i; 65 | memcpy(ctx->wbuf, buf + i, (len > SHA1_BLOCK_SIZE ? SHA1_BLOCK_SIZE : len)); 66 | 67 | if(len < SHA1_BLOCK_SIZE) 68 | memcpy(((char*)ctx->wbuf) + len, buf, SHA1_BLOCK_SIZE - len); 69 | 70 | /* compress using the SHA1 compression function */ 71 | sha1_compile(ctx); 72 | 73 | /* put digest size block back into the random pool */ 74 | memcpy(buf + i, ctx->hash, SHA1_DIGEST_SIZE); 75 | } 76 | } 77 | 78 | /* refresh the output buffer and update the random pool by adding */ 79 | /* entropy and remixing */ 80 | 81 | static void update_pool(prng_ctx ctx[1]) 82 | { unsigned int i = 0; 83 | 84 | /* transfer random pool data to the output buffer */ 85 | memcpy(ctx->obuf, ctx->rbuf, PRNG_POOL_SIZE); 86 | 87 | /* enter entropy data into the pool */ 88 | while(i < PRNG_POOL_SIZE) 89 | i += ctx->entropy(ctx->rbuf + i, PRNG_POOL_SIZE - i); 90 | 91 | /* invert and xor the original pool data into the pool */ 92 | for(i = 0; i < PRNG_POOL_SIZE; ++i) 93 | ctx->rbuf[i] ^= ~ctx->obuf[i]; 94 | 95 | /* mix the pool and the output buffer */ 96 | prng_mix(ctx->rbuf); 97 | prng_mix(ctx->obuf); 98 | } 99 | 100 | void prng_init(prng_entropy_fn fun, prng_ctx ctx[1]) 101 | { int i; 102 | 103 | /* clear the buffers and the counter in the context */ 104 | memset(ctx, 0, sizeof(prng_ctx)); 105 | 106 | /* set the pointer to the entropy collection function */ 107 | ctx->entropy = fun; 108 | 109 | /* initialise the random data pool */ 110 | update_pool(ctx); 111 | 112 | /* mix the pool a minimum number of times */ 113 | for(i = 0; i < PRNG_MIN_MIX; ++i) 114 | prng_mix(ctx->rbuf); 115 | 116 | /* update the pool to prime the pool output buffer */ 117 | update_pool(ctx); 118 | } 119 | 120 | /* provide random bytes from the random data pool */ 121 | 122 | void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1]) 123 | { unsigned char *rp = data; 124 | unsigned int len, pos = ctx->pos; 125 | 126 | while(data_len) 127 | { 128 | /* transfer 'data_len' bytes (or the number of bytes remaining */ 129 | /* the pool output buffer if less) into the output */ 130 | len = (data_len < PRNG_POOL_SIZE - pos ? data_len : PRNG_POOL_SIZE - pos); 131 | memcpy(rp, ctx->obuf + pos, len); 132 | rp += len; /* update ouput buffer position pointer */ 133 | pos += len; /* update pool output buffer pointer */ 134 | data_len -= len; /* update the remaining data count */ 135 | 136 | /* refresh the random pool if necessary */ 137 | if(pos == PRNG_POOL_SIZE) 138 | { 139 | update_pool(ctx); pos = 0; 140 | } 141 | } 142 | 143 | ctx->pos = pos; 144 | } 145 | 146 | void prng_end(prng_ctx ctx[1]) 147 | { 148 | /* ensure the data in the context is destroyed */ 149 | memset(ctx, 0, sizeof(prng_ctx)); 150 | } 151 | 152 | #if defined(__cplusplus) 153 | } 154 | #endif 155 | 156 | -------------------------------------------------------------------------------- /cpp/minizip/aes/prng.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. 4 | All rights reserved. 5 | 6 | LICENSE TERMS 7 | 8 | The free distribution and use of this software in both source and binary 9 | form is allowed (with or without changes) provided that: 10 | 11 | 1. distributions of this source code include the above copyright 12 | notice, this list of conditions and the following disclaimer; 13 | 14 | 2. distributions in binary form include the above copyright 15 | notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other associated materials; 17 | 18 | 3. the copyright holder's name is not used to endorse products 19 | built using this software without specific written permission. 20 | 21 | ALTERNATIVELY, provided that this notice is retained in full, this product 22 | may be distributed under the terms of the GNU General Public License (GPL), 23 | in which case the provisions of the GPL apply INSTEAD OF those given above. 24 | 25 | DISCLAIMER 26 | 27 | This software is provided 'as is' with no explicit or implied warranties 28 | in respect of its properties, including, but not limited to, correctness 29 | and/or fitness for purpose. 30 | --------------------------------------------------------------------------- 31 | Issue Date: 24/01/2003 32 | 33 | This is the header file for an implementation of a random data pool based on 34 | the use of an external entropy function (inspired by Peter Gutmann's work). 35 | */ 36 | 37 | #ifndef _PRNG_H 38 | #define _PRNG_H 39 | 40 | #include "sha1.h" 41 | 42 | #define PRNG_POOL_LEN 256 /* minimum random pool size */ 43 | #define PRNG_MIN_MIX 20 /* min initial pool mixing iterations */ 44 | 45 | /* ensure that pool length is a multiple of the SHA1 digest size */ 46 | 47 | #define PRNG_POOL_SIZE (SHA1_DIGEST_SIZE * (1 + (PRNG_POOL_LEN - 1) / SHA1_DIGEST_SIZE)) 48 | 49 | #if defined(__cplusplus) 50 | extern "C" 51 | { 52 | #endif 53 | 54 | /* A function for providing entropy is a parameter in the prng_init() */ 55 | /* call. This function has the following form and returns a maximum */ 56 | /* of 'len' bytes of pseudo random data in the buffer 'buf'. It can */ 57 | /* return less than 'len' bytes but will be repeatedly called for more */ 58 | /* data in this case. */ 59 | 60 | typedef int (*prng_entropy_fn)(unsigned char buf[], unsigned int len); 61 | 62 | typedef struct 63 | { unsigned char rbuf[PRNG_POOL_SIZE]; /* the random pool */ 64 | unsigned char obuf[PRNG_POOL_SIZE]; /* pool output buffer */ 65 | unsigned int pos; /* output buffer position */ 66 | prng_entropy_fn entropy; /* entropy function pointer */ 67 | } prng_ctx; 68 | 69 | /* initialise the random stream generator */ 70 | void prng_init(prng_entropy_fn fun, prng_ctx ctx[1]); 71 | 72 | /* obtain random bytes from the generator */ 73 | void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1]); 74 | 75 | /* close the random stream generator */ 76 | void prng_end(prng_ctx ctx[1]); 77 | 78 | #if defined(__cplusplus) 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /cpp/minizip/aes/pwd2key.c: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The free distribution and use of this software in both source and binary 8 | form is allowed (with or without changes) provided that: 9 | 10 | 1. distributions of this source code include the above copyright 11 | notice, this list of conditions and the following disclaimer; 12 | 13 | 2. distributions in binary form include the above copyright 14 | notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other associated materials; 16 | 17 | 3. the copyright holder's name is not used to endorse products 18 | built using this software without specific written permission. 19 | 20 | ALTERNATIVELY, provided that this notice is retained in full, this product 21 | may be distributed under the terms of the GNU General Public License (GPL), 22 | in which case the provisions of the GPL apply INSTEAD OF those given above. 23 | 24 | DISCLAIMER 25 | 26 | This software is provided 'as is' with no explicit or implied warranties 27 | in respect of its properties, including, but not limited to, correctness 28 | and/or fitness for purpose. 29 | --------------------------------------------------------------------------- 30 | Issue Date: 26/08/2003 31 | 32 | This is an implementation of RFC2898, which specifies key derivation from 33 | a password and a salt value. 34 | */ 35 | 36 | #include 37 | #include "hmac.h" 38 | 39 | #if defined(__cplusplus) 40 | extern "C" 41 | { 42 | #endif 43 | 44 | void derive_key(const unsigned char pwd[], /* the PASSWORD */ 45 | unsigned int pwd_len, /* and its length */ 46 | const unsigned char salt[], /* the SALT and its */ 47 | unsigned int salt_len, /* length */ 48 | unsigned int iter, /* the number of iterations */ 49 | unsigned char key[], /* space for the output key */ 50 | unsigned int key_len)/* and its required length */ 51 | { 52 | unsigned int i, j, k, n_blk; 53 | unsigned char uu[HASH_OUTPUT_SIZE], ux[HASH_OUTPUT_SIZE]; 54 | hmac_ctx c1[1], c2[1], c3[1]; 55 | 56 | /* set HMAC context (c1) for password */ 57 | hmac_sha_begin(c1); 58 | hmac_sha_key(pwd, pwd_len, c1); 59 | 60 | /* set HMAC context (c2) for password and salt */ 61 | memcpy(c2, c1, sizeof(hmac_ctx)); 62 | hmac_sha_data(salt, salt_len, c2); 63 | 64 | /* find the number of SHA blocks in the key */ 65 | n_blk = 1 + (key_len - 1) / HASH_OUTPUT_SIZE; 66 | 67 | for(i = 0; i < n_blk; ++i) /* for each block in key */ 68 | { 69 | /* ux[] holds the running xor value */ 70 | memset(ux, 0, HASH_OUTPUT_SIZE); 71 | 72 | /* set HMAC context (c3) for password and salt */ 73 | memcpy(c3, c2, sizeof(hmac_ctx)); 74 | 75 | /* enter additional data for 1st block into uu */ 76 | uu[0] = (unsigned char)((i + 1) >> 24); 77 | uu[1] = (unsigned char)((i + 1) >> 16); 78 | uu[2] = (unsigned char)((i + 1) >> 8); 79 | uu[3] = (unsigned char)(i + 1); 80 | 81 | /* this is the key mixing iteration */ 82 | for(j = 0, k = 4; j < iter; ++j) 83 | { 84 | /* add previous round data to HMAC */ 85 | hmac_sha_data(uu, k, c3); 86 | 87 | /* obtain HMAC for uu[] */ 88 | hmac_sha_end(uu, HASH_OUTPUT_SIZE, c3); 89 | 90 | /* xor into the running xor block */ 91 | for(k = 0; k < HASH_OUTPUT_SIZE; ++k) 92 | ux[k] ^= uu[k]; 93 | 94 | /* set HMAC context (c3) for password */ 95 | memcpy(c3, c1, sizeof(hmac_ctx)); 96 | } 97 | 98 | /* compile key blocks into the key output */ 99 | j = 0; k = i * HASH_OUTPUT_SIZE; 100 | while(j < HASH_OUTPUT_SIZE && k < key_len) 101 | key[k++] = ux[j++]; 102 | } 103 | } 104 | 105 | #ifdef TEST 106 | 107 | #include 108 | 109 | struct 110 | { unsigned int pwd_len; 111 | unsigned int salt_len; 112 | unsigned int it_count; 113 | unsigned char *pwd; 114 | unsigned char salt[32]; 115 | unsigned char key[32]; 116 | } tests[] = 117 | { 118 | { 8, 4, 5, (unsigned char*)"password", 119 | { 120 | 0x12, 0x34, 0x56, 0x78 121 | }, 122 | { 123 | 0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7, 124 | 0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 125 | } 126 | }, 127 | { 8, 8, 5, (unsigned char*)"password", 128 | { 129 | 0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 130 | }, 131 | { 132 | 0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6, 133 | 0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 134 | } 135 | }, 136 | { 8, 21, 1, (unsigned char*)"password", 137 | { 138 | "ATHENA.MIT.EDUraeburn" 139 | }, 140 | { 141 | 0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01, 142 | 0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15 143 | } 144 | }, 145 | { 8, 21, 2, (unsigned char*)"password", 146 | { 147 | "ATHENA.MIT.EDUraeburn" 148 | }, 149 | { 150 | 0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e, 151 | 0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d 152 | } 153 | }, 154 | { 8, 21, 1200, (unsigned char*)"password", 155 | { 156 | "ATHENA.MIT.EDUraeburn" 157 | }, 158 | { 159 | 0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e, 160 | 0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b 161 | } 162 | } 163 | }; 164 | 165 | int main() 166 | { unsigned int i, j, key_len = 256; 167 | unsigned char key[256]; 168 | 169 | printf("\nTest of RFC2898 Password Based Key Derivation"); 170 | for(i = 0; i < 5; ++i) 171 | { 172 | derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt, 173 | tests[i].salt_len, tests[i].it_count, key, key_len); 174 | 175 | printf("\ntest %i: ", i + 1); 176 | printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good"); 177 | for(j = 0; j < key_len && j < 64; j += 4) 178 | { 179 | if(j % 16 == 0) 180 | printf("\n"); 181 | printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]); 182 | } 183 | printf(j < key_len ? " ... \n" : "\n"); 184 | } 185 | printf("\n"); 186 | return 0; 187 | } 188 | 189 | #if defined(__cplusplus) 190 | } 191 | #endif 192 | 193 | #endif 194 | -------------------------------------------------------------------------------- /cpp/minizip/aes/pwd2key.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The free distribution and use of this software in both source and binary 8 | form is allowed (with or without changes) provided that: 9 | 10 | 1. distributions of this source code include the above copyright 11 | notice, this list of conditions and the following disclaimer; 12 | 13 | 2. distributions in binary form include the above copyright 14 | notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other associated materials; 16 | 17 | 3. the copyright holder's name is not used to endorse products 18 | built using this software without specific written permission. 19 | 20 | ALTERNATIVELY, provided that this notice is retained in full, this product 21 | may be distributed under the terms of the GNU General Public License (GPL), 22 | in which case the provisions of the GPL apply INSTEAD OF those given above. 23 | 24 | DISCLAIMER 25 | 26 | This software is provided 'as is' with no explicit or implied warranties 27 | in respect of its properties, including, but not limited to, correctness 28 | and/or fitness for purpose. 29 | --------------------------------------------------------------------------- 30 | Issue Date: 26/08/2003 31 | 32 | This is an implementation of RFC2898, which specifies key derivation from 33 | a password and a salt value. 34 | */ 35 | 36 | #ifndef PWD2KEY_H 37 | #define PWD2KEY_H 38 | 39 | #if defined(__cplusplus) 40 | extern "C" 41 | { 42 | #endif 43 | 44 | void derive_key( 45 | const unsigned char pwd[], /* the PASSWORD, and */ 46 | unsigned int pwd_len, /* its length */ 47 | const unsigned char salt[], /* the SALT and its */ 48 | unsigned int salt_len, /* length */ 49 | unsigned int iter, /* the number of iterations */ 50 | unsigned char key[], /* space for the output key */ 51 | unsigned int key_len); /* and its required length */ 52 | 53 | #if defined(__cplusplus) 54 | } 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /cpp/minizip/aes/sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The free distribution and use of this software in both source and binary 8 | form is allowed (with or without changes) provided that: 9 | 10 | 1. distributions of this source code include the above copyright 11 | notice, this list of conditions and the following disclaimer; 12 | 13 | 2. distributions in binary form include the above copyright 14 | notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other associated materials; 16 | 17 | 3. the copyright holder's name is not used to endorse products 18 | built using this software without specific written permission. 19 | 20 | ALTERNATIVELY, provided that this notice is retained in full, this product 21 | may be distributed under the terms of the GNU General Public License (GPL), 22 | in which case the provisions of the GPL apply INSTEAD OF those given above. 23 | 24 | DISCLAIMER 25 | 26 | This software is provided 'as is' with no explicit or implied warranties 27 | in respect of its properties, including, but not limited to, correctness 28 | and/or fitness for purpose. 29 | --------------------------------------------------------------------------- 30 | Issue Date: 01/08/2005 31 | 32 | This is a byte oriented version of SHA1 that operates on arrays of bytes 33 | stored in memory. 34 | */ 35 | 36 | #include /* for memcpy() etc. */ 37 | 38 | #include "sha1.h" 39 | #include "brg_endian.h" 40 | 41 | #if defined(__cplusplus) 42 | extern "C" 43 | { 44 | #endif 45 | 46 | #if defined( _MSC_VER ) && ( _MSC_VER > 800 ) 47 | #pragma intrinsic(memcpy) 48 | #endif 49 | 50 | #if 0 && defined(_MSC_VER) 51 | #define rotl32 _lrotl 52 | #define rotr32 _lrotr 53 | #else 54 | #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) 55 | #define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) 56 | #endif 57 | 58 | #if !defined(bswap_32) 59 | #define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) 60 | #endif 61 | 62 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) 63 | #define SWAP_BYTES 64 | #else 65 | #undef SWAP_BYTES 66 | #endif 67 | 68 | #if defined(SWAP_BYTES) 69 | #define bsw_32(p,n) \ 70 | { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); } 71 | #else 72 | #define bsw_32(p,n) 73 | #endif 74 | 75 | #define SHA1_MASK (SHA1_BLOCK_SIZE - 1) 76 | 77 | #if 0 78 | 79 | #define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 80 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) 81 | #define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 82 | 83 | #else /* Discovered by Rich Schroeppel and Colin Plumb */ 84 | 85 | #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) 86 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) 87 | #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) 88 | 89 | #endif 90 | 91 | /* Compile 64 bytes of hash data into SHA1 context. Note */ 92 | /* that this routine assumes that the byte order in the */ 93 | /* ctx->wbuf[] at this point is in such an order that low */ 94 | /* address bytes in the ORIGINAL byte stream will go in */ 95 | /* this buffer to the high end of 32-bit words on BOTH big */ 96 | /* and little endian systems */ 97 | 98 | #ifdef ARRAY 99 | #define q(v,n) v[n] 100 | #else 101 | #define q(v,n) v##n 102 | #endif 103 | 104 | #define one_cycle(v,a,b,c,d,e,f,k,h) \ 105 | q(v,e) += rotr32(q(v,a),27) + \ 106 | f(q(v,b),q(v,c),q(v,d)) + k + h; \ 107 | q(v,b) = rotr32(q(v,b), 2) 108 | 109 | #define five_cycle(v,f,k,i) \ 110 | one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \ 111 | one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \ 112 | one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \ 113 | one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \ 114 | one_cycle(v, 1,2,3,4,0, f,k,hf(i+4)) 115 | 116 | VOID_RETURN sha1_compile(sha1_ctx ctx[1]) 117 | { uint_32t *w = ctx->wbuf; 118 | 119 | #ifdef ARRAY 120 | uint_32t v[5]; 121 | memcpy(v, ctx->hash, 5 * sizeof(uint_32t)); 122 | #else 123 | uint_32t v0, v1, v2, v3, v4; 124 | v0 = ctx->hash[0]; v1 = ctx->hash[1]; 125 | v2 = ctx->hash[2]; v3 = ctx->hash[3]; 126 | v4 = ctx->hash[4]; 127 | #endif 128 | 129 | #define hf(i) w[i] 130 | 131 | five_cycle(v, ch, 0x5a827999, 0); 132 | five_cycle(v, ch, 0x5a827999, 5); 133 | five_cycle(v, ch, 0x5a827999, 10); 134 | one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \ 135 | 136 | #undef hf 137 | #define hf(i) (w[(i) & 15] = rotl32( \ 138 | w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \ 139 | ^ w[((i) + 2) & 15] ^ w[(i) & 15], 1)) 140 | 141 | one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16)); 142 | one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17)); 143 | one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18)); 144 | one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19)); 145 | 146 | five_cycle(v, parity, 0x6ed9eba1, 20); 147 | five_cycle(v, parity, 0x6ed9eba1, 25); 148 | five_cycle(v, parity, 0x6ed9eba1, 30); 149 | five_cycle(v, parity, 0x6ed9eba1, 35); 150 | 151 | five_cycle(v, maj, 0x8f1bbcdc, 40); 152 | five_cycle(v, maj, 0x8f1bbcdc, 45); 153 | five_cycle(v, maj, 0x8f1bbcdc, 50); 154 | five_cycle(v, maj, 0x8f1bbcdc, 55); 155 | 156 | five_cycle(v, parity, 0xca62c1d6, 60); 157 | five_cycle(v, parity, 0xca62c1d6, 65); 158 | five_cycle(v, parity, 0xca62c1d6, 70); 159 | five_cycle(v, parity, 0xca62c1d6, 75); 160 | 161 | #ifdef ARRAY 162 | ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; 163 | ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; 164 | ctx->hash[4] += v[4]; 165 | #else 166 | ctx->hash[0] += v0; ctx->hash[1] += v1; 167 | ctx->hash[2] += v2; ctx->hash[3] += v3; 168 | ctx->hash[4] += v4; 169 | #endif 170 | } 171 | 172 | VOID_RETURN sha1_begin(sha1_ctx ctx[1]) 173 | { 174 | ctx->count[0] = ctx->count[1] = 0; 175 | ctx->hash[0] = 0x67452301; 176 | ctx->hash[1] = 0xefcdab89; 177 | ctx->hash[2] = 0x98badcfe; 178 | ctx->hash[3] = 0x10325476; 179 | ctx->hash[4] = 0xc3d2e1f0; 180 | } 181 | 182 | /* SHA1 hash data in an array of bytes into hash buffer and */ 183 | /* call the hash_compile function as required. */ 184 | 185 | VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]) 186 | { uint_32t pos = (uint_32t)(ctx->count[0] & SHA1_MASK), 187 | space = SHA1_BLOCK_SIZE - pos; 188 | const unsigned char *sp = data; 189 | 190 | if((ctx->count[0] += len) < len) 191 | ++(ctx->count[1]); 192 | 193 | while(len >= space) /* tranfer whole blocks if possible */ 194 | { 195 | memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); 196 | sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0; 197 | bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2); 198 | sha1_compile(ctx); 199 | } 200 | 201 | memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); 202 | } 203 | 204 | /* SHA1 final padding and digest calculation */ 205 | 206 | VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]) 207 | { uint_32t i = (uint_32t)(ctx->count[0] & SHA1_MASK); 208 | 209 | /* put bytes in the buffer in an order in which references to */ 210 | /* 32-bit words will put bytes with lower addresses into the */ 211 | /* top of 32 bit words on BOTH big and little endian machines */ 212 | bsw_32(ctx->wbuf, (i + 3) >> 2); 213 | 214 | /* we now need to mask valid bytes and add the padding which is */ 215 | /* a single 1 bit and as many zero bits as necessary. Note that */ 216 | /* we can always add the first padding byte here because the */ 217 | /* buffer always has at least one empty slot */ 218 | ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3); 219 | ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3); 220 | 221 | /* we need 9 or more empty positions, one for the padding byte */ 222 | /* (above) and eight for the length count. If there is not */ 223 | /* enough space, pad and empty the buffer */ 224 | if(i > SHA1_BLOCK_SIZE - 9) 225 | { 226 | if(i < 60) ctx->wbuf[15] = 0; 227 | sha1_compile(ctx); 228 | i = 0; 229 | } 230 | else /* compute a word index for the empty buffer positions */ 231 | i = (i >> 2) + 1; 232 | 233 | while(i < 14) /* and zero pad all but last two positions */ 234 | ctx->wbuf[i++] = 0; 235 | 236 | /* the following 32-bit length fields are assembled in the */ 237 | /* wrong byte order on little endian machines but this is */ 238 | /* corrected later since they are only ever used as 32-bit */ 239 | /* word values. */ 240 | ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); 241 | ctx->wbuf[15] = ctx->count[0] << 3; 242 | sha1_compile(ctx); 243 | 244 | /* extract the hash value as bytes in case the hash buffer is */ 245 | /* misaligned for 32-bit words */ 246 | for(i = 0; i < SHA1_DIGEST_SIZE; ++i) 247 | hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); 248 | } 249 | 250 | VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len) 251 | { sha1_ctx cx[1]; 252 | 253 | sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx); 254 | } 255 | 256 | #if defined(__cplusplus) 257 | } 258 | #endif 259 | -------------------------------------------------------------------------------- /cpp/minizip/aes/sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The free distribution and use of this software in both source and binary 8 | form is allowed (with or without changes) provided that: 9 | 10 | 1. distributions of this source code include the above copyright 11 | notice, this list of conditions and the following disclaimer; 12 | 13 | 2. distributions in binary form include the above copyright 14 | notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other associated materials; 16 | 17 | 3. the copyright holder's name is not used to endorse products 18 | built using this software without specific written permission. 19 | 20 | ALTERNATIVELY, provided that this notice is retained in full, this product 21 | may be distributed under the terms of the GNU General Public License (GPL), 22 | in which case the provisions of the GPL apply INSTEAD OF those given above. 23 | 24 | DISCLAIMER 25 | 26 | This software is provided 'as is' with no explicit or implied warranties 27 | in respect of its properties, including, but not limited to, correctness 28 | and/or fitness for purpose. 29 | --------------------------------------------------------------------------- 30 | Issue Date: 01/08/2005 31 | */ 32 | 33 | #ifndef _SHA1_H 34 | #define _SHA1_H 35 | 36 | #include 37 | #include "brg_types.h" 38 | 39 | #define SHA1_BLOCK_SIZE 64 40 | #define SHA1_DIGEST_SIZE 20 41 | 42 | #if defined(__cplusplus) 43 | extern "C" 44 | { 45 | #endif 46 | 47 | /* type to hold the SHA256 context */ 48 | 49 | typedef struct 50 | { uint_32t count[2]; 51 | uint_32t hash[5]; 52 | uint_32t wbuf[16]; 53 | } sha1_ctx; 54 | 55 | /* Note that these prototypes are the same for both bit and */ 56 | /* byte oriented implementations. However the length fields */ 57 | /* are in bytes or bits as appropriate for the version used */ 58 | /* and bit sequences are input as arrays of bytes in which */ 59 | /* bit sequences run from the most to the least significant */ 60 | /* end of each byte */ 61 | 62 | VOID_RETURN sha1_compile(sha1_ctx ctx[1]); 63 | 64 | VOID_RETURN sha1_begin(sha1_ctx ctx[1]); 65 | VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]); 66 | VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]); 67 | VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len); 68 | 69 | #if defined(__cplusplus) 70 | } 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /cpp/minizip/configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_INIT([minizip], [1.2.8], [bugzilla.redhat.com]) 5 | AC_CONFIG_SRCDIR([minizip.c]) 6 | AM_INIT_AUTOMAKE([foreign]) 7 | LT_INIT 8 | 9 | AC_MSG_CHECKING([whether to build example programs]) 10 | AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs])) 11 | AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes]) 12 | if test "$enable_demos" = yes 13 | then 14 | AC_MSG_RESULT([yes]) 15 | else 16 | AC_MSG_RESULT([no]) 17 | fi 18 | 19 | case "${host}" in 20 | *-mingw* | mingw*) 21 | WIN32="yes" 22 | ;; 23 | *) 24 | ;; 25 | esac 26 | AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) 27 | 28 | 29 | AC_SUBST([HAVE_UNISTD_H], [0]) 30 | AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], []) 31 | AC_CONFIG_FILES([Makefile minizip.pc]) 32 | AC_OUTPUT 33 | -------------------------------------------------------------------------------- /cpp/minizip/crypt.h: -------------------------------------------------------------------------------- 1 | /* crypt.h -- base code for traditional PKWARE encryption 2 | Version 1.01e, February 12th, 2005 3 | 4 | Copyright (C) 1998-2005 Gilles Vollant 5 | Modifications for Info-ZIP crypting 6 | Copyright (C) 2003 Terry Thorsen 7 | 8 | This code is a modified version of crypting code in Info-ZIP distribution 9 | 10 | Copyright (C) 1990-2000 Info-ZIP. All rights reserved. 11 | 12 | See the Info-ZIP LICENSE file version 2000-Apr-09 or later for terms of use 13 | which also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 14 | 15 | The encryption/decryption parts of this source code (as opposed to the 16 | non-echoing password parts) were originally written in Europe. The 17 | whole source package can be freely distributed, including from the USA. 18 | (Prior to January 2000, re-export from the US was a violation of US law.) 19 | 20 | This encryption code is a direct transcription of the algorithm from 21 | Roger Schlafly, described by Phil Katz in the file appnote.txt. This 22 | file (appnote.txt) is distributed with the PKZIP program (even in the 23 | version without encryption capabilities). 24 | 25 | If you don't need crypting in your application, just define symbols 26 | NOCRYPT and NOUNCRYPT. 27 | 28 | Mar 8th, 2016 - Lucio Cosmo 29 | Fixed support for 64bit builds for archives with "PKWARE" password. 30 | Changed long, unsigned long, unsigned to unsigned int in 31 | access functions to crctables and pkeys 32 | 33 | */ 34 | 35 | #define CRC32(c, b) ((*(pcrc_32_tab+(((unsigned int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) 36 | 37 | /*********************************************************************** 38 | * Return the next byte in the pseudo-random sequence 39 | */ 40 | static int decrypt_byte(unsigned int* pkeys) 41 | { 42 | unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an 43 | * unpredictable manner on 16-bit systems; not a problem 44 | * with any known compiler so far, though */ 45 | 46 | temp = ((unsigned int)(*(pkeys+2)) & 0xffff) | 2; 47 | return (unsigned int)(((temp * (temp ^ 1)) >> 8) & 0xff); 48 | } 49 | 50 | /*********************************************************************** 51 | * Update the encryption keys with the next byte of plain text 52 | */ 53 | static int update_keys(unsigned int* pkeys,const unsigned int* pcrc_32_tab,int c) 54 | { 55 | (*(pkeys+0)) = CRC32((*(pkeys+0)), c); 56 | (*(pkeys+1)) += (*(pkeys+0)) & 0xff; 57 | (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; 58 | { 59 | register int keyshift = (int)((*(pkeys+1)) >> 24); 60 | (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); 61 | } 62 | return c; 63 | } 64 | 65 | 66 | /*********************************************************************** 67 | * Initialize the encryption keys and the random header according to 68 | * the given password. 69 | */ 70 | static void init_keys(const char* passwd,unsigned int* pkeys,const unsigned int* pcrc_32_tab) 71 | { 72 | *(pkeys+0) = 305419896L; 73 | *(pkeys+1) = 591751049L; 74 | *(pkeys+2) = 878082192L; 75 | while (*passwd != 0) 76 | { 77 | update_keys(pkeys,pcrc_32_tab,(int)*passwd); 78 | passwd++; 79 | } 80 | } 81 | 82 | #define zdecode(pkeys,pcrc_32_tab,c) \ 83 | (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys))) 84 | 85 | #define zencode(pkeys,pcrc_32_tab,c,t) \ 86 | (t=decrypt_byte(pkeys), update_keys(pkeys,pcrc_32_tab,c), t^(c)) 87 | 88 | #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED 89 | 90 | #define RAND_HEAD_LEN 12 91 | /* "last resort" source for second part of crypt seed pattern */ 92 | # ifndef ZCR_SEED2 93 | # define ZCR_SEED2 3141592654UL /* use PI as default pattern */ 94 | # endif 95 | 96 | static int crypthead(const char* passwd, /* password string */ 97 | unsigned char* buf, /* where to write header */ 98 | int bufSize, 99 | unsigned int* pkeys, 100 | const unsigned int* pcrc_32_tab, 101 | unsigned int crcForCrypting) 102 | { 103 | int n; /* index in random header */ 104 | int t; /* temporary */ 105 | int c; /* random byte */ 106 | unsigned char header[RAND_HEAD_LEN-2]; /* random header */ 107 | static unsigned calls = 0; /* ensure different random header each time */ 108 | 109 | if (bufSize < RAND_HEAD_LEN) 110 | return 0; 111 | 112 | /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the 113 | * output of rand() to get less predictability, since rand() is 114 | * often poorly implemented. 115 | */ 116 | if (++calls == 1) 117 | { 118 | srand((unsigned)(time(NULL) ^ ZCR_SEED2)); 119 | } 120 | init_keys(passwd, pkeys, pcrc_32_tab); 121 | for (n = 0; n < RAND_HEAD_LEN-2; n++) 122 | { 123 | c = (rand() >> 7) & 0xff; 124 | header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); 125 | } 126 | /* Encrypt random header (last two bytes is high word of crc) */ 127 | init_keys(passwd, pkeys, pcrc_32_tab); 128 | for (n = 0; n < RAND_HEAD_LEN-2; n++) 129 | { 130 | buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); 131 | } 132 | buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); 133 | buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); 134 | return n; 135 | } 136 | 137 | #endif 138 | -------------------------------------------------------------------------------- /cpp/minizip/ioapi.h: -------------------------------------------------------------------------------- 1 | /* ioapi.h -- IO base function header for compress/uncompress .zip 2 | part of the MiniZip project 3 | 4 | Copyright (C) 1998-2010 Gilles Vollant 5 | http://www.winimage.com/zLibDll/minizip.html 6 | Modifications for Zip64 support 7 | Copyright (C) 2009-2010 Mathias Svensson 8 | http://result42.com 9 | 10 | This program is distributed under the terms of the same license as zlib. 11 | See the accompanying LICENSE file for the full text of the license. 12 | */ 13 | 14 | #ifndef _ZLIBIOAPI64_H 15 | #define _ZLIBIOAPI64_H 16 | 17 | #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) 18 | # ifndef __USE_FILE_OFFSET64 19 | # define __USE_FILE_OFFSET64 20 | # endif 21 | # ifndef __USE_LARGEFILE64 22 | # define __USE_LARGEFILE64 23 | # endif 24 | # ifndef _LARGEFILE64_SOURCE 25 | # define _LARGEFILE64_SOURCE 26 | # endif 27 | # ifndef _FILE_OFFSET_BIT 28 | # define _FILE_OFFSET_BIT 64 29 | # endif 30 | #endif 31 | 32 | #include 33 | #include 34 | #include "zlib.h" 35 | 36 | #if defined(USE_FILE32API) 37 | # define fopen64 fopen 38 | # define ftello64 ftell 39 | # define fseeko64 fseek 40 | #else 41 | # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) 42 | # define fopen64 fopen 43 | # define ftello64 ftello 44 | # define fseeko64 fseeko 45 | # endif 46 | # ifdef _MSC_VER 47 | # define fopen64 fopen 48 | # if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) 49 | # define ftello64 _ftelli64 50 | # define fseeko64 _fseeki64 51 | # else /* old MSC */ 52 | # define ftello64 ftell 53 | # define fseeko64 fseek 54 | # endif 55 | # endif 56 | #endif 57 | 58 | /* a type choosen by DEFINE */ 59 | #ifdef HAVE_64BIT_INT_CUSTOM 60 | typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; 61 | #else 62 | # ifdef HAVE_STDINT_H 63 | # include "stdint.h" 64 | typedef uint64_t ZPOS64_T; 65 | # else 66 | # if defined(_MSC_VER) || defined(__BORLANDC__) 67 | typedef unsigned __int64 ZPOS64_T; 68 | # else 69 | typedef unsigned long long int ZPOS64_T; 70 | # endif 71 | # endif 72 | #endif 73 | 74 | #ifdef __cplusplus 75 | extern "C" { 76 | #endif 77 | 78 | #define ZLIB_FILEFUNC_SEEK_CUR (1) 79 | #define ZLIB_FILEFUNC_SEEK_END (2) 80 | #define ZLIB_FILEFUNC_SEEK_SET (0) 81 | 82 | #define ZLIB_FILEFUNC_MODE_READ (1) 83 | #define ZLIB_FILEFUNC_MODE_WRITE (2) 84 | #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) 85 | #define ZLIB_FILEFUNC_MODE_EXISTING (4) 86 | #define ZLIB_FILEFUNC_MODE_CREATE (8) 87 | 88 | #ifndef ZCALLBACK 89 | # if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || \ 90 | defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) 91 | # define ZCALLBACK CALLBACK 92 | # else 93 | # define ZCALLBACK 94 | # endif 95 | #endif 96 | 97 | typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); 98 | typedef voidpf (ZCALLBACK *opendisk_file_func) OF((voidpf opaque, voidpf stream, int number_disk, int mode)); 99 | typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 100 | typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); 101 | typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); 102 | typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); 103 | 104 | typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); 105 | typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); 106 | 107 | /* here is the "old" 32 bits structure structure */ 108 | typedef struct zlib_filefunc_def_s 109 | { 110 | open_file_func zopen_file; 111 | opendisk_file_func zopendisk_file; 112 | read_file_func zread_file; 113 | write_file_func zwrite_file; 114 | tell_file_func ztell_file; 115 | seek_file_func zseek_file; 116 | close_file_func zclose_file; 117 | testerror_file_func zerror_file; 118 | voidpf opaque; 119 | } zlib_filefunc_def; 120 | 121 | typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); 122 | typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); 123 | typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); 124 | typedef voidpf (ZCALLBACK *opendisk64_file_func)OF((voidpf opaque, voidpf stream, int number_disk, int mode)); 125 | 126 | typedef struct zlib_filefunc64_def_s 127 | { 128 | open64_file_func zopen64_file; 129 | opendisk64_file_func zopendisk64_file; 130 | read_file_func zread_file; 131 | write_file_func zwrite_file; 132 | tell64_file_func ztell64_file; 133 | seek64_file_func zseek64_file; 134 | close_file_func zclose_file; 135 | testerror_file_func zerror_file; 136 | voidpf opaque; 137 | } zlib_filefunc64_def; 138 | 139 | void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 140 | void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); 141 | 142 | /* now internal definition, only for zip.c and unzip.h */ 143 | typedef struct zlib_filefunc64_32_def_s 144 | { 145 | zlib_filefunc64_def zfile_func64; 146 | open_file_func zopen32_file; 147 | opendisk_file_func zopendisk32_file; 148 | tell_file_func ztell32_file; 149 | seek_file_func zseek32_file; 150 | } zlib_filefunc64_32_def; 151 | 152 | #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 153 | #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 154 | /*#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))*/ 155 | /*#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))*/ 156 | #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) 157 | #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) 158 | 159 | voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); 160 | voidpf call_zopendisk64 OF((const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, int number_disk, int mode)); 161 | long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); 162 | ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); 163 | 164 | void fill_zlib_filefunc64_32_def_from_filefunc32 OF((zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)); 165 | 166 | #define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) 167 | #define ZOPENDISK64(filefunc,filestream,diskn,mode) (call_zopendisk64((&(filefunc)),(filestream),(diskn),(mode))) 168 | #define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) 169 | #define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) 170 | 171 | #ifdef __cplusplus 172 | } 173 | #endif 174 | 175 | #endif 176 | -------------------------------------------------------------------------------- /cpp/minizip/ioapi_buf.h: -------------------------------------------------------------------------------- 1 | /* ioapi_buf.h -- IO base function header for compress/uncompress .zip 2 | files using zlib + zip or unzip API 3 | 4 | This version of ioapi is designed to buffer IO. 5 | 6 | Copyright (C) 1998-2003 Gilles Vollant 7 | (C) 2012-2014 Nathan Moinvaziri 8 | 9 | This program is distributed under the terms of the same license as zlib. 10 | See the accompanying LICENSE file for the full text of the license. 11 | */ 12 | 13 | #ifndef _IOAPI_BUF_H 14 | #define _IOAPI_BUF_H 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "zlib.h" 21 | #include "ioapi.h" 22 | 23 | #define IOBUF_BUFFERSIZE (64 * 1024) 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | voidpf ZCALLBACK fopen_buf_func OF((voidpf opaque,const char* filename,int mode)); 30 | voidpf ZCALLBACK fopen64_buf_func OF((voidpf opaque,const char* filename,int mode)); 31 | voidpf ZCALLBACK fopendisk_buf_func OF((voidpf opaque, voidpf stream_cd, int number_disk, int mode)); 32 | voidpf ZCALLBACK fopendisk64_buf_func OF((voidpf opaque, voidpf stream_cd, int number_disk, int mode)); 33 | uLong ZCALLBACK fread_buf_func OF((voidpf opaque,voidpf stream,void* buf,uLong size)); 34 | uLong ZCALLBACK fwrite_buf_func OF((voidpf opaque,voidpf stream,const void* buf,uLong size)); 35 | long ZCALLBACK ftell_buf_func OF((voidpf opaque,voidpf stream)); 36 | ZPOS64_T ZCALLBACK ftell64_buf_func OF((voidpf opaque, voidpf stream)); 37 | long ZCALLBACK fseek_buf_func OF((voidpf opaque,voidpf stream,uLong offset,int origin)); 38 | long ZCALLBACK fseek64_buf_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); 39 | int ZCALLBACK fclose_buf_func OF((voidpf opaque,voidpf stream)); 40 | int ZCALLBACK ferror_buf_func OF((voidpf opaque,voidpf stream)); 41 | 42 | typedef struct ourbuffer_s { 43 | zlib_filefunc_def filefunc; 44 | zlib_filefunc64_def filefunc64; 45 | } ourbuffer_t; 46 | 47 | void fill_buffer_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def, ourbuffer_t *ourbuf)); 48 | void fill_buffer_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def, ourbuffer_t *ourbuf)); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /cpp/minizip/ioapi_mem.c: -------------------------------------------------------------------------------- 1 | /* ioapi_mem.h -- IO base function header for compress/uncompress .zip 2 | files using zlib + zip or unzip API 3 | 4 | This version of ioapi is designed to access memory rather than files. 5 | We do use a region of memory to put data in to and take it out of. We do 6 | not have auto-extending buffers and do not inform anyone else that the 7 | data has been written. It is really intended for accessing a zip archive 8 | embedded in an application such that I can write an installer with no 9 | external files. Creation of archives has not been attempted, although 10 | parts of the framework are present. 11 | 12 | Based on Unzip ioapi.c version 0.22, May 19th, 2003 13 | 14 | Copyright (C) 1998-2003 Gilles Vollant 15 | (C) 2003 Justin Fletcher 16 | 17 | This file is under the same license as the Unzip tool it is distributed 18 | with. 19 | */ 20 | 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "zlib.h" 27 | #include "ioapi.h" 28 | 29 | #include "ioapi_mem.h" 30 | 31 | #ifndef IOMEM_BUFFERSIZE 32 | # define IOMEM_BUFFERSIZE (64 * 1024) 33 | #endif 34 | 35 | voidpf ZCALLBACK fopen_mem_func (opaque, filename, mode) 36 | voidpf opaque; 37 | const char* filename; 38 | int mode; 39 | { 40 | ourmemory_t *mem = (ourmemory_t *)opaque; 41 | if (mem == NULL) 42 | return NULL; /* Mem structure passed in was null */ 43 | 44 | if (mode & ZLIB_FILEFUNC_MODE_CREATE) 45 | { 46 | if (mem->grow) 47 | { 48 | mem->size = IOMEM_BUFFERSIZE; 49 | mem->base = (char *)malloc(mem->size); 50 | } 51 | 52 | mem->limit = 0; /* When writing we start with 0 bytes written */ 53 | } 54 | else 55 | mem->limit = mem->size; 56 | 57 | mem->cur_offset = 0; 58 | 59 | return mem; 60 | } 61 | 62 | voidpf ZCALLBACK fopendisk_mem_func (opaque, stream, number_disk, mode) 63 | voidpf opaque; 64 | voidpf stream; 65 | int number_disk; 66 | int mode; 67 | { 68 | /* Not used */ 69 | return NULL; 70 | } 71 | 72 | uLong ZCALLBACK fread_mem_func (opaque, stream, buf, size) 73 | voidpf opaque; 74 | voidpf stream; 75 | void* buf; 76 | uLong size; 77 | { 78 | ourmemory_t *mem = (ourmemory_t *)stream; 79 | 80 | if (size > mem->size - mem->cur_offset) 81 | size = mem->size - mem->cur_offset; 82 | 83 | memcpy(buf, mem->base + mem->cur_offset, size); 84 | mem->cur_offset += size; 85 | 86 | return size; 87 | } 88 | 89 | 90 | uLong ZCALLBACK fwrite_mem_func (opaque, stream, buf, size) 91 | voidpf opaque; 92 | voidpf stream; 93 | const void* buf; 94 | uLong size; 95 | { 96 | ourmemory_t *mem = (ourmemory_t *)stream; 97 | char *newbase = NULL; 98 | uLong newmemsize = 0; 99 | 100 | if (size > mem->size - mem->cur_offset) 101 | { 102 | if (mem->grow) 103 | { 104 | newmemsize = mem->size; 105 | if (size < IOMEM_BUFFERSIZE) 106 | newmemsize += IOMEM_BUFFERSIZE; 107 | else 108 | newmemsize += size; 109 | newbase = (char *)malloc(newmemsize); 110 | memcpy(newbase, mem->base, mem->size); 111 | free(mem->base); 112 | mem->base = newbase; 113 | mem->size = newmemsize; 114 | } 115 | else 116 | size = mem->size - mem->cur_offset; 117 | } 118 | memcpy(mem->base + mem->cur_offset, buf, size); 119 | mem->cur_offset += size; 120 | if (mem->cur_offset > mem->limit) 121 | mem->limit = mem->cur_offset; 122 | 123 | return size; 124 | } 125 | 126 | long ZCALLBACK ftell_mem_func (opaque, stream) 127 | voidpf opaque; 128 | voidpf stream; 129 | { 130 | ourmemory_t *mem = (ourmemory_t *)stream; 131 | return mem->cur_offset; 132 | } 133 | 134 | long ZCALLBACK fseek_mem_func (opaque, stream, offset, origin) 135 | voidpf opaque; 136 | voidpf stream; 137 | uLong offset; 138 | int origin; 139 | { 140 | ourmemory_t *mem = (ourmemory_t *)stream; 141 | uLong new_pos; 142 | switch (origin) 143 | { 144 | case ZLIB_FILEFUNC_SEEK_CUR: 145 | new_pos = mem->cur_offset + offset; 146 | break; 147 | case ZLIB_FILEFUNC_SEEK_END: 148 | new_pos = mem->limit + offset; 149 | break; 150 | case ZLIB_FILEFUNC_SEEK_SET: 151 | new_pos = offset; 152 | break; 153 | default: 154 | return -1; 155 | } 156 | 157 | if (new_pos > mem->size) 158 | return 1; /* Failed to seek that far */ 159 | mem->cur_offset = new_pos; 160 | return 0; 161 | } 162 | 163 | int ZCALLBACK fclose_mem_func (opaque, stream) 164 | voidpf opaque; 165 | voidpf stream; 166 | { 167 | /* Even with grow = 1, caller must always free() memory */ 168 | return 0; 169 | } 170 | 171 | int ZCALLBACK ferror_mem_func (opaque, stream) 172 | voidpf opaque; 173 | voidpf stream; 174 | { 175 | /* We never return errors */ 176 | return 0; 177 | } 178 | 179 | void fill_memory_filefunc (pzlib_filefunc_def, ourmem) 180 | zlib_filefunc_def* pzlib_filefunc_def; 181 | ourmemory_t *ourmem; 182 | { 183 | pzlib_filefunc_def->zopen_file = fopen_mem_func; 184 | pzlib_filefunc_def->zopendisk_file = fopendisk_mem_func; 185 | pzlib_filefunc_def->zread_file = fread_mem_func; 186 | pzlib_filefunc_def->zwrite_file = fwrite_mem_func; 187 | pzlib_filefunc_def->ztell_file = ftell_mem_func; 188 | pzlib_filefunc_def->zseek_file = fseek_mem_func; 189 | pzlib_filefunc_def->zclose_file = fclose_mem_func; 190 | pzlib_filefunc_def->zerror_file = ferror_mem_func; 191 | pzlib_filefunc_def->opaque = ourmem; 192 | } 193 | -------------------------------------------------------------------------------- /cpp/minizip/ioapi_mem.h: -------------------------------------------------------------------------------- 1 | /* ioapi_mem.h -- IO base function header for compress/uncompress .zip 2 | files using zlib + zip or unzip API 3 | 4 | This version of ioapi is designed to access memory rather than files. 5 | We do use a region of memory to put data in to and take it out of. 6 | 7 | Copyright (C) 1998-2003 Gilles Vollant 8 | (C) 2003 Justin Fletcher 9 | 10 | This program is distributed under the terms of the same license as zlib. 11 | See the accompanying LICENSE file for the full text of the license. 12 | */ 13 | 14 | #ifndef _IOAPI_MEM_H 15 | #define _IOAPI_MEM_H 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "zlib.h" 22 | #include "ioapi.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | voidpf ZCALLBACK fopen_mem_func OF((voidpf opaque,const char* filename,int mode)); 29 | voidpf ZCALLBACK fopendisk_mem_func OF((voidpf opaque, voidpf stream, int number_disk, int mode)); 30 | uLong ZCALLBACK fread_mem_func OF((voidpf opaque,voidpf stream,void* buf,uLong size)); 31 | uLong ZCALLBACK fwrite_mem_func OF((voidpf opaque,voidpf stream,const void* buf,uLong size)); 32 | long ZCALLBACK ftell_mem_func OF((voidpf opaque,voidpf stream)); 33 | long ZCALLBACK fseek_mem_func OF((voidpf opaque,voidpf stream,uLong offset,int origin)); 34 | int ZCALLBACK fclose_mem_func OF((voidpf opaque,voidpf stream)); 35 | int ZCALLBACK ferror_mem_func OF((voidpf opaque,voidpf stream)); 36 | 37 | typedef struct ourmemory_s { 38 | char *base; /* Base of the region of memory we're using */ 39 | uLong size; /* Size of the region of memory we're using */ 40 | uLong limit; /* Furthest we've written */ 41 | uLong cur_offset; /* Current offset in the area */ 42 | int grow; /* Growable memory buffer */ 43 | } ourmemory_t; 44 | 45 | void fill_memory_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def, ourmemory_t *ourmem)); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /cpp/minizip/iowin32.h: -------------------------------------------------------------------------------- 1 | /* iowin32.h -- IO base function header for compress/uncompress .zip 2 | Version 1.1, February 14h, 2010 3 | part of the MiniZip project 4 | 5 | Copyright (C) 1998-2010 Gilles Vollant 6 | http://www.winimage.com/zLibDll/minizip.html 7 | Modifications for Zip64 support 8 | Copyright (C) 2009-2010 Mathias Svensson 9 | http://result42.com 10 | 11 | This program is distributed under the terms of the same license as zlib. 12 | See the accompanying LICENSE file for the full text of the license. 13 | */ 14 | 15 | #ifndef _IOWIN32_H 16 | #define _IOWIN32_H 17 | 18 | #include 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 25 | void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def)); 26 | void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def)); 27 | void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def)); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /cpp/minizip/libaes.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinLiAmoy/rnn-fpga/7f485719b87d1021a16944bba68c1d43c28ea794/cpp/minizip/libaes.a -------------------------------------------------------------------------------- /cpp/minizip/libminizip.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinLiAmoy/rnn-fpga/7f485719b87d1021a16944bba68c1d43c28ea794/cpp/minizip/libminizip.a -------------------------------------------------------------------------------- /cpp/minizip/miniunz.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 52 | 55 | 58 | 61 | 66 | 69 | 72 | 75 | 78 | 81 | 84 | 87 | 88 | 96 | 99 | 102 | 105 | 108 | 111 | 123 | 126 | 129 | 132 | 139 | 142 | 145 | 148 | 151 | 154 | 157 | 160 | 161 | 162 | 163 | 164 | 165 | 170 | 173 | 174 | 177 | 178 | 181 | 182 | 185 | 186 | 187 | 192 | 195 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 209 | 214 | 215 | 218 | 221 | 222 | 225 | 226 | 229 | 230 | 233 | 234 | 237 | 238 | 241 | 242 | 245 | 246 | 249 | 250 | 253 | 254 | 257 | 258 | 261 | 262 | 265 | 266 | 269 | 270 | 273 | 274 | 277 | 278 | 281 | 282 | 285 | 286 | 289 | 290 | 293 | 294 | 297 | 298 | 301 | 302 | 303 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 325 | 326 | 329 | 330 | 333 | 334 | 337 | 338 | 341 | 342 | 345 | 346 | 349 | 350 | 353 | 354 | 357 | 358 | 361 | 362 | 365 | 366 | 369 | 370 | 373 | 374 | 377 | 378 | 381 | 382 | 385 | 386 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | -------------------------------------------------------------------------------- /cpp/minizip/minizip.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@/minizip 5 | 6 | Name: minizip 7 | Description: Minizip zip file manipulation library 8 | Requires: 9 | Version: @PACKAGE_VERSION@ 10 | Libs: -L${libdir} -lminizip 11 | Libs.private: -lz 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /cpp/minizip/minizip.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{8D770B0A-A853-4FB7-8E71-5BDDC16A8C11}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{9C3AFF9E-022F-4A42-BCDC-C705AEE00DEB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8D770B0A-A853-4FB7-8E71-5BDDC16A8C11}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {8D770B0A-A853-4FB7-8E71-5BDDC16A8C11}.Debug|Win32.Build.0 = Debug|Win32 16 | {8D770B0A-A853-4FB7-8E71-5BDDC16A8C11}.Release|Win32.ActiveCfg = Release|Win32 17 | {8D770B0A-A853-4FB7-8E71-5BDDC16A8C11}.Release|Win32.Build.0 = Release|Win32 18 | {9C3AFF9E-022F-4A42-BCDC-C705AEE00DEB}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {9C3AFF9E-022F-4A42-BCDC-C705AEE00DEB}.Debug|Win32.Build.0 = Debug|Win32 20 | {9C3AFF9E-022F-4A42-BCDC-C705AEE00DEB}.Release|Win32.ActiveCfg = Release|Win32 21 | {9C3AFF9E-022F-4A42-BCDC-C705AEE00DEB}.Release|Win32.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /cpp/minizip/minizip.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 52 | 55 | 58 | 61 | 66 | 69 | 72 | 75 | 78 | 81 | 84 | 87 | 88 | 96 | 99 | 102 | 105 | 108 | 111 | 123 | 126 | 129 | 132 | 139 | 142 | 145 | 148 | 151 | 154 | 157 | 160 | 161 | 162 | 163 | 164 | 165 | 170 | 173 | 174 | 177 | 178 | 181 | 182 | 183 | 188 | 191 | 192 | 195 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 209 | 214 | 215 | 218 | 221 | 222 | 225 | 226 | 229 | 230 | 233 | 234 | 237 | 238 | 241 | 242 | 245 | 246 | 249 | 250 | 253 | 254 | 257 | 258 | 261 | 262 | 265 | 266 | 269 | 270 | 273 | 274 | 277 | 278 | 281 | 282 | 285 | 286 | 289 | 290 | 293 | 294 | 297 | 298 | 301 | 302 | 303 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 325 | 326 | 329 | 330 | 333 | 334 | 337 | 338 | 341 | 342 | 345 | 346 | 349 | 350 | 353 | 354 | 357 | 358 | 361 | 362 | 365 | 366 | 369 | 370 | 373 | 374 | 377 | 378 | 381 | 382 | 385 | 386 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | -------------------------------------------------------------------------------- /cpp/utils/Common.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | //------------------------------------------------------------------------ 4 | std::string get_root_dir() { 5 | char* root = getenv("CRAFT_BNN_ROOT"); 6 | if (!root) { 7 | fprintf(stderr, "Cannot find CRAFT_BNN_ROOT directory\n"); 8 | exit(-1); 9 | } 10 | return std::string(root); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /cpp/utils/Common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "Typedefs.h" 11 | 12 | // Returns the repo's root dir or exits 13 | std::string get_root_dir(); 14 | 15 | // We encode negative to -1, positive to 0 16 | template 17 | Bit sgn(const T x) { 18 | #pragma HLS INLINE 19 | return (x < 0) ? -1 : 0; 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /cpp/utils/DataIO.cpp: -------------------------------------------------------------------------------- 1 | #include "DataIO.h" 2 | 3 | 4 | Cifar10TestInputs::Cifar10TestInputs(unsigned n) 5 | : m_size(n*CHANNELS*ROWS*COLS) 6 | { 7 | data = new float[m_size]; // ML: data's type and size 8 | 9 | std::string full_filename = get_root_dir() + filename; 10 | DB_PRINT(2, "Opening data archive %s\n", full_filename.c_str()); 11 | unzFile ar = open_unzip(full_filename.c_str()); 12 | unsigned nfiles = get_nfiles_in_unzip(ar); 13 | assert(nfiles == 1); 14 | 15 | // We read m_size*4 bytes from the archive 16 | // ML: data stored in Inputs is 32 bits float 17 | unsigned fsize = get_current_file_size(ar); 18 | assert(m_size*4 <= fsize); 19 | 20 | DB_PRINT(2, "Reading %u bytes\n", m_size*4); 21 | read_current_file(ar, (void*)data, m_size*4); // ML: read the inputs to data 22 | 23 | unzClose(ar); 24 | } 25 | 26 | Cifar10TestLabels::Cifar10TestLabels(unsigned n) 27 | : m_size(n) 28 | { 29 | data = new float[m_size]; 30 | 31 | std::string full_filename = get_root_dir() + filename; 32 | DB_PRINT(2, "Opening data archive %s\n", full_filename.c_str()); 33 | unzFile ar = open_unzip(full_filename.c_str()); 34 | unsigned nfiles = get_nfiles_in_unzip(ar); 35 | assert(nfiles == 1); 36 | 37 | // We read n*4 bytes from the archive 38 | unsigned fsize = get_current_file_size(ar); 39 | assert(m_size*4 <= fsize); 40 | 41 | DB_PRINT(2, "Reading %u bytes\n", m_size*4); 42 | read_current_file(ar, (void*)data, m_size*4); 43 | unzClose(ar); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /cpp/utils/DataIO.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------ 2 | // Class to read the image data 3 | //------------------------------------------------------------------------ 4 | #include 5 | 6 | #include "Debug.h" 7 | #include "ZipIO.h" 8 | #include "Common.h" 9 | #include "SArray.h" 10 | 11 | // This class will load N cifar10 test images 12 | struct Cifar10TestInputs { 13 | static const unsigned CHANNELS=3; 14 | static const unsigned ROWS=32; 15 | static const unsigned COLS=32; 16 | static constexpr const char* filename = "/data/cifar10_test_inputs.zip"; 17 | 18 | float* data; 19 | unsigned m_size; 20 | 21 | Cifar10TestInputs(unsigned n); 22 | ~Cifar10TestInputs() { delete[] data; } 23 | unsigned size() { return m_size; } 24 | }; 25 | 26 | struct Cifar10TestLabels { 27 | static constexpr const char* filename = "/data/cifar10_test_labels.zip"; 28 | 29 | float* data; 30 | unsigned m_size; 31 | 32 | Cifar10TestLabels(unsigned n); 33 | ~Cifar10TestLabels() { delete[] data; } 34 | unsigned size() { return m_size; } 35 | }; 36 | -------------------------------------------------------------------------------- /cpp/utils/Debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_H 2 | #define DEBUG_H 3 | 4 | #ifndef DEBUG_LEVEL 5 | #define DEBUG_LEVEL 0 6 | #endif 7 | 8 | #ifdef HLS_COMPILE 9 | #undef DEBUG_LEVEL 10 | #endif 11 | 12 | #ifdef DEBUG_LEVEL 13 | 14 | #define DB(lvl, x) if (lvl <= DEBUG_LEVEL) {x;} 15 | #define DB_PRINT(lvl, ...) \ 16 | if (lvl <= DEBUG_LEVEL) \ 17 | printf (__VA_ARGS__) 18 | 19 | #else 20 | 21 | #define DB(lvl, x) 22 | #define DB_PRINT(lvl, ...) 23 | 24 | #endif 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /cpp/utils/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | # HDR are pure headers 4 | HDR=Debug.h BitVector.h QuantizeParams.h Layers.h Typedefs.h 5 | # OBJ must include a .cpp and .h with same name 6 | OBJ=DataIO.o ParamIO.o ZipIO.o Timer.o Common.o 7 | EXE=open_zip.exe 8 | ART=libCraftUtils.a 9 | 10 | all: $(ART) 11 | 12 | # Rule for object files, each object must have a header 13 | $(OBJ): %.o: %.cpp %.h 14 | $(CXX) -c $< -o $@ $(CFLAGS) 15 | 16 | %.o: %.cpp 17 | $(CXX) -c $< -o $@ $(CFLAGS) 18 | 19 | # Rule for executables 20 | $(EXE): %.exe: %.o $(OBJ) 21 | g++ $^ -o $@ $(CFLAGS) $(LDFLAGS) 22 | 23 | # Rule for libs 24 | $(ART): $(OBJ) 25 | $(AR) $@ $^ 26 | 27 | .PHONY: hlsclean 28 | clean: 29 | rm -f *.o *.exe *.a 30 | -------------------------------------------------------------------------------- /cpp/utils/ParamIO.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ParamIO.h" 4 | #include "ZipIO.h" 5 | #include "Common.h" 6 | 7 | Params::Params(std::string zipfile) 8 | : m_filename(zipfile), 9 | m_arrays(0) 10 | { 11 | // Open file 12 | DB_PRINT(2, "Opening params archive %s\n", m_filename.c_str()); 13 | unzFile ar = open_unzip(m_filename); 14 | 15 | // Get number of files in the archive 16 | m_arrays = get_nfiles_in_unzip(ar); 17 | DB_PRINT(2, "Number of param arrays: %u\n", m_arrays); 18 | assert(m_arrays <= MAX_LAYERS); 19 | 20 | // Read each array 21 | for (unsigned i = 0; i < m_arrays; ++i) { 22 | unsigned fsize = get_current_file_size(ar); 23 | m_array_size[i] = fsize; // size in bytes 24 | 25 | m_data[i] = new float[fsize/4]; 26 | read_current_file(ar, (void*)m_data[i], fsize); 27 | 28 | unzGoToNextFile(ar); 29 | } 30 | 31 | unzClose(ar); 32 | } 33 | 34 | Params::~Params() { 35 | for (unsigned i = 0; i < m_arrays; ++i) 36 | delete[] m_data[i]; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /cpp/utils/ParamIO.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------ 2 | // Class to read the parameters from a .zip archive. 3 | // Requires zlib and minizip. 4 | //------------------------------------------------------------------------ 5 | #ifndef PARAM_IO_H 6 | #define PARAM_IO_H 7 | 8 | #include 9 | #include 10 | #include "../minizip/unzip.h" 11 | #include "Debug.h" 12 | 13 | /* Parameters are organized into arrays. A layer may have multiple arrays of 14 | * params. For example Weight and Bias are two arrays for a Conv layer 15 | */ 16 | // ML: * case of batch normalizaion? 17 | struct Params { 18 | static const unsigned MAX_LAYERS = 64; // ML: actually it's the max array number 19 | 20 | std::string m_filename; 21 | unsigned m_arrays; 22 | unsigned m_array_size[MAX_LAYERS]; 23 | float* m_data[MAX_LAYERS]; 24 | 25 | public: 26 | // Read a zip archive containing NN params. We make the assumption 27 | // that each file in the archive is one array. The data is stored 28 | // as just an array of bytes 29 | Params(std::string zipfile); 30 | // Safely deletes params 31 | ~Params(); 32 | 33 | // Get the number of layers 34 | unsigned num_arrays() const { return m_arrays; } 35 | // Get the size of the params array in bytes 36 | unsigned array_size(unsigned i) const { 37 | return m_array_size[i]; 38 | } 39 | // Get a pointer to the params for layer 40 | float* array_data(unsigned i) const { 41 | return m_data[i]; 42 | } 43 | 44 | float* float_data(unsigned i) const { 45 | return array_data(i); 46 | } 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /cpp/utils/SArray.h: -------------------------------------------------------------------------------- 1 | #ifndef SARRAY_H 2 | #define SARRAY_H 3 | 4 | //------------------------------------------------------------------------ 5 | // Static array organized as N SxS images 6 | //------------------------------------------------------------------------ 7 | template 8 | struct SArray { 9 | typedef T ElemType; 10 | T data[SIZE]; 11 | 12 | static constexpr unsigned size() { return SIZE; } 13 | 14 | // get base ptr 15 | T* ptr() { return data; } 16 | const T* ptr() const { return data; } 17 | 18 | // array subscript 19 | T& operator[](unsigned i) { return data[i]; } 20 | const T& operator[](unsigned i) const { return data[i]; } 21 | 22 | void set(T x) { 23 | for (unsigned i = 0; i < size(); ++i) 24 | data[i] = x; 25 | } 26 | 27 | void clear() { 28 | set(0); 29 | } 30 | 31 | // copy data from another array or SArray 32 | template 33 | void copy_from(const A& other, unsigned siz=size()) { 34 | assert(siz <= size()); 35 | for (unsigned i = 0; i < siz; ++i) 36 | data[i] = other[i]; 37 | } 38 | 39 | // copy data and binarize 40 | template 41 | void binarize_from(const A& other, unsigned siz=size()) { 42 | assert(siz <= size()); 43 | for (unsigned i = 0; i < siz; ++i) 44 | data[i] = (other[i] >= 0) ? 0 : 1; 45 | } 46 | 47 | // print a subimage 48 | void print_sub(unsigned n, unsigned S, 49 | unsigned maxs=8, char fmt='f') const { 50 | maxs = (maxs >= S) ? S : maxs; 51 | assert(n*S*S < size()); 52 | for (unsigned r = 0; r < maxs; ++r) { 53 | for (unsigned c = 0; c < S; ++c) { 54 | if (fmt == 'f') 55 | printf ("%6.3f ", (float)data[n*S*S + r*S + c]); 56 | else 57 | printf ("%5d ", (int)data[n*S*S + r*S + c]); 58 | } 59 | printf ("\n"); 60 | } 61 | } 62 | 63 | // print an image 64 | void print(unsigned n=0, unsigned S=32, char fmt='f') const { 65 | print_sub(n, S, S, fmt); 66 | } 67 | 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /cpp/utils/Timer.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------- 2 | // Timer.cpp 3 | //--------------------------------------------------------- 4 | #include "Timer.h" 5 | 6 | #ifdef TIMER_ON 7 | //--------------------------------------------------------- 8 | // Timer is active 9 | //--------------------------------------------------------- 10 | 11 | Timer::Timer(const char* Name, bool On) { 12 | if (On) { 13 | // record the start time 14 | gettimeofday(&ts_start, NULL); 15 | nCalls = 1; 16 | } 17 | else { 18 | nCalls = 0; 19 | } 20 | totalTime = 0; 21 | strcpy(binName, Name); 22 | } 23 | 24 | Timer::~Timer() { 25 | // on being destroyed, print the average and total time 26 | if (nCalls > 0) { 27 | printf ("%-20s: ", binName); 28 | printf ("%6d calls; ", nCalls); 29 | if (totalTime < 1e-6) 30 | printf ("%6.3f usecs total time\n", 1e6*totalTime); 31 | else if (totalTime < 1e-3) 32 | printf ("%6.3f msecs total time\n", 1e3*totalTime); 33 | else 34 | printf ("%6.3f secs total time\n", totalTime); 35 | } 36 | } 37 | 38 | void Timer::start() { 39 | // record start time 40 | gettimeofday(&ts_start, NULL); 41 | nCalls++; 42 | } 43 | 44 | void Timer::stop() { 45 | // get current time, add elapsed time to totalTime 46 | timeval ts_curr; 47 | gettimeofday(&ts_curr, NULL); 48 | totalTime += float(ts_curr.tv_sec - ts_start.tv_sec) + 49 | float(ts_curr.tv_usec)*1e-6 - float(ts_start.tv_usec)*1e-6; 50 | } 51 | 52 | float Timer::get_time() { 53 | return totalTime; 54 | } 55 | 56 | #else 57 | //--------------------------------------------------------- 58 | // Timer turned off, methods do nothing 59 | //--------------------------------------------------------- 60 | Timer::Timer(const char* Name="", bool On=false) { 61 | } 62 | 63 | Timer::~Timer() { 64 | } 65 | 66 | void Timer::start() { 67 | } 68 | 69 | void Timer::stop() { 70 | } 71 | 72 | float Timer::get_time() { 73 | return 0; 74 | } 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /cpp/utils/Timer.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------- 2 | // Timer.h 3 | //--------------------------------------------------------- 4 | #ifndef __TIMER_H__ 5 | #define __TIMER_H__ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define TIMER_ON 12 | 13 | //--------------------------------------------------------- 14 | // Timer is an object which helps profile programs using 15 | // the clock() function. 16 | // - By default, a timer is stopped when you instantiate it 17 | // and must be started manually 18 | // - Passing True to the constructor starts the timer when 19 | // it is constructed 20 | // - When the timer is destructed it prints stats to stdout 21 | //--------------------------------------------------------- 22 | class Timer { 23 | 24 | #ifdef TIMER_ON 25 | 26 | char binName[50]; 27 | unsigned nCalls; 28 | timeval ts_start; 29 | float totalTime; 30 | 31 | #endif 32 | 33 | public: 34 | // constructor 35 | Timer(const char* Name="", bool On=false); 36 | // destructor 37 | ~Timer(); 38 | 39 | // start/stop timer 40 | void start(); 41 | void stop(); 42 | 43 | // returns time in seconds 44 | float get_time(); 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /cpp/utils/Typedefs.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEFS_H 2 | #define TYPEDEFS_H 3 | 4 | #include 5 | 6 | //#define USE_FLOAT 7 | 8 | #ifdef USE_FLOAT 9 | 10 | typedef float InputFixed; 11 | 12 | // Types for weights 13 | typedef ap_int<1> Bit; 14 | typedef ap_int<2> TwoBit; 15 | 16 | typedef float KType; 17 | typedef float HType; 18 | 19 | typedef float NormOutput; 20 | typedef ap_int<14> ConvOutput; 21 | 22 | #else 23 | 24 | // Quantized 32-bit input images in the range [-1,1] 25 | typedef ap_fixed<32,2, AP_RND> InputFixed; 26 | 27 | // Types for weights 28 | typedef ap_int<1> Bit; 29 | typedef ap_int<2> TwoBit; 30 | 31 | typedef ap_fixed<16,2> KType; 32 | typedef ap_fixed<16,4> HType; // ML: KType and HType are used in the last layer, where outputs are not binaried 33 | 34 | typedef ap_fixed<16,5> NormOutput; 35 | typedef ap_int<14> ConvOutput; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /cpp/utils/ZipIO.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ZipIO.h" 4 | #include "Debug.h" 5 | 6 | //------------------------------------------------------------------------ 7 | unzFile open_unzip(const std::string filename) { 8 | unzFile ar = unzOpen(filename.c_str()); 9 | if (ar == NULL) { 10 | fprintf(stderr, "Error opening %s\n", filename.c_str()); 11 | exit(-1); 12 | } 13 | return ar; 14 | 15 | } 16 | 17 | //------------------------------------------------------------------------ 18 | unsigned get_nfiles_in_unzip(unzFile ar) { 19 | unz_global_info info; 20 | int err = unzGetGlobalInfo(ar, &info); 21 | assert(!err); 22 | return info.number_entry; 23 | } 24 | 25 | //------------------------------------------------------------------------ 26 | unsigned get_current_file_size(unzFile ar) { 27 | unz_file_info finfo; 28 | char fname[50]; 29 | 30 | int err = unzGetCurrentFileInfo(ar, &finfo, fname, 50, NULL, 0, NULL, 0); 31 | assert(!err); 32 | unsigned fsize = finfo.uncompressed_size; 33 | 34 | DB_PRINT(3, "Reading %10s, %u bytes\n", fname, fsize); 35 | 36 | assert(fsize > 0); 37 | return fsize; 38 | } 39 | 40 | //------------------------------------------------------------------------ 41 | void read_current_file(unzFile ar, void* buffer, unsigned bytes) { 42 | int err = unzOpenCurrentFile(ar); 43 | assert(!err); 44 | 45 | unsigned b = unzReadCurrentFile(ar, buffer, bytes); 46 | assert(b == bytes); 47 | 48 | unzCloseCurrentFile(ar); 49 | } 50 | 51 | //------------------------------------------------------------------------ 52 | void write_buffer_to_zip(zipFile zf, std::string fname, void* buf, unsigned len) { 53 | int err; 54 | DB_PRINT(3, "Writing %10s, %u bytes\n", fname.c_str(), len); 55 | 56 | // Open new file 57 | zip_fileinfo zi = {0}; 58 | err = zipOpenNewFileInZip(zf, fname.c_str(), &zi, 59 | NULL, 0, NULL, 0, NULL, 60 | 0, /* method */ 61 | Z_DEFAULT_COMPRESSION); /* level */ 62 | assert(err == ZIP_OK); 63 | 64 | // Write data 65 | err = zipWriteInFileInZip(zf, buf, len); 66 | assert(err == ZIP_OK); 67 | 68 | // Close file 69 | err = zipCloseFileInZip(zf); 70 | assert(err == ZIP_OK); 71 | } 72 | 73 | -------------------------------------------------------------------------------- /cpp/utils/ZipIO.h: -------------------------------------------------------------------------------- 1 | #ifndef ZIP_IO_H 2 | #define ZIP_IO_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../minizip/zip.h" 8 | #include "../minizip/unzip.h" 9 | 10 | //------------------------------------------------------------------------ 11 | // Functions for reading a zip archive 12 | //------------------------------------------------------------------------ 13 | unzFile open_unzip(const std::string filename); 14 | unsigned get_nfiles_in_unzip(unzFile ar); 15 | unsigned get_current_file_size(unzFile ar); 16 | void read_current_file(unzFile ar, void* buffer, unsigned bytes); 17 | 18 | //------------------------------------------------------------------------ 19 | // Writes a buffer to a new file with name [fname] inside the 20 | // zip archive [zf]. 21 | //------------------------------------------------------------------------ 22 | void write_buffer_to_zip( 23 | zipFile zf, // zip archive handle 24 | std::string fname, // name of file instead archive to write 25 | void* buf, // buffer of data 26 | unsigned len // how many bytes to write 27 | ); 28 | 29 | //------------------------------------------------------------------------ 30 | // SArray to and from zipfile 31 | //------------------------------------------------------------------------ 32 | // Read zip archive to SArray, used when you know the archive contains 33 | // one array and it has an exact size 34 | template 35 | void unzip_to_sarray(std::string filename, Array &buf) { 36 | unzFile ar = open_unzip(filename); 37 | unsigned fsize = get_current_file_size(ar); 38 | assert(fsize == sizeof(buf.data)); 39 | 40 | read_current_file(ar, (void*)buf.ptr(), fsize); 41 | unzClose(ar); 42 | } 43 | 44 | // write an array to a zip archive containing one file 45 | template 46 | void sarray_to_zip(std::string filename, const Array &buf, unsigned n_elems=0) { 47 | zipFile ar = zipOpen(filename.c_str(), 0); 48 | n_elems = (n_elems == 0) ? Array::size() : n_elems; 49 | 50 | // copy the SArray data to an array of float 51 | float* data = new float[n_elems]; 52 | for (unsigned i = 0; i < n_elems; ++i) { 53 | data[i] = buf[i]; 54 | } 55 | 56 | // store the array of float 57 | write_buffer_to_zip(ar, "arr_0", (void*)data, n_elems*sizeof(float)); 58 | delete[] data; 59 | int err = zipClose(ar, NULL); 60 | assert(err == ZIP_OK); 61 | } 62 | 63 | //------------------------------------------------------------------------ 64 | // C Array to and from zipfile 65 | //------------------------------------------------------------------------ 66 | template 67 | void unzip_to_array(std::string filename, T buf[]) { 68 | unzFile ar = open_unzip(filename); 69 | unsigned fsize = get_current_file_size(ar); 70 | assert(fsize != 0 && fsize % 4 == 0); 71 | 72 | read_current_file(ar, (void*)buf, fsize); 73 | unzClose(ar); 74 | } 75 | 76 | template 77 | void bitarray_to_zip(std::string filename, T buf[], unsigned n_elems) { 78 | zipFile ar = zipOpen(filename.c_str(), 0); 79 | const unsigned elem_size = buf[0].length(); 80 | 81 | // copy the array data to an array of float 82 | float* data = new float[n_elems]; 83 | for (unsigned i = 0; i < n_elems; ++i) { 84 | data[i] = (buf[i/elem_size][i%elem_size] == 0) ? 1.0 : -1.0; 85 | } 86 | // store the array of float 87 | write_buffer_to_zip(ar, "arr_0", (void*)data, n_elems*sizeof(float)); 88 | delete[] data; 89 | int err = zipClose(ar, NULL); 90 | assert(err == ZIP_OK); 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /cpp/utils/open_zip.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------ 2 | // Simple test program for minizip, it checks the contents (files) in 3 | // a zip archive and reports the size of each file 4 | // Requires zlib and minizip. 5 | //------------------------------------------------------------------------ 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../minizip/unzip.h" 11 | 12 | int main(int argc, char** argv) { 13 | if (argc < 2) { 14 | printf("Usage: %s \n", argv[0]); 15 | return 0; 16 | } 17 | 18 | int err; 19 | 20 | // Open the zipfile 21 | // A "zipfile" means the zip archive, which can be a directory containing 22 | // many files. 23 | unzFile zipfile = unzOpen(argv[1]); 24 | if (zipfile == NULL) { 25 | printf("Could not open %s\n", argv[1]); 26 | return -1; 27 | } 28 | 29 | // Get the number of files (entries) inside 30 | unz_global_info info; 31 | err = unzGetGlobalInfo(zipfile, &info); 32 | assert (!err); 33 | unsigned entries = info.number_entry; 34 | printf ("Entries: %u\n", entries); 35 | 36 | float** data = new float*[entries]; 37 | 38 | for (unsigned i = 0; i < entries; ++i) { 39 | // Get some info on the file 40 | unz_file_info finfo; 41 | char filename[50]; 42 | err = unzGetCurrentFileInfo(zipfile, &finfo, filename, 50, NULL, 0, NULL, 0); 43 | assert (!err); 44 | printf (" File %s: size=%luKB, compsize=%luKB\n", filename, 45 | finfo.uncompressed_size>>10, finfo.compressed_size>>10); 46 | 47 | // The data is an array of floats packed into 4-byte chunks 48 | unsigned array_size = finfo.uncompressed_size/4; 49 | assert(finfo.uncompressed_size % 4 == 0); 50 | assert(array_size > 0); 51 | data[i] = new float[array_size]; 52 | 53 | // Read the data from the current file 4 bytes at a time, 54 | // convert the bytes to a float and store it 55 | unzOpenCurrentFile(zipfile); 56 | float f; 57 | 58 | for (unsigned j = 0; j < array_size; ++j) { 59 | // unzReadCurrentFile returns the number of bytes read 60 | // or 0 if end of file is reached 61 | err = unzReadCurrentFile(zipfile, (void*)&f, 4); 62 | assert((err == 4) || (j == array_size-1)); 63 | data[i][j] = f; 64 | 65 | if (j < 5) 66 | printf (" %5.2f", data[i][j]); 67 | } 68 | printf ("\n"); 69 | 70 | unzCloseCurrentFile(zipfile); 71 | unzGoToNextFile(zipfile); 72 | } 73 | 74 | unzClose(zipfile); 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /p15-zhao.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinLiAmoy/rnn-fpga/7f485719b87d1021a16944bba68c1d43c28ea794/p15-zhao.pdf -------------------------------------------------------------------------------- /params/rnn_parameters.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinLiAmoy/rnn-fpga/7f485719b87d1021a16944bba68c1d43c28ea794/params/rnn_parameters.zip -------------------------------------------------------------------------------- /settings64.sh: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # Copyright (c) 1986-2017 Xilinx, Inc. All rights reserved. # 3 | ############################################################## 4 | 5 | source /home/hang/Xilinx/SDx/2017.1/SDK/.settings64-Software_Development_Kit.sh 6 | source /home/hang/Xilinx/DocNav/.settings64-DocNav.sh 7 | source /home/hang/Xilinx/SDx/2017.1/.settings64-SDx.sh 8 | source /home/hang/Xilinx/SDx/2017.1/Vivado_HLS/.settings64-SDx_High_Level_Synthesis.sh 9 | source /home/hang/Xilinx/SDx/2017.1/Vivado/.settings64-Vivado.sh 10 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | export CRAFT_BNN_ROOT=$DIR 5 | --------------------------------------------------------------------------------