├── .gitignore ├── LICENSE ├── README.md ├── cpp ├── Makefile ├── Makefile.inc ├── accel │ ├── Accel.cpp │ ├── Accel.h │ ├── AccelPrint.cpp │ ├── AccelPrint.h │ ├── AccelSchedule.cpp │ ├── AccelSchedule.h │ ├── AccelTest.cpp │ ├── AccelTest.h │ ├── Dense.cpp │ ├── Dense.h │ ├── InputConv.cpp │ ├── InputConv.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 ├── data └── get_data.sh ├── params └── get_params.sh ├── python ├── in_memory_zip.py └── npz2zip.py └── setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc 3 | *.npz 4 | *.zip 5 | *.o 6 | *.a 7 | *.exe 8 | 9 | *.prj 10 | vivado_hls.log 11 | -------------------------------------------------------------------------------- /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 | Publications 2 | ------------------------------------------------------------------------ 3 | If you use this code in your research, please cite our [FPGA'17 paper][1]: 4 | ``` 5 | @article{zhao-bnn-fpga2017, 6 | title = "{Accelerating Binarized Convolutional Neural Networks 7 | with Software-Programmable FPGAs}", 8 | author = {Ritchie Zhao and Weinan Song and Wentao Zhang and Tianwei Xing and 9 | Jeng-Hau Lin and Mani Srivastava and Rajesh Gupta and Zhiru Zhang}, 10 | journal = {Int'l Symp. on Field-Programmable Gate Arrays (FPGA)}, 11 | month = {Feb}, 12 | year = {2017}, 13 | } 14 | ``` 15 | [1]: http://dx.doi.org/10.1145/3020078.3021741 16 | 17 | Introduction 18 | ------------------------------------------------------------------------ 19 | bnn-fpga is an open-source implementation of a binarized neural network (BNN) 20 | accelerator for CIFAR-10 on FPGA. 21 | The architecture and training of the BNN is proposed by [Courbarieaux et al.][2] 22 | and open-source Python code is available at https://github.com/MatthieuCourbariaux/BinaryNet. 23 | 24 | Our accelerator targets low-power embedded field-programmable SoCs and was 25 | tested on a Zedboard. At time of writing the error rate on the 10000 images 26 | in the CIFAR-10 test set is **11.19%**. 27 | 28 | [2]: https://arxiv.org/abs/1602.02830 29 | 30 | Build Setup 31 | ------------------------------------------------------------------------ 32 | You will need Xilinx SDSoC on your PATH and the Vivado HLS 33 | header include files on your CPATH. 34 | 35 | Verified SDSoC versions: 2016.4, 2017.1 36 | 37 | With these tools in place do the following from the repository root: 38 | ``` 39 | % source setup.sh 40 | % cd data; ./get_data.sh; cd .. 41 | % cd params; ./get_params.sh; cd .. 42 | ``` 43 | This will set environment variables and download data and parameter zip files. 44 | 45 | If the get scripts do not work, please go to this [Google Drive][3] to download 46 | the files that need to go into the **data** and **params** folders. 47 | 48 | [3]: https://drive.google.com/drive/folders/1QC2PP209d7mh2aXUJ3j433Ij7aHBNP0I?usp=sharing 49 | 50 | To build the software model: 51 | ``` 52 | % cd cpp 53 | % make -j4 54 | ``` 55 | 56 | To build the FPGA bitstream do (with the software build complete): 57 | ``` 58 | % cd cpp/accel/sdsoc_build 59 | % make -j4 60 | ``` 61 | Post-route timing and area information is available in 62 | **sdsoc_build/\_sds/reports/sds.rpt**. 63 | 64 | Branches 65 | ------------------------------------------------------------------------ 66 | The master branch contains a debug build including a random testbench, 67 | a per-layer testbench, and a full bnn testbench. The optimized branch 68 | contains only the full testbench. 69 | 70 | FPGA Evaluation 71 | ------------------------------------------------------------------------ 72 | 1. After the FPGA bitstream is finished building, copy the **sd_card** 73 | directory onto an SD card. 74 | 2. Copy both **data** and **params** directories onto the same SD card. 75 | 3. Insert the card into the Zedboard and power on the Zedboard. 76 | 4. Connect to the Zedboard via USB and wait for the boot sequence to finish. 77 | 5. At the terminal prompt do the following: 78 | ``` 79 | % cd mnt 80 | % export CRAFT_BNN_ROOT=. 81 | % ./accel_test_bnn.exe 82 | ``` 83 | Where N is the number of images you want to test. Up to 10000 images from 84 | the CIFAR-10 test set are available. The program will print out the 85 | prediction accuracy and accelerator runtime at the end. Note that the 86 | program performs weight binarization and reordering before invoking 87 | the accelerator so there will be a pause at the very beginning. 88 | 89 | Varying the Number of Convolvers 90 | ------------------------------------------------------------------------ 91 | Go to **cpp/accel/Accel.h** and change CONVOLVERS to the desired number 92 | (must be a power of 2). You must do a make clean and rebuild everything 93 | from scratch. 94 | 95 | Known Issues and Bugs 96 | ------------------------------------------------------------------------ 97 | 1. SDSoC compilation error due to glibc include file (Issue #1) \ 98 | This occurs if SDSoC sees the native version of glibc on CPATH, overriding the ARM version for cross-compilation. The fix is to remove /usr/include from CPATH. In some cases this prevents SDSoC from seeing zlib; currently the suggested fix is to build zlib in a different (non-system) directory and add that to CPATH. 99 | -------------------------------------------------------------------------------- /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 | const unsigned CONVOLVERS = 2; 26 | 27 | const unsigned WORD_SIZE = 64; 28 | const unsigned WT_SIZE = 9; 29 | const unsigned CONV_W_PER_WORD = 7; 30 | const unsigned CONV1_W_PER_WORD = 4; 31 | const unsigned KH_PER_WORD = 4; 32 | const unsigned BYTE_SIZE = 8; 33 | const unsigned K = 3; 34 | const unsigned WT_L = 16*4*512; // parameter to control wt mem size 35 | const unsigned C_WT_WORDS = ((WT_L+CONV_W_PER_WORD-1)/CONV_W_PER_WORD + CONVOLVERS-1) / CONVOLVERS; // wt words per convolver 36 | const unsigned WT_WORDS = C_WT_WORDS*CONVOLVERS; 37 | const unsigned KH_WORDS = WT_L/128*16 / WORD_SIZE; 38 | 39 | const unsigned DMEM_WORDS = 128*32*32 / WORD_SIZE; 40 | const unsigned C_DMEM_WORDS = DMEM_WORDS / CONVOLVERS; 41 | const unsigned DMEM_O_WORDS = 512*4*4 / WORD_SIZE; 42 | const unsigned DB_MEM_WORDS = 32*32; 43 | 44 | const unsigned PIX_PER_PHASE = 2*32*32; 45 | 46 | const unsigned MAX_WIDTH = WORD_SIZE; 47 | const unsigned BANK_WIDTH = 8; 48 | const unsigned LOG_BANK_WIDTH = 3; 49 | 50 | const unsigned CONV_ROWS = 3; 51 | const unsigned CONV_COLS = BANK_WIDTH+2; 52 | const unsigned CONV_BANKS = WORD_SIZE / BANK_WIDTH; 53 | 54 | //------------------------------------------------------------------- 55 | // Typedefs 56 | //------------------------------------------------------------------- 57 | enum LayerTypeEnum {LAYER_CONV1, LAYER_CONV, LAYER_DENSE, LAYER_LAST}; 58 | 59 | typedef ap_int Word; 60 | typedef ap_int WtType; 61 | typedef ap_uint<16> Address; 62 | typedef ap_int<12> ConvSum; 63 | typedef ap_int<5> ConvOut; 64 | typedef ap_uint<10> IdxType; 65 | typedef ap_fixed<16,4> C1Comp; 66 | typedef ap_int<16> NormComp; 67 | typedef ap_int<16> DenseSum; 68 | typedef ap_fixed<16,12> DenseNorm; 69 | 70 | typedef ap_fixed<20,2, AP_RND> C1InputType; 71 | typedef ap_fixed<24,6, AP_RND> C1ConvType; 72 | 73 | 74 | //------------------------------------------------------------------- 75 | // Template functions 76 | //------------------------------------------------------------------- 77 | template 78 | void load_kh(T& comp, const Word kh_mem[KH_WORDS], Address idx) { 79 | Word kh_word = kh_mem[idx/KH_PER_WORD]; 80 | IdxType off = idx % KH_PER_WORD; 81 | if (off == 0) 82 | comp(15,0) = kh_word(15, 0); 83 | else if (off == 1) 84 | comp(15,0) = kh_word(31,16); 85 | else if (off == 2) 86 | comp(15,0) = kh_word(47,32); 87 | else 88 | comp(15,0) = kh_word(63,48); 89 | } 90 | 91 | //------------------------------------------------------------------- 92 | // Accelerator synthesizable top-level function 93 | //------------------------------------------------------------------- 94 | #pragma SDS data copy(dmem_i[0:input_words], dmem_o[0:output_words]) 95 | #pragma SDS data access_pattern(dmem_i:SEQUENTIAL, dmem_o:SEQUENTIAL) 96 | #pragma SDS data access_pattern(wt_i:SEQUENTIAL, kh_i:SEQUENTIAL) 97 | #pragma SDS data mem_attribute(dmem_i:PHYSICAL_CONTIGUOUS, dmem_o:PHYSICAL_CONTIGUOUS) 98 | #pragma SDS data mem_attribute(wt_i:PHYSICAL_CONTIGUOUS, kh_i:PHYSICAL_CONTIGUOUS) 99 | #pragma SDS data data_mover(dmem_i:AXIDMA_SIMPLE, dmem_o:AXIDMA_SIMPLE) 100 | #pragma SDS data data_mover(wt_i:AXIDMA_SIMPLE, kh_i:AXIDMA_SIMPLE) 101 | void top( 102 | Word wt_i[WT_WORDS], 103 | Word kh_i[KH_WORDS], 104 | Word dmem_i[DMEM_WORDS], 105 | Word dmem_o[DMEM_O_WORDS], 106 | const Address n_inputs, 107 | const Address n_outputs, 108 | const Address input_words, 109 | const Address output_words, 110 | const ap_uint<3> layer_mode, // [0]='new layer', [2:1]='conv1,conv,dense' 111 | const ap_uint<1> dmem_mode, // 0 means dmem[0] is input 112 | const ap_uint<2> width_mode, // 0=8'b, 1=16'b, 2=32'b 113 | const ap_uint<2> norm_mode // 0='do nothing', 1='do norm', 2='do pool' 114 | ); 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /cpp/accel/AccelPrint.cpp: -------------------------------------------------------------------------------- 1 | #include "AccelPrint.h" 2 | 3 | void print_params3d(Word in[], unsigned M, unsigned num) { 4 | unsigned addr = M / CONV_W_PER_WORD; 5 | unsigned off = M % CONV_W_PER_WORD; 6 | for (unsigned n = M; n < M+num; ++n) { 7 | print_bits(in, addr*WORD_SIZE+off*WT_SIZE, 3, 3, 3); 8 | printf ("--%u--\n", n+1); 9 | if (++off == CONV_W_PER_WORD) { 10 | off = 0; 11 | addr++; 12 | } 13 | } 14 | } 15 | 16 | void print_wt_word(const Word& in) { 17 | assert(K*K == WT_SIZE); 18 | for (unsigned i = 0; i < CONV_W_PER_WORD; ++i) { 19 | for (unsigned r = 0; r < K; ++r) { 20 | for (unsigned c = 0; c < K; ++c) { 21 | printf ("%3d", in[i*WT_SIZE + r*K + c] == 0 ? 0 : 1); 22 | } 23 | printf ("\n"); 24 | } 25 | printf ("--%u/%u--\n", i+1, CONV_W_PER_WORD); 26 | } 27 | } 28 | 29 | void print_wt(const WtType& in) { 30 | for (unsigned r = 0; r < K; ++r) { 31 | for (unsigned c = 0; c < K; ++c) { 32 | printf ("%3d", in[r*K + c] == 0 ? 0 : 1); 33 | } 34 | printf ("\n"); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /cpp/accel/AccelPrint.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_PRINT_H 2 | #define ACCEL_PRINT_H 3 | 4 | #include "Accel.h" 5 | #include 6 | 7 | //------------------------------------------------------------------------ 8 | // For an array of ap_int's, sets/gets the bit at bit_idx 9 | // calculated from the start of the array to val 10 | //------------------------------------------------------------------------ 11 | template 12 | inline void set_bit(T array[], unsigned bit_idx, Bit val) { 13 | unsigned W = array[0].length(); 14 | Address idx = bit_idx / W; 15 | Address offset = bit_idx % W; 16 | array[idx][offset] = val; 17 | } 18 | 19 | template 20 | inline Bit get_bit(T array[], unsigned bit_idx) { 21 | unsigned W = array[0].length(); 22 | Address idx = bit_idx / W; 23 | Address offset = bit_idx % W; 24 | Bit result = array[idx][offset]; 25 | return result; 26 | } 27 | 28 | //------------------------------------------------------------------------ 29 | // Printing matrices and bit arrays 30 | //------------------------------------------------------------------------ 31 | template 32 | void print_mat(T in[], unsigned S, unsigned R, unsigned C) { 33 | R = (R >= S) ? S : R; 34 | C = (C >= S) ? S : C; 35 | for (unsigned r = 0; r < R; ++r) { 36 | for (unsigned c = 0; c < C; ++c) 37 | std::cout << std::setw(4) << in[r*S+c] << " "; 38 | printf ("\n"); 39 | } 40 | } 41 | 42 | template 43 | void print_mat3d(T in[], unsigned M, unsigned num, unsigned S, unsigned R, unsigned C) { 44 | for (unsigned m = M; m < M+num; ++m) { 45 | print_mat(in+m*S*S, S, R, C); 46 | printf ("--%u--\n", m+1); 47 | } 48 | } 49 | 50 | template 51 | void print_bits(T in[], unsigned bit_offset, unsigned S, unsigned R, unsigned C) { 52 | R = (R >= S) ? S : R; 53 | C = (C >= S) ? S : C; 54 | for (unsigned r = 0; r < R; ++r) { 55 | for (unsigned c = 0; c < C; ++c) 56 | std::cout << std::setw(2) << get_bit(in, bit_offset+r*S+c) << " "; 57 | printf ("\n"); 58 | } 59 | } 60 | 61 | template 62 | void print_bits3d(T in[], unsigned M, unsigned num, unsigned S, unsigned R, unsigned C) { 63 | for (unsigned m = M; m < M+num; ++m) { 64 | print_bits(in, m*S*S, S, R, C); 65 | printf ("--%u--\n", m+1); 66 | } 67 | } 68 | 69 | void print_params3d(Word in[], unsigned M, unsigned num); 70 | void print_wt_word(const Word& in); 71 | void print_wt(const WtType& in); 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /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* kh; 12 | unsigned n_inputs; 13 | unsigned n_outputs; 14 | ap_uint<3> layer_mode; // [0]='new layer', [2:1]='conv1,conv,dense' 15 | ap_uint<2> width_mode; // 0=8'b, 1=16'b, 2=32'b 16 | ap_uint<2> norm_mode; // 0='do nothing', 1='do norm', 2='do pool' 17 | 18 | AccelInfo() { 19 | wt = new Word[WT_WORDS]; 20 | kh = new Word[KH_WORDS]; 21 | } 22 | 23 | ~AccelInfo() { 24 | delete[] wt; 25 | delete[] kh; 26 | } 27 | }; 28 | 29 | typedef std::vector AccelSchedule; 30 | 31 | void compute_accel_schedule( 32 | Word* wt, 33 | Word* kh, 34 | unsigned n_inputs, 35 | unsigned n_outputs, 36 | unsigned width, 37 | const ap_uint<2> layer_type, // 0=conv1, 1=conv, 2=dense 38 | const ap_uint<1> max_pool, 39 | AccelSchedule &schedule 40 | ); 41 | 42 | void run_accel_schedule( 43 | Word* data_i, 44 | Word* data_o, 45 | unsigned layer_idx, 46 | unsigned input_words, 47 | unsigned output_words, 48 | ap_uint<1> dmem_mode, 49 | AccelSchedule& s 50 | ); 51 | 52 | void load_conv1_weights(Word* wt, Word* wt_o, 53 | unsigned o, unsigned n_out); 54 | void load_conv_weights(Word* wt, Word* wt_o, 55 | unsigned o, unsigned n_in, unsigned n_out); 56 | void load_dense_weights(Word* wt, Word* wt_o, 57 | unsigned o, unsigned n_in, unsigned n_out); 58 | 59 | void load_kh(Word* kh, Word* kh_mem, unsigned o, unsigned n_imgs); 60 | 61 | unsigned find_conv_batch_size(unsigned width, unsigned width_o, 62 | unsigned n_inputs, unsigned n_outputs); 63 | unsigned find_dense_batch_size(unsigned n_inputs, unsigned n_outputs); 64 | 65 | float total_time(); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /cpp/accel/AccelTest.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_ACCEL_TEST_H 2 | #define ACCEL_ACCEL_TEST_H 3 | 4 | #include "Typedefs.h" 5 | #include "Accel.h" 6 | #include "AccelPrint.h" 7 | #include 8 | 9 | const unsigned N_LAYERS = 9; 10 | const unsigned L_CONV = 6; 11 | const unsigned S_tab[] = { 32, 32, 16, 16, 8, 8, 4, 1, 1, 1}; 12 | const unsigned M_tab[] = { 3, 128, 128, 256, 256, 512, 8192, 1024, 1024}; 13 | const unsigned N_tab[] = {128, 128, 256, 256, 512, 512, 1024, 1024, 10}; 14 | const unsigned T_tab[] = { 0, 1, 1, 1, 1, 1, 2, 2, 3}; 15 | const unsigned widx_tab[] = {0, 3, 6, 9, 12, 15, 18, 21, 24}; 16 | const unsigned kidx_tab[] = {1, 4, 7, 10, 13, 16, 19, 22, 25}; 17 | const unsigned hidx_tab[] = {2, 5, 8, 11, 14, 17, 20, 23, 26}; 18 | const unsigned pool_tab[] = {0, 1, 0, 1, 0, 1, 0, 0, 0}; 19 | 20 | // layer_idx goes from 1 to 9 21 | bool layer_is_conv(unsigned layer_idx); 22 | bool layer_is_binconv(unsigned layer_idx); 23 | bool layer_is_fpconv(unsigned layer_idx); 24 | bool layer_is_last(unsigned layer_idx); 25 | bool layer_wt_size(unsigned layer_idx); 26 | bool layer_kh_size(unsigned layer_idx); 27 | 28 | // number of Words allocated to store n weights 29 | unsigned WTS_TO_WORDS(const unsigned n); 30 | // Simple log function, only works for powers of 2 31 | unsigned log2(unsigned x); 32 | 33 | //------------------------------------------------------------------------ 34 | // Set an array of ap_int's using some data, used to binarize test 35 | // inputs and outputs 36 | //------------------------------------------------------------------------ 37 | template 38 | void set_bit_array(T1 array[], const T2* data, unsigned size) { 39 | for (unsigned i = 0; i < size; ++i) { 40 | set_bit(array, i, (data[i]>=0) ? Bit(0) : Bit(-1)); 41 | } 42 | } 43 | 44 | //------------------------------------------------------------------------ 45 | // Functions used to preprocess params and inputs 46 | //------------------------------------------------------------------------ 47 | void set_weight_array(Word* w, const float* wts, unsigned layer_idx); 48 | void set_conv_weight_array(Word* w, const float* wts, unsigned size); 49 | void set_dense_weight_array(Word* w, const float* wts, unsigned M, unsigned N); 50 | 51 | void set_bnorm_array(Word* kh, const float* k, const float* h, unsigned layer_idx); 52 | void set_bnorm_array1(Word* kh, const float* k, const float* h, unsigned layer_idx, unsigned N); 53 | void set_bnorm_array2(Word* kh, const float* k, const float* h, unsigned N); 54 | 55 | void binarize_input_images(Word* dmem_i, const float* inputs, unsigned S); 56 | 57 | //------------------------------------------------------------------------ 58 | // Padded convolution (used for golden reference) 59 | //------------------------------------------------------------------------ 60 | void padded_conv(Word in[], Word w[], Word out[], unsigned M, unsigned S); 61 | 62 | //------------------------------------------------------------------------ 63 | // Helper test function for the accelerator 64 | // This function calls the accelerator, then runs a check of the results 65 | // against conv_ref (if not NULL) and bin_ref. 66 | //------------------------------------------------------------------------ 67 | void test_conv_layer( 68 | Word* weights, 69 | Word* kh, 70 | Word* data_i, 71 | Word* data_o, 72 | Word* conv_ref, 73 | Word* bin_ref, 74 | const unsigned M, 75 | const unsigned N, 76 | const unsigned S, 77 | const ap_uint<1> conv_mode=1, 78 | const ap_uint<1> max_pool=0 79 | ); 80 | 81 | void test_dense_layer( 82 | Word* weights, 83 | Word* kh, 84 | Word* data_i, 85 | Word* data_o, 86 | Word* bin_ref, 87 | const unsigned M, // pixels 88 | const unsigned N // pixels 89 | ); 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /cpp/accel/Dense.cpp: -------------------------------------------------------------------------------- 1 | #include "Dense.h" 2 | #include "Timer.h" 3 | 4 | const static Word m1("0x5555555555555555", 16); 5 | const static Word m2("0x3333333333333333", 16); 6 | const static Word m4("0x0f0f0f0f0f0f0f0f", 16); 7 | const static Word h01("0x0101010101010101", 16); 8 | static Timer t_dense("dense"); 9 | static Timer t_last ("last"); 10 | 11 | // ----------------------------------------------------------------------- 12 | // Performs dense dot product on M input bits, n*M is the weight offset 13 | // ----------------------------------------------------------------------- 14 | int dotproduct_m( 15 | const Word* in, 16 | const Word* w, 17 | const unsigned M, 18 | const unsigned n 19 | ) { 20 | assert (M % WORD_SIZE == 0); 21 | int sum = 0; 22 | 23 | // Loop across in the inputs in batches of WORD_SIZE 24 | for (unsigned m = 0; m < M; m+=WORD_SIZE) { 25 | const Word in_wrd = in[m/WORD_SIZE]; 26 | const Word wt_wrd = w[(n*M+m)/WORD_SIZE]; 27 | 28 | Word x = wt_wrd ^ in_wrd; 29 | 30 | // count_set bit for 64 bits, returns 2*cnt 31 | x -= (x >> 1) & m1; 32 | x = (x & m2) + ((x >> 2) & m2); 33 | x = (x + (x >> 4)) & m4; 34 | x += x >> 8; 35 | x += x >> 16; 36 | x += x >> 32; 37 | x = x & 0x7f; 38 | 39 | sum += WORD_SIZE - (x<<1).to_int(); 40 | } 41 | return sum; 42 | } 43 | 44 | // ----------------------------------------------------------------------- 45 | // Internal dense layer 46 | // ----------------------------------------------------------------------- 47 | void dense_layer_cpu( 48 | const Word* wt, 49 | const float* k_data, 50 | const float* h_data, 51 | const Word* in, 52 | Word* out, 53 | const unsigned M, 54 | const unsigned N 55 | ) { 56 | t_dense.start(); 57 | 58 | for (unsigned n = 0; n < N; n+=WORD_SIZE) { 59 | Word out_wrd = 0; 60 | for (unsigned nb = 0; nb < WORD_SIZE; ++nb) { 61 | int sum = dotproduct_m(in, wt, M, n+nb); 62 | float res = static_cast(sum) * k_data[n+nb] + h_data[n+nb]; 63 | if (res < 0) 64 | out_wrd[nb] = 1; 65 | } 66 | out[n/WORD_SIZE] = out_wrd; 67 | } 68 | 69 | t_dense.stop(); 70 | } 71 | 72 | // ----------------------------------------------------------------------- 73 | // Final dense layer 74 | // ----------------------------------------------------------------------- 75 | int last_layer_cpu( 76 | const Word* wt, 77 | const float* k_data, 78 | const float* h_data, 79 | const Word* in, 80 | const unsigned M, 81 | const unsigned N 82 | ) { 83 | t_last.start(); 84 | 85 | int pred = -1; 86 | float maxval = 0; 87 | 88 | for (unsigned n = 0; n < N; ++n) { 89 | int sum = dotproduct_m(in, wt, M, n); 90 | float val = static_cast(sum) * k_data[n] + h_data[n]; 91 | if (pred == -1 || val > maxval) { 92 | pred = n; 93 | maxval = val; 94 | } 95 | } 96 | 97 | t_last.stop(); 98 | return pred; 99 | } 100 | -------------------------------------------------------------------------------- /cpp/accel/Dense.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_DENSE_H 2 | #define ACCEL_DENSE_H 3 | 4 | #include "Debug.h" 5 | #include "Typedefs.h" 6 | #include "Accel.h" 7 | 8 | void dense_layer_cpu( 9 | const Word* w, 10 | const float* k_data, 11 | const float* h_data, 12 | const Word* data_i, 13 | Word* data_o, 14 | const unsigned M, 15 | const unsigned N 16 | ); 17 | 18 | int last_layer_cpu( 19 | const Word* w, 20 | const float* k_data, 21 | const float* h_data, 22 | const Word* in, 23 | const unsigned M, 24 | const unsigned N 25 | ); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /cpp/accel/InputConv.cpp: -------------------------------------------------------------------------------- 1 | #include "InputConv.h" 2 | #include "AccelTest.h" 3 | #include "Timer.h" 4 | 5 | void run_input_conv_layer( 6 | const float* w_data, 7 | const float* k_data, 8 | const float* h_data, 9 | const float* data_i, 10 | Word* data_o, 11 | const unsigned M, 12 | const unsigned N 13 | ) { 14 | const unsigned S = 32; 15 | 16 | std::vector w; 17 | w.reserve(M*N*K*K); 18 | for (unsigned i = 0; i < M*N*K*K; ++i) { 19 | w[i] = (w_data[i] >= 0) ? false : true; 20 | } 21 | 22 | float conv_buffer[S*S]; 23 | float in_buffer[(S+2)*(S+2)]; 24 | 25 | // ------------------------------------------ 26 | // assign 0 to the boundaries 27 | // ------------------------------------------ 28 | for (unsigned c = 0; c < S+2; ++c) 29 | in_buffer[c] = 0; 30 | for (unsigned r = 1; r < S+1; ++r) { 31 | in_buffer[r*(S+2) + 0] = 0; 32 | in_buffer[r*(S+2) + S+1] = 0; 33 | } 34 | for (unsigned c = 0; c < S+2; ++c) 35 | in_buffer[(S+1)*(S+2) + c] = 0; 36 | 37 | static Timer t_conv1("conv1"); 38 | t_conv1.start(); 39 | 40 | // ------------------------------------------ 41 | // Main conv loop 42 | // ------------------------------------------ 43 | for (unsigned n = 0; n < N; ++n) { 44 | // clear conv_buffer 45 | for (unsigned i = 0; i < S*S; ++i) { 46 | conv_buffer[i] = 0; 47 | } 48 | 49 | // Loop over all input images 50 | for (unsigned m = 0; m < M; ++m) { 51 | const unsigned w_n = n*M + m; 52 | 53 | // copy input 54 | for (unsigned r = 1; r < S+1; ++r) { 55 | for (unsigned c = 1; c < S+1; ++c) { 56 | in_buffer[r*(S+2) + c] = data_i[m*S*S + (r-1)*S + (c-1)]; 57 | } } 58 | 59 | // operate on 1 input image 60 | for (int r = 0; r < S; ++r) { 61 | for (int c = 0; c < S; ++c) { 62 | float res = 0; 63 | 64 | // perform convolution 65 | for (int kr = 0; kr < K; ++kr) { 66 | for (int kc = 0; kc < K; ++kc) { 67 | float pix = in_buffer[(r+kr)*(S+2) + (c+kc)]; 68 | const bool b = w[w_n*K*K + (8-(kr*K+kc))]; 69 | res += (b==0) ? pix : -pix; 70 | } } // kr,kc 71 | 72 | conv_buffer[r*S + c] += res; 73 | } } // r,c of input img 74 | } // m 75 | 76 | // perform batch-norm 77 | for (unsigned i = 0; i < S*S; i+=WORD_SIZE) { 78 | Word out_wrd = 0; 79 | for (unsigned b = 0; b < WORD_SIZE; ++b) { 80 | float x = static_cast(conv_buffer[i+b]); 81 | x = x * k_data[n] + h_data[n]; 82 | out_wrd[b] = (x >= 0) ? 0 : 1; 83 | } 84 | data_o[(n*S*S + i)/WORD_SIZE] = out_wrd; 85 | } 86 | } // n 87 | 88 | t_conv1.stop(); 89 | } 90 | -------------------------------------------------------------------------------- /cpp/accel/InputConv.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEL_INPUT_CONV_H 2 | #define ACCEL_INPUT_CONV_H 3 | 4 | #include "Typedefs.h" 5 | #include "Accel.h" 6 | 7 | void run_input_conv_layer( 8 | const float* w_data, 9 | const float* k_data, 10 | const float* h_data, 11 | const float* data_i, 12 | Word* data_o, 13 | const unsigned M, 14 | const unsigned N 15 | ); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /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 AccelPrint.o Dense.o InputConv.o 10 | EXE=accel_test_bnn.exe accel_test_layer.exe accel_test_random.exe 11 | 12 | all: $(EXE) 13 | 14 | # Rule for object files, each object must have a header 15 | $(OBJ): %.o: %.cpp %.h 16 | $(CXX) -c $< -o $@ $(CFLAGS) 17 | 18 | %.o: %.cpp 19 | $(CXX) -c $< -o $@ $(CFLAGS) 20 | 21 | # Rule for executables 22 | $(EXE): %.exe: %.o $(OBJ) 23 | g++ $^ -o $@ $(CFLAGS) $(LDFLAGS) 24 | 25 | .PHONY: hls clean hlsclean 26 | hls: 27 | vivado_hls hls.tcl 28 | 29 | hlsclean: 30 | rm -rf hls.prj vivado_hls.log 31 | 32 | clean: hlsclean 33 | rm -f *.o *.exe 34 | -------------------------------------------------------------------------------- /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 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 images to test as 1st arg\n"); 17 | return 0; 18 | } 19 | const unsigned n_imgs = std::stoi(argv[1]); 20 | 21 | const unsigned lconv = 6; // last conv 22 | const unsigned ldense = 8; // last dense 23 | const bool DENSE_LAYER_CPU = getenv("BNN_DENSE_LAYER_CPU") != NULL; 24 | const bool LAST_LAYER_CPU = getenv("BNN_LAST_LAYER_CPU") != NULL; 25 | if (DENSE_LAYER_CPU) 26 | printf ("## Dense layer CPU is turned on ##\n"); 27 | if (LAST_LAYER_CPU) 28 | printf ("## Last layer CPU is turned on ##\n"); 29 | 30 | // print some config numbers 31 | printf ("* WT_WORDS = %u\n", WT_WORDS); 32 | printf ("* KH_WORDS = %u\n", KH_WORDS); 33 | 34 | // Load input data 35 | printf ("## Loading input data ##\n"); 36 | Cifar10TestInputs X(n_imgs); 37 | Cifar10TestLabels y(n_imgs); 38 | 39 | // Load parameters 40 | printf ("## Loading parameters ##\n"); 41 | Params params(get_root_dir() + "/params/cifar10_parameters_nb.zip"); 42 | 43 | // --------------------------------------------------------------------- 44 | // allocate and binarize all weights 45 | // --------------------------------------------------------------------- 46 | Word* wt[N_LAYERS]; 47 | Word* kh[N_LAYERS]; 48 | for (unsigned l = 0; l < N_LAYERS; ++l) { 49 | const unsigned M = M_tab[l]; 50 | const unsigned N = N_tab[l]; 51 | if (layer_is_conv(l+1)) 52 | wt[l] = new Word[WTS_TO_WORDS(M*N)]; 53 | else 54 | wt[l] = new Word[M*N / WORD_SIZE]; 55 | const float* weights = params.float_data(widx_tab[l]); 56 | set_weight_array(wt[l], weights, l+1); 57 | 58 | kh[l] = new Word[N/KH_PER_WORD * sizeof(Word)]; 59 | const float* k = params.float_data(kidx_tab[l]); 60 | const float* h = params.float_data(hidx_tab[l]); 61 | set_bnorm_array(kh[l], k, h, l+1); 62 | } 63 | 64 | // --------------------------------------------------------------------- 65 | // // compute accelerator schedule (divides up weights) 66 | // --------------------------------------------------------------------- 67 | AccelSchedule layer_sched[N_LAYERS]; 68 | for (unsigned l = 0; l < N_LAYERS; ++l) { 69 | compute_accel_schedule( 70 | wt[l], kh[l], 71 | M_tab[l], N_tab[l], S_tab[l], T_tab[l], pool_tab[l], 72 | layer_sched[l] 73 | ); 74 | } 75 | 76 | // allocate memories for data i/o for the accelerator 77 | Word* data_i = (Word*) MEM_ALLOC( DMEM_WORDS * sizeof(Word) ); 78 | Word* data_o = (Word*) MEM_ALLOC( DMEM_O_WORDS * sizeof(Word) ); 79 | if (!data_i || !data_o) { 80 | fprintf (stderr, "**** ERROR: Alloc failed in %s\n", __FILE__); 81 | return (-2); 82 | } 83 | 84 | unsigned n_errors = 0; 85 | 86 | printf ("## Running BNN for %d images\n", n_imgs); 87 | 88 | //-------------------------------------------------------------- 89 | // Run BNN 90 | //-------------------------------------------------------------- 91 | for (unsigned n = 0; n < n_imgs; ++n) { 92 | float* data = X.data + n*3*32*32; 93 | binarize_input_images(data_i, data, 32); 94 | 95 | //------------------------------------------------------------ 96 | // Execute conv layers 97 | //------------------------------------------------------------ 98 | for (unsigned l = 1; l <= lconv; ++l) { 99 | const unsigned M = M_tab[l-1]; 100 | const unsigned N = N_tab[l-1]; 101 | const unsigned S = S_tab[l-1]; 102 | unsigned input_words = (l==1) ? S*S : M*S*S/WORD_SIZE; 103 | unsigned output_words = (pool_tab[l-1]) ? N*S*S/WORD_SIZE/4 : N*S*S/WORD_SIZE; 104 | 105 | run_accel_schedule( 106 | data_i, data_o, 107 | l-1, // layer_idx 108 | (l==1) ? input_words : 0, 109 | (l==lconv && DENSE_LAYER_CPU) ? output_words : 0, 110 | l % 2, // mem_mode 111 | layer_sched[l-1] 112 | ); 113 | } 114 | 115 | //------------------------------------------------------------ 116 | // Execute dense layers 117 | //------------------------------------------------------------ 118 | for (unsigned l = lconv+1; l <= ldense; ++l) { 119 | const unsigned M = M_tab[l-1]; 120 | const unsigned N = N_tab[l-1]; 121 | 122 | if (DENSE_LAYER_CPU) { 123 | for (unsigned i = 0; i < M/WORD_SIZE; ++i) 124 | data_i[i] = data_o[i]; 125 | 126 | dense_layer_cpu( 127 | wt[l-1], params.float_data(3*l-2), params.float_data(3*l-1), 128 | data_i, data_o, M, N 129 | ); 130 | 131 | } else { 132 | run_accel_schedule( 133 | data_i, data_o, 134 | l-1, 135 | 0, // input_words 136 | (l==ldense && LAST_LAYER_CPU) ? 1024/WORD_SIZE : 0, 137 | l % 2, 138 | layer_sched[l-1] 139 | ); 140 | } 141 | } 142 | 143 | //------------------------------------------------------------ 144 | // Execute last layer 145 | //------------------------------------------------------------ 146 | int prediction = -1; 147 | if (DENSE_LAYER_CPU || LAST_LAYER_CPU) { 148 | prediction = last_layer_cpu( 149 | wt[ldense], 150 | params.float_data(kidx_tab[ldense]), 151 | params.float_data(hidx_tab[ldense]), 152 | data_o, 153 | M_tab[ldense], N_tab[ldense] 154 | ); 155 | } else { 156 | run_accel_schedule( 157 | data_i, data_o, 158 | ldense, 159 | 0, 1, 160 | 1, 161 | layer_sched[ldense] 162 | ); 163 | ap_int<8> p = 0; 164 | p(7,0) = data_o[0](7,0); 165 | prediction = p.to_int(); 166 | } 167 | 168 | //assert(prediction >= 0 && prediction <= 9); 169 | int label = y.data[n]; 170 | 171 | printf (" Pred/Label:\t%2u/%2d\t[%s]\n", prediction, label, 172 | ((prediction==label)?" OK ":"FAIL")); 173 | 174 | n_errors += (prediction!=label); 175 | } 176 | 177 | printf ("\n"); 178 | printf ("Errors: %u (%4.2f%%)\n", n_errors, float(n_errors)*100/n_imgs); 179 | printf ("\n"); 180 | printf ("Total accel runtime = %10.4f seconds\n", total_time()); 181 | printf ("\n"); 182 | 183 | MEM_FREE( data_o ); 184 | MEM_FREE( data_i ); 185 | for (unsigned n = 0; n < N_LAYERS; ++n) { 186 | delete[] wt[n]; 187 | delete[] kh[n]; 188 | } 189 | return 0; 190 | } 191 | -------------------------------------------------------------------------------- /cpp/accel/accel_test_layer.cpp: -------------------------------------------------------------------------------- 1 | #include 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_inline conv3x3b 5 | set_directive_inline encode_bit 6 | #set_directive_inline conv_word 7 | set_directive_inline process_word 8 | #set_directive_inline bin_conv 9 | #set_directive_inline fp_conv 10 | #set_directive_inline bin_dense 11 | 12 | set_directive_pipeline conv_word 13 | set_directive_pipeline top/LOOP_DMEM_I 14 | set_directive_pipeline top/LOOP_DMEM_O 15 | set_directive_pipeline top/LOOP_WT_I 16 | set_directive_pipeline top/LOOP_KH_I 17 | 18 | set_directive_loop_tripcount -min 1 -max 512 top/LOOP_DMEM_I 19 | set_directive_loop_tripcount -min 1 -max 1 top/LOOP_DMEM_O 20 | set_directive_loop_tripcount -min 1 -max 1 top/LOOP_IMG_BATCH 21 | set_directive_loop_tripcount -min 1 -max 512 bin_conv/LOOP_PHASES 22 | 23 | # bin_conv/LOOP_WORDS_IN_PHASE 24 | set_directive_pipeline bin_conv/LOOP_WORDS_IN_PHASE 25 | set_directive_loop_tripcount -min 17 -max 32 bin_conv/LOOP_WORDS_IN_PHASE 26 | set_directive_dependence -variable fixed_buffer -type inter -dependent false bin_conv/LOOP_WORDS_IN_PHASE 27 | # bin_conv/LOOP_ACC_PHASES 28 | set_directive_loop_tripcount -min 1 -max 1 bin_conv/LOOP_ACC_PHASES 29 | set_directive_pipeline bin_conv/LOOP_ACC_PHASES_I 30 | set_directive_loop_tripcount -min 1 -max 16 bin_conv/LOOP_ACC_PHASES_I 31 | # bin_conv/LOOP_BATCH_NORM 32 | set_directive_pipeline bin_conv/LOOP_BATCH_NORM 33 | set_directive_loop_tripcount -min 1 -max 16 bin_conv/LOOP_BATCH_NORM 34 | # bin_conv/LOOP_POOL_NORM 35 | set_directive_pipeline bin_conv/LOOP_POOL_NORM 36 | set_directive_loop_tripcount -min 1 -max 16 bin_conv/LOOP_POOL_NORM 37 | 38 | # fp_conv/LOOP_FP_CONV_O 39 | set_directive_loop_tripcount -min 1 -max 32 fp_conv/LOOP_FP_CONV_O 40 | # fp_conv/LOOP_RESET_LINEBUFFERS 41 | set_directive_unroll fp_conv/LOOP_RESET_LINEBUFFERS 42 | set_directive_unroll -region fp_conv/LOOP_RESET_LINEBUFFERS 43 | # fp_conv/LOOP_LOAD_WTS 44 | set_directive_unroll fp_conv/LOOP_LOAD_WTS 45 | # fp_conv/LOOP_CONV_COLS 46 | set_directive_pipeline fp_conv/LOOP_CONV_COLS 47 | # fp_conv/LOOP_OUTPUT 48 | set_directive_pipeline fp_conv/LOOP_OUTPUT 49 | 50 | # bin_dense/LOOP_DENSE_I 51 | set_directive_pipeline bin_dense/LOOP_DENSE_I 52 | set_directive_loop_tripcount -min 1 -max 1 bin_dense/LOOP_DENSE_O 53 | set_directive_loop_tripcount -min 1 -max 64 bin_dense/LOOP_DENSE_I 54 | 55 | # Each ping-poing buffer in the dmem has 2048 words 56 | # For input layer we need 3*32*32/2 = 1536 words total, divided into blocks of 512 57 | set_directive_array_partition top dmem -dim 1 -type complete 58 | set_directive_array_partition top dmem -dim 2 -type complete 59 | set_directive_array_partition top wt_mem -dim 1 -type complete 60 | set_directive_array_partition bin_conv line_buffer -dim 0 -type complete 61 | set_directive_array_partition bin_conv conv_params -dim 0 -type complete 62 | set_directive_array_partition bin_conv fixed_buffer -dim 2 -type complete 63 | set_directive_array_partition bin_conv fixed_temp -dim 0 -type complete 64 | set_directive_array_partition bin_conv word_buffer -dim 0 -type complete 65 | set_directive_array_partition bin_conv old_word_buffer -dim 0 -type complete 66 | set_directive_array_partition bin_conv lb -dim 0 -type complete 67 | set_directive_array_partition bin_conv rb -dim 0 -type complete 68 | set_directive_array_partition bin_conv wt_word_buffer -dim 0 -type complete 69 | set_directive_array_partition bin_conv conv_out_buffer -dim 0 -type complete 70 | set_directive_array_partition fp_conv win -dim 0 -type complete 71 | set_directive_array_partition fp_conv lbuf -dim 0 -type complete 72 | set_directive_array_partition fp_conv outwords -dim 0 -type complete 73 | set_directive_array_partition fp_conv wtbuf -dim 0 -type complete 74 | set_directive_array_partition bin_fc sum_m -dim 0 -type complete 75 | #========================================================================= 76 | -------------------------------------------------------------------------------- /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 top Accel.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 AccelPrint.o Dense.o InputConv.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/cornell-zhang/bnn-fpga/d6680114a1ea7c7343acb0562ea833edbb0c60c1/cpp/accel/sdsoc_build/libhf_minizip/libaes.a -------------------------------------------------------------------------------- /cpp/accel/sdsoc_build/libhf_minizip/libminizip.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cornell-zhang/bnn-fpga/d6680114a1ea7c7343acb0562ea833edbb0c60c1/cpp/accel/sdsoc_build/libhf_minizip/libminizip.a -------------------------------------------------------------------------------- /cpp/accel/sdsoc_build/libhf_minizip/libz.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cornell-zhang/bnn-fpga/d6680114a1ea7c7343acb0562ea833edbb0c60c1/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 "top" wt_i 5 | set_directive_interface -mode ap_fifo "top" kh_i 6 | set_directive_interface -mode ap_fifo "top" dmem_i 7 | set_directive_interface -mode ap_fifo "top" dmem_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/cornell-zhang/bnn-fpga/d6680114a1ea7c7343acb0562ea833edbb0c60c1/cpp/minizip/libaes.a -------------------------------------------------------------------------------- /cpp/minizip/libminizip.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cornell-zhang/bnn-fpga/d6680114a1ea7c7343acb0562ea833edbb0c60c1/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 | 9 | #include "Typedefs.h" 10 | 11 | // Returns the repo's root dir or exits 12 | std::string get_root_dir(); 13 | 14 | // We encode negative to -1, positive to 0 15 | template 16 | Bit sgn(const T x) { 17 | #pragma HLS INLINE 18 | return (x < 0) ? -1 : 0; 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /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]; 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 | unsigned fsize = get_current_file_size(ar); 17 | assert(m_size*4 <= fsize); 18 | 19 | DB_PRINT(2, "Reading %u bytes\n", m_size*4); 20 | read_current_file(ar, (void*)data, m_size*4); 21 | 22 | unzClose(ar); 23 | } 24 | 25 | Cifar10TestLabels::Cifar10TestLabels(unsigned n) 26 | : m_size(n) 27 | { 28 | data = new float[m_size]; 29 | 30 | std::string full_filename = get_root_dir() + filename; 31 | DB_PRINT(2, "Opening data archive %s\n", full_filename.c_str()); 32 | unzFile ar = open_unzip(full_filename.c_str()); 33 | unsigned nfiles = get_nfiles_in_unzip(ar); 34 | assert(nfiles == 1); 35 | 36 | // We read n*4 bytes from the archive 37 | unsigned fsize = get_current_file_size(ar); 38 | assert(m_size*4 <= fsize); 39 | 40 | DB_PRINT(2, "Reading %u bytes\n", m_size*4); 41 | read_current_file(ar, (void*)data, m_size*4); 42 | unzClose(ar); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /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 | struct Params { 17 | static const unsigned MAX_LAYERS = 64; 18 | 19 | std::string m_filename; 20 | unsigned m_arrays; 21 | unsigned m_array_size[MAX_LAYERS]; 22 | float* m_data[MAX_LAYERS]; 23 | 24 | public: 25 | // Read a zip archive containing NN params. We make the assumption 26 | // that each file in the archive is one array. The data is stored 27 | // as just an array of bytes 28 | Params(std::string zipfile); 29 | // Safely deletes params 30 | ~Params(); 31 | 32 | // Get the number of layers 33 | unsigned num_arrays() const { return m_arrays; } 34 | // Get the size of the params array in bytes 35 | unsigned array_size(unsigned i) const { 36 | return m_array_size[i]; 37 | } 38 | // Get a pointer to the params for layer 39 | float* array_data(unsigned i) const { 40 | return m_data[i]; 41 | } 42 | 43 | float* float_data(unsigned i) const { 44 | return array_data(i); 45 | } 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /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; 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 | unsigned get_nfiles_in_unzip(unzFile ar) { 18 | unz_global_info info; 19 | int err = unzGetGlobalInfo(ar, &info); 20 | assert(!err); 21 | return info.number_entry; 22 | } 23 | 24 | //------------------------------------------------------------------------ 25 | unsigned get_current_file_size(unzFile ar) { 26 | unz_file_info finfo; 27 | char fname[50]; 28 | 29 | int err = unzGetCurrentFileInfo(ar, &finfo, fname, 50, NULL, 0, NULL, 0); 30 | assert(!err); 31 | unsigned fsize = finfo.uncompressed_size; 32 | 33 | DB_PRINT(3, "Reading %10s, %u bytes\n", fname, fsize); 34 | 35 | assert(fsize > 0); 36 | return fsize; 37 | } 38 | 39 | //------------------------------------------------------------------------ 40 | void read_current_file(unzFile ar, void* buffer, unsigned bytes) { 41 | int err = unzOpenCurrentFile(ar); 42 | assert(!err); 43 | 44 | unsigned b = unzReadCurrentFile(ar, buffer, bytes); 45 | assert(b == bytes); 46 | 47 | unzCloseCurrentFile(ar); 48 | } 49 | 50 | //------------------------------------------------------------------------ 51 | void write_buffer_to_zip(zipFile zf, std::string fname, void* buf, unsigned len) { 52 | int err; 53 | DB_PRINT(3, "Writing %10s, %u bytes\n", fname.c_str(), len); 54 | 55 | // Open new file 56 | zip_fileinfo zi = {0}; 57 | err = zipOpenNewFileInZip(zf, fname.c_str(), &zi, 58 | NULL, 0, NULL, 0, NULL, 59 | 0, /* method */ 60 | Z_DEFAULT_COMPRESSION); /* level */ 61 | assert(err == ZIP_OK); 62 | 63 | // Write data 64 | err = zipWriteInFileInZip(zf, buf, len); 65 | assert(err == ZIP_OK); 66 | 67 | // Close file 68 | err = zipCloseFileInZip(zf); 69 | assert(err == ZIP_OK); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /data/get_data.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURR_DIR=`pwd` 4 | DIR="$( cd "$( dirname "${BASH_ROUCE[0]}" )" && pwd )" 5 | cd $DIR 6 | 7 | declare -a files=("cifar10_test_inputs.zip" "cifar10_test_labels.zip" 8 | "cpp_conv1_maps.zip" "cpp_conv2_maps.zip" 9 | "cpp_conv3_maps.zip" "cpp_conv4_maps.zip" 10 | "cpp_conv5_maps.zip" "cpp_conv6_maps.zip" 11 | "cpp_dense0_maps.zip" "cpp_dense1_maps.zip" 12 | "cpp_dense2_maps.zip") 13 | 14 | for i in "${files[@]}" ; do 15 | if [ -f $i ] ; then 16 | echo "$i already exists" 17 | else 18 | wget "www.csl.cornell.edu/~rzhao/files/$i" 19 | fi 20 | done 21 | 22 | cd $CURR_DIR 23 | -------------------------------------------------------------------------------- /params/get_params.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURR_DIR=`pwd` 4 | DIR="$( cd "$( dirname "${BASH_ROUCE[0]}" )" && pwd )" 5 | cd $DIR 6 | 7 | declare -a files=("cifar10_parameters_nb.zip" "cifar10_parameters_nb.npz") 8 | 9 | for i in "${files[@]}" ; do 10 | if [ -f $i ] ; then 11 | echo "$i already exists" 12 | else 13 | wget "www.csl.cornell.edu/~rzhao/files/$i" 14 | fi 15 | done 16 | 17 | cd $CURR_DIR 18 | -------------------------------------------------------------------------------- /python/in_memory_zip.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------- 2 | # Python code to write a zip archive with multiple files 3 | # Taken from stackoverflow 4 | #------------------------------------------------------------------------- 5 | import zipfile 6 | try: 7 | from cStringIO import StringIO 8 | except ImportError: 9 | from io import BytesIO as StringIO 10 | 11 | class in_memory_zip(object): 12 | def __init__(self): 13 | # Create the in-memory file-like object 14 | self.in_memory_data = StringIO() 15 | # Create the in-memory zipfile 16 | self.in_memory_zip = zipfile.ZipFile( 17 | self.in_memory_data, 'w', zipfile.ZIP_DEFLATED, False) 18 | self.in_memory_zip.debug = 3 19 | 20 | def append(self, filename_in_zip, file_contents): 21 | '''Appends a file with name filename_in_zip and contents of 22 | file_contents to the in-memory zip.''' 23 | self.in_memory_zip.writestr(filename_in_zip, file_contents) 24 | return self # so you can daisy-chain 25 | 26 | def writetofile(self, filename): 27 | '''Writes the in-memory zip to a file.''' 28 | # Mark the files as having been created on Windows so that 29 | # Unix permissions are not inferred as 0000 30 | for zfile in self.in_memory_zip.filelist: 31 | zfile.create_system = 0 32 | self.in_memory_zip.close() 33 | with open(filename, 'wb') as f: 34 | f.write(self.in_memory_data.getvalue()) 35 | 36 | if __name__ == "__main__": 37 | # Run a test 38 | imz = in_memory_zip() 39 | imz.append("test.txt", "Another test").append("test2.txt", "Still another") 40 | imz.writetofile("test.zip") 41 | -------------------------------------------------------------------------------- /python/npz2zip.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------- 2 | # Converts a .npz numpy archive into a zip archive which can be read 3 | # by many more utilities as well as our C++ code. 4 | # 5 | # Primarily used to convert the BNN parameters to C++ readable format. 6 | # 7 | # This file only deals with Floating Point parameters, for binarization 8 | # use npz2zip_binary.py 9 | #------------------------------------------------------------------------- 10 | from in_memory_zip import in_memory_zip 11 | import numpy as np 12 | import struct 13 | import sys 14 | 15 | if __name__ == "__main__": 16 | if len(sys.argv) < 3: 17 | print "Usage: npz2zip.py " 18 | exit(-1) 19 | 20 | # initialize a zip archive 21 | imz = in_memory_zip() 22 | 23 | # load the npz file 24 | f = np.load(sys.argv[1]) 25 | 26 | for i in range(len(f.keys())): 27 | k = 'arr_' + str(i) 28 | val = f[k] 29 | val = val.flatten() 30 | 31 | print "Writing", k, "\tsize =", len(val), "floats" 32 | 33 | # write the data to a file in plaintext 34 | #fp = open('frompy', 'w') 35 | #for v in val: 36 | # fp.write(('%10.8f' % v) +'\n') 37 | #fp.close() 38 | 39 | # generate a string by packing each float as 4 bytes 40 | buf = struct.pack('%sf' % len(val), *val) 41 | 42 | imz.append(k, buf) 43 | 44 | # write zip archive to disk 45 | imz.writetofile(sys.argv[2]) 46 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | export CRAFT_BNN_ROOT=$DIR 5 | --------------------------------------------------------------------------------