├── tool ├── cache.hpp ├── cache.h ├── permutation_list.h ├── permutation_list.cpp ├── lrucache.h ├── search.h ├── configparser.h ├── layer.cpp ├── guessmask.h ├── commandlineparser.h ├── lrucache.hpp ├── guessmask.cpp ├── permutation.h ├── statemask.h ├── commandlineparser.cpp ├── main.cpp ├── step_nonlinear.h ├── mask.cpp ├── step_linear.h ├── statemask.hpp ├── mask.h ├── configparser.cpp ├── layer.h └── search.cpp ├── .gitmodules ├── .gitignore ├── target ├── prost256_permutation.h ├── icepole_permutation.h ├── keccak1600_permutation.h ├── ascon_permutation.h ├── icepole.h ├── keccak1600.h ├── prost256_permutation.cpp ├── ascon_permutation.cpp ├── ascon.h ├── prost256.cpp ├── icepole_permutation.cpp ├── keccak1600_permutation.cpp ├── prost256.h ├── ascon.cpp ├── keccak1600.cpp └── icepole.cpp ├── Makefile ├── examples ├── ascon_3_rounds_typeI.xml ├── ascon_3_rounds_typeII.xml ├── prost256_4_rounds_typeI.xml ├── prost256_5_rounds_typeI.xml ├── keccak_2_rounds_typeI.xml └── icepole_3_rounds_typeIII.xml └── README.md /tool/cache.hpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tinyxml2"] 2 | path = tinyxml2 3 | url = https://github.com/leethomason/tinyxml2.git 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | lin 23 | 24 | # vim tmp files 25 | *.swp 26 | *~ 27 | -------------------------------------------------------------------------------- /target/prost256_permutation.h: -------------------------------------------------------------------------------- 1 | #ifndef PROST256PERMUTATION_H_ 2 | #define PROST256PERMUTATION_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "prost256.h" 8 | #include "mask.h" 9 | #include "permutation.h" 10 | 11 | 12 | struct Prost256Permutation : public Permutation { 13 | // Prost256Permutation& operator=(const Prost256Permutation& rhs); 14 | Prost256Permutation(unsigned int rounds); 15 | Prost256Permutation(const Prost256Permutation& other); 16 | void touchall(); 17 | PermPtr clone() const; 18 | virtual void PrintWithProbability(std::ostream& stream = std::cout, 19 | unsigned int offset = 0) override; 20 | 21 | }; 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /target/icepole_permutation.h: -------------------------------------------------------------------------------- 1 | #ifndef ICEPOLEPERMUTATION_H_ 2 | #define ICEPOLEPERMUTATION_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "icepole.h" 8 | #include "mask.h" 9 | #include "permutation.h" 10 | 11 | 12 | struct IcepolePermutation : public Permutation { 13 | IcepolePermutation& operator=(const IcepolePermutation& rhs); 14 | IcepolePermutation(unsigned int rounds); 15 | IcepolePermutation(const IcepolePermutation& other); 16 | virtual void set(Permutation* perm); 17 | bool update(); 18 | void touchall(); 19 | PermPtr clone() const; 20 | virtual void PrintWithProbability(std::ostream& stream = std::cout, 21 | unsigned int offset = 0) override; 22 | 23 | }; 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /target/keccak1600_permutation.h: -------------------------------------------------------------------------------- 1 | #ifndef KECCAK1600PERMUTATION_H_ 2 | #define KECCAK1600PERMUTATION_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "keccak1600.h" 8 | #include "mask.h" 9 | #include "permutation.h" 10 | 11 | 12 | struct Keccak1600Permutation : public Permutation { 13 | Keccak1600Permutation& operator=(const Keccak1600Permutation& rhs); 14 | Keccak1600Permutation(unsigned int rounds); 15 | Keccak1600Permutation(const Keccak1600Permutation& other); 16 | virtual void set(Permutation* perm); 17 | bool update(); 18 | void touchall(); 19 | PermPtr clone() const; 20 | virtual void PrintWithProbability(std::ostream& stream = std::cout, 21 | unsigned int offset = 0) override; 22 | 23 | }; 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL=/bin/sh 2 | .SUFFIXES: 3 | .SUFFIXES: .cpp .h .o 4 | 5 | CXX=g++ 6 | CXXFLAGS=-c -Wall -march=native -std=c++11 -DTERMINALCOLORS 7 | FASTFLAGS=-O3 8 | DEBUGFLAGS=-g 9 | CLUSTERCXXFLAGS=-c -Wall -std=c++11 -O3 10 | #LDFLAGS=-pthread 11 | LDFLAGS= 12 | SRC_DIR=tool target 13 | BUILD_DIR=build 14 | SOURCES=$(foreach srcdir,$(SRC_DIR),$(wildcard $(srcdir)/*.cpp)) 15 | #OBJECTS=$(addprefix build/,${SOURCES:.cpp=.o}) 16 | OBJECTS=$(foreach srcdir,$(SRC_DIR),$(patsubst $(srcdir)/%.cpp,$(BUILD_DIR)/%.o,$(filter $(srcdir)/%.cpp,$(SOURCES)))) 17 | INCLUDES=$(addprefix -I,$(SRC_DIR)) 18 | vpath %.cpp $(SRC_DIR) 19 | vpath %.h $(SRC_DIR) 20 | vpath %.hpp $(SRC_DIR) 21 | TITLE=lin 22 | 23 | .PHONY : all clean 24 | 25 | # make all 26 | all: fast 27 | 28 | # make fast 29 | fast: CXXFLAGS += $(FASTFLAGS) 30 | fast: $(TITLE) 31 | 32 | # make fastdebug 33 | fastdebug: CXXFLAGS += $(FASTFLAGS) $(DEBUGFLAGS) 34 | fastdebug: $(TITLE) 35 | 36 | # make debug 37 | debug: CXXFLAGS += $(DEBUGFLAGS) 38 | debug: $(TITLE) 39 | 40 | # make cluster 41 | cluster: CXXFLAGS = $(CLUSTERCXXFLAGS) 42 | cluster: $(TITLE) 43 | 44 | # make 45 | $(TITLE): $(OBJECTS) $(BUILD_DIR)/tinyxml2.o 46 | $(CXX) -g -o $@ $^ $(INCLUDES) $(LDFLAGS) 47 | 48 | # make %.o 49 | $(BUILD_DIR)/%.o: %.cpp 50 | $(CXX) $(CXXFLAGS) -o $@ $< -MMD -MF ./$@.d $(INCLUDES) $(LDFLAGS) 51 | 52 | $(BUILD_DIR)/tinyxml2.o: tinyxml2/tinyxml2.cpp 53 | $(CXX) $(CXXFLAGS) -o $@ tinyxml2/tinyxml2.cpp -MMD -MF ./$@.d $(LDFLAGS) 54 | 55 | # make clean 56 | clean: 57 | rm -f $(BUILD_DIR)/*.o $(BUILD_DIR)/*.d $(TITLE) 58 | 59 | -include $(wildcard $(BUILD_DIR)/*.d) 60 | -------------------------------------------------------------------------------- /tool/cache.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | 28 | #ifndef CACHE_H_ 29 | #define CACHE_H_ 30 | 31 | template 32 | class Cache { 33 | public: 34 | virtual ~Cache() {}; 35 | virtual bool find(const KEY_TYPE& key, TYPE& content) = 0; 36 | virtual bool insert(const KEY_TYPE& key, const TYPE& content) = 0; 37 | }; 38 | 39 | #include "cache.hpp" 40 | 41 | #endif /* CACHE_H_ */ 42 | -------------------------------------------------------------------------------- /tool/permutation_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef PERMUTATION_LIST_H_ 28 | #define PERMUTATION_LIST_H_ 29 | 30 | #include 31 | #include 32 | 33 | #include "permutation.h" 34 | #include "ascon_permutation.h" 35 | #include "keccak1600_permutation.h" 36 | #include "prost256_permutation.h" 37 | #include "icepole_permutation.h" 38 | 39 | 40 | extern Permutation* permutation_list(std::string name, int rounds); 41 | #endif /* PERMUTATION_LIST_H_ */ 42 | -------------------------------------------------------------------------------- /tool/permutation_list.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include "permutation_list.h" 28 | 29 | Permutation* permutation_list(std::string name, int rounds) { 30 | 31 | if (name.compare("ascon") == 0) 32 | return new AsconPermutation(rounds); 33 | if (name.compare("keccak1600") == 0) 34 | return new Keccak1600Permutation(rounds); 35 | if (name.compare("icepole") == 0) 36 | return new IcepolePermutation(rounds); 37 | if (name.compare("prost256") == 0) 38 | return new Prost256Permutation(rounds); 39 | 40 | assert(!"instance with this name not found"); 41 | return nullptr; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /target/ascon_permutation.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef ASCONPERMUTATION_H_ 28 | #define ASCONPERMUTATION_H_ 29 | 30 | #include 31 | #include 32 | 33 | #include "ascon.h" 34 | #include "mask.h" 35 | #include "permutation.h" 36 | 37 | struct AsconPermutation : public Permutation { 38 | AsconPermutation(unsigned int rounds); 39 | AsconPermutation(const AsconPermutation& other); 40 | void touchall(); 41 | PermPtr clone() const; 42 | virtual void PrintWithProbability(std::ostream& stream = std::cout, 43 | unsigned int offset = 0) override; 44 | 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /tool/lrucache.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef LRUCACHE_H_ 28 | #define LRUCACHE_H_ 29 | 30 | #include 31 | #include 32 | 33 | #include "cache.h" 34 | 35 | template 36 | class LRU_Cache : public Cache { 37 | public: 38 | LRU_Cache(unsigned int max_cache_size); 39 | virtual bool find(const KEY_TYPE& key, TYPE& content); 40 | virtual bool insert(const KEY_TYPE& key, const TYPE& content); 41 | 42 | private: 43 | unsigned int max_cache_size_ = 0x1000; 44 | unsigned int cache_size_ ; 45 | unsigned long long time_; 46 | 47 | void deleteOldestElement(); 48 | 49 | std::unordered_map> cache_; 50 | 51 | }; 52 | 53 | #include "lrucache.hpp" 54 | 55 | #endif /* LRUCACHE_H_ */ 56 | -------------------------------------------------------------------------------- /tool/search.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef SEARCH_H_ 28 | #define SEARCH_H_ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "permutation.h" 39 | #include "mask.h" 40 | #include "guessmask.h" 41 | #include "configparser.h" 42 | #include "commandlineparser.h" 43 | 44 | class Search { 45 | 46 | public: 47 | Search(Permutation &perm); 48 | void StackSearch1(Commandlineparser& cl_param, Configparser& config_param); 49 | void StackSearchKeccak(Commandlineparser& cl_param, Configparser& config_param); 50 | 51 | private: 52 | double KeccakProb(std::stack>& char_stack); 53 | 54 | Permutation *perm_; 55 | 56 | }; 57 | 58 | #endif /* SEARCH_H_ */ 59 | -------------------------------------------------------------------------------- /target/icepole.h: -------------------------------------------------------------------------------- 1 | #ifndef ICEPOLE_H_ 2 | #define ICEPOLE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "layer.h" 11 | #include "mask.h" 12 | #include "statemask.h" 13 | #include "step_linear.h" 14 | #include "step_nonlinear.h" 15 | #include "lrucache.h" 16 | 17 | 18 | struct IcepoleState : public StateMask<20,64> { 19 | IcepoleState(); 20 | friend std::ostream& operator<<(std::ostream& stream, const IcepoleState& statemask); 21 | void print(std::ostream& stream); 22 | virtual IcepoleState* clone(); 23 | }; 24 | 25 | 26 | #define ROTR(x,n) (((x)>>(n))|((x)<<(64-(n)))) 27 | #define ROTL(x,n) (((x)<<(n))|((x)>>(64-(n)))) 28 | 29 | 30 | 31 | struct IcepoleLinearLayer : public LinearLayer { 32 | IcepoleLinearLayer& operator=(const IcepoleLinearLayer& rhs); 33 | IcepoleLinearLayer(); 34 | virtual IcepoleLinearLayer* clone(); 35 | void Init(); 36 | IcepoleLinearLayer(StateMaskBase *in, StateMaskBase *out); 37 | virtual bool updateStep(unsigned int step_pos); 38 | unsigned int GetNumSteps(); 39 | virtual void copyValues(LinearLayer* other); 40 | 41 | static const unsigned int word_size_ = { 64 }; 42 | static const unsigned int words_per_step_ = { 20 }; 43 | static const unsigned int linear_steps_ = {1 }; 44 | std::array, linear_steps_> icepole_linear_; 45 | }; 46 | 47 | 48 | struct IcepoleSboxLayer : public SboxLayer<5, 256> { 49 | IcepoleSboxLayer& operator=(const IcepoleSboxLayer& rhs); 50 | IcepoleSboxLayer(); 51 | IcepoleSboxLayer(StateMaskBase *in, StateMaskBase *out); 52 | virtual IcepoleSboxLayer* clone(); 53 | virtual bool updateStep(unsigned int step_pos); 54 | Mask GetVerticalMask(unsigned int b, const StateMaskBase& s) const; 55 | void SetVerticalMask(unsigned int b, StateMaskBase& s, const Mask& mask); 56 | 57 | static const unsigned int cache_size_ = { 0x1000 }; 58 | static std::unique_ptr> cache_; 59 | static std::shared_ptr> ldt_; 60 | }; 61 | 62 | 63 | 64 | #endif // ICEPOLE_H_ 65 | -------------------------------------------------------------------------------- /tool/configparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef CONFIGPARSER_H_ 28 | #define CONFIGPARSER_H_ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "../tinyxml2/tinyxml2.h" 37 | #include "permutation.h" 38 | #include "guessmask.h" 39 | #include "permutation_list.h" 40 | 41 | 42 | struct Configparser { 43 | Configparser(); 44 | bool parseFile(std::string filename); 45 | std::unique_ptr getPermutation(); 46 | Settings getSettings(); 47 | unsigned int getCredits(); 48 | bool printActive(); 49 | bool Error(std::initializer_list msg); 50 | bool Warning(std::initializer_list msg); 51 | 52 | std::unique_ptr perm_; 53 | Settings settings_; 54 | unsigned int credits_; 55 | bool print_active_; 56 | }; 57 | 58 | #endif /* CONFIGPARSER_H_ */ 59 | -------------------------------------------------------------------------------- /target/keccak1600.h: -------------------------------------------------------------------------------- 1 | #ifndef KECCAK1600_H_ 2 | #define KECCAK1600_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "layer.h" 11 | #include "mask.h" 12 | #include "statemask.h" 13 | #include "step_linear.h" 14 | #include "step_nonlinear.h" 15 | #include "lrucache.h" 16 | 17 | 18 | struct Keccak1600State : public StateMask<25,64> { 19 | Keccak1600State(); 20 | friend std::ostream& operator<<(std::ostream& stream, const Keccak1600State& statemask); 21 | void print(std::ostream& stream); 22 | virtual Keccak1600State* clone(); 23 | }; 24 | 25 | 26 | #define ROTR(x,n) (((x)>>(n))|((x)<<(64-(n)))) 27 | #define ROTL(x,n) (((x)<<(n))|((x)>>(64-(n)))) 28 | 29 | 30 | 31 | struct Keccak1600LinearLayer : public LinearLayer { 32 | Keccak1600LinearLayer& operator=(const Keccak1600LinearLayer& rhs); 33 | Keccak1600LinearLayer(); 34 | virtual Keccak1600LinearLayer* clone(); 35 | void Init(); 36 | Keccak1600LinearLayer(StateMaskBase *in, StateMaskBase *out); 37 | virtual bool updateStep(unsigned int step_pos); 38 | unsigned int GetNumSteps(); 39 | virtual void copyValues(LinearLayer* other); 40 | 41 | static const unsigned int word_size_ = { 64 }; 42 | static const unsigned int words_per_step_ = { 25 }; 43 | static const unsigned int linear_steps_ = {1 }; 44 | std::array, linear_steps_> keccak_linear_; 45 | }; 46 | 47 | 48 | struct Keccak1600SboxLayer : public SboxLayer<5, 320> { 49 | Keccak1600SboxLayer& operator=(const Keccak1600SboxLayer& rhs); 50 | Keccak1600SboxLayer(); 51 | Keccak1600SboxLayer(StateMaskBase *in, StateMaskBase *out); 52 | virtual Keccak1600SboxLayer* clone(); 53 | virtual bool updateStep(unsigned int step_pos); 54 | Mask GetVerticalMask(unsigned int b, const StateMaskBase& s) const; 55 | void SetVerticalMask(unsigned int b, StateMaskBase& s, const Mask& mask); 56 | 57 | static const unsigned int cache_size_ = { 0x1000 }; 58 | static std::unique_ptr> cache_; 59 | static std::shared_ptr> ldt_; 60 | }; 61 | 62 | 63 | 64 | #endif // KECCAK1600_H_ 65 | -------------------------------------------------------------------------------- /tool/layer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | 28 | #include "layer.h" 29 | 30 | SboxPos::SboxPos(uint16_t layer, uint16_t pos) : layer_(layer),pos_(pos){ 31 | } 32 | 33 | 34 | //----------------------------------------------------------------------------- 35 | 36 | Layer::Layer(StateMaskBase *in, StateMaskBase *out) : in(in), out(out) { 37 | } 38 | 39 | void Layer::SetMasks(StateMaskBase *inmask, StateMaskBase *outmask) { 40 | in = inmask; 41 | out = outmask; 42 | } 43 | 44 | //----------------------------------------------------------------------------- 45 | 46 | LinearLayer::LinearLayer(StateMaskBase *in, StateMaskBase *out) : Layer(in, out) { 47 | } 48 | 49 | bool LinearLayer::Update(){ 50 | bool ret_val = true; 51 | 52 | for(unsigned int i = 0; i < GetNumSteps(); ++i) 53 | ret_val &= updateStep(i); 54 | 55 | in->resetChangesLinear(); 56 | out->resetChangesLinear(); 57 | return ret_val; 58 | } 59 | 60 | //----------------------------------------------------------------------------- 61 | 62 | SboxLayerBase::SboxLayerBase(StateMaskBase *in, StateMaskBase *out) : Layer(in, out) { 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /tool/guessmask.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef GUESSMASK_H_ 28 | #define GUESSMASK_H_ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "layer.h" 38 | #include "permutation.h" 39 | 40 | 41 | 42 | struct Setting { 43 | std::vector> guess_weights_; 44 | float push_stack_probability_; 45 | float sbox_weight_probability_; 46 | float sbox_weight_hamming_; 47 | unsigned int alternative_sbox_guesses_; 48 | }; 49 | 50 | typedef std::vector Settings; 51 | 52 | 53 | struct GuessMask { 54 | 55 | int createMask(Permutation *perm, Settings& settings); 56 | int getRandPos(SboxPos& box, bool& active); 57 | float getPushStackProb(); 58 | float getSboxWeigthProb(); 59 | float getSboxWeightHamming(); 60 | unsigned int getAlternativeSboxGuesses(); 61 | 62 | 63 | std::list> weighted_pos_; 64 | float total_weight_; 65 | Setting* current_setting_; 66 | 67 | private: 68 | std::array,2> temp_active_boxes_; 69 | }; 70 | 71 | 72 | 73 | #endif /* GUESSMASK_H_ */ 74 | -------------------------------------------------------------------------------- /tool/commandlineparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | 28 | #ifndef COMMANDLINEPARSER_H_ 29 | #define COMMANDLINEPARSER_H_ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | struct Parameter { 37 | std::string name; 38 | std::string helptext; 39 | const char* defaultvalue; 40 | const char* value; 41 | 42 | Parameter(std::string name, std::string helptext, const char *defaultvalue, const char* value); 43 | }; 44 | 45 | struct Commandlineparser { 46 | Commandlineparser(std::string description); 47 | void addParameter(std::string parameter_switch, std::string helptext, const char* parameter); 48 | const char* getParameter(std::string parameter_switch); 49 | int getIntParameter(std::string parameter_switch); 50 | float getFloatParameter(std::string parameter_switch); 51 | bool getBoolParameter(std::string parameter_switch); 52 | void parse(int& argc,const char* argv[]); 53 | void print_pars(); 54 | void print_fatal_error(std::string errmsg); 55 | void print_help(); 56 | 57 | std::string description_; 58 | unsigned maxlen_; 59 | std::map params_; 60 | }; 61 | 62 | #endif /* COMMANDLINEPARSER_H_ */ 63 | -------------------------------------------------------------------------------- /tool/lrucache.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | template 28 | LRU_Cache::LRU_Cache(unsigned int max_cache_size) 29 | : max_cache_size_(max_cache_size), 30 | cache_size_(0), 31 | time_(0) { 32 | cache_.reserve(max_cache_size_); 33 | } 34 | 35 | template 36 | bool LRU_Cache::find(const KEY_TYPE& key, TYPE& content) { 37 | auto element = cache_.find(key); 38 | 39 | if (element == cache_.end()) 40 | return false; 41 | 42 | content = element->second.first; 43 | element->second.second = ++time_; 44 | 45 | return true; 46 | } 47 | 48 | template 49 | bool LRU_Cache::insert(const KEY_TYPE& key, 50 | const TYPE& content) { 51 | if (cache_size_ >= max_cache_size_) 52 | deleteOldestElement(); 53 | 54 | // std::cout << "Insert: " << key << std::endl << "Size: " << cache_size_ << std::endl; 55 | 56 | cache_size_++; 57 | bool cache_worked = true; 58 | cache_worked &= cache_.emplace( 59 | key, 60 | std::pair(content, ++time_)).second; 61 | assert(cache_worked == true); 62 | return cache_worked; 63 | } 64 | 65 | template 66 | void LRU_Cache::deleteOldestElement() { 67 | auto lru_element = cache_.begin(); 68 | for (auto element = cache_.begin(); element != cache_.end(); ++element) 69 | if (element->second.second < lru_element->second.second) 70 | lru_element = element; 71 | cache_.erase(lru_element); 72 | cache_size_--; 73 | } 74 | -------------------------------------------------------------------------------- /tool/guessmask.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include "guessmask.h" 28 | 29 | int GuessMask::createMask(Permutation *perm, Settings& settings){ 30 | 31 | weighted_pos_.clear(); 32 | total_weight_ = 0; 33 | 34 | perm->SboxStatus(temp_active_boxes_[1], temp_active_boxes_[0]); 35 | 36 | for (auto& set : settings) { 37 | for (int i = 0; i < 2; ++i) { 38 | for (auto& box : temp_active_boxes_[i]) { 39 | if (set.guess_weights_[box.layer_][i] != 0) { 40 | total_weight_ += set.guess_weights_[box.layer_][i]; 41 | weighted_pos_.push_back(std::tuple(box, set.guess_weights_[box.layer_][i], i==1 )); 42 | } 43 | } 44 | } 45 | if(total_weight_ != 0){ 46 | current_setting_ = &set; 47 | return 1; 48 | } 49 | } 50 | 51 | return 0; 52 | } 53 | int GuessMask::getRandPos(SboxPos& box, bool& active) { 54 | std::uniform_real_distribution guessbox(0, total_weight_); 55 | 56 | std::mt19937 generator( 57 | std::chrono::high_resolution_clock::now().time_since_epoch().count()); 58 | float rand = guessbox(generator); 59 | float current_weight = 0; 60 | for (auto it = weighted_pos_.begin(); it != weighted_pos_.end(); ++it) { 61 | current_weight += std::get<1>(*it); 62 | if (current_weight >= rand) { 63 | box = std::get<0>(*it); 64 | active = std::get<2>(*it); 65 | total_weight_ -= std::get<1>(*it); 66 | weighted_pos_.erase(it); 67 | return 1; 68 | } 69 | } 70 | 71 | return 0; 72 | } 73 | 74 | float GuessMask::getPushStackProb(){ 75 | return current_setting_->push_stack_probability_; 76 | } 77 | float GuessMask::getSboxWeigthProb(){ 78 | return current_setting_->sbox_weight_probability_; 79 | } 80 | float GuessMask::getSboxWeightHamming(){ 81 | return current_setting_->sbox_weight_hamming_; 82 | } 83 | 84 | unsigned int GuessMask::getAlternativeSboxGuesses(){ 85 | return current_setting_->alternative_sbox_guesses_; 86 | } 87 | -------------------------------------------------------------------------------- /examples/ascon_3_rounds_typeI.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /examples/ascon_3_rounds_typeII.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /target/prost256_permutation.cpp: -------------------------------------------------------------------------------- 1 | #include "prost256_permutation.h" 2 | 3 | 4 | Prost256Permutation::Prost256Permutation(unsigned int rounds) : Permutation(rounds) { 5 | for(unsigned int i = 0; i< 2*rounds +1; ++i) { 6 | this->state_masks_[i].reset(new Prost256State); 7 | this->saved_state_masks_[i].reset(new Prost256State); 8 | } 9 | for (unsigned int i = 0; i < rounds; ++i) { 10 | this->sbox_layers_[i].reset(new Prost256SboxLayer); 11 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2*i].get(), this->state_masks_[2*i + 1].get()); 12 | if((i & 1) == 1) 13 | this->linear_layers_[i].reset(new Prost256LinearLayer<1>); 14 | else 15 | this->linear_layers_[i].reset(new Prost256LinearLayer<0>); 16 | this->linear_layers_[i]->SetMasks(this->state_masks_[2*i + 1].get(), this->state_masks_[2*i + 2].get()); 17 | this->saved_sbox_layers_[i].reset(new Prost256SboxLayer); 18 | this->saved_sbox_layers_[i]->SetMasks(this->saved_state_masks_[2*i].get(), this->saved_state_masks_[2*i + 1].get()); 19 | if ((i & 1) == 1) 20 | this->saved_linear_layers_[i].reset(new Prost256LinearLayer<1>); 21 | else 22 | this->saved_linear_layers_[i].reset(new Prost256LinearLayer<0>); 23 | this->saved_linear_layers_[i]->SetMasks(this->saved_state_masks_[2*i + 1].get(), this->saved_state_masks_[2*i + 2].get()); 24 | } 25 | touchall(); 26 | } 27 | 28 | 29 | Prost256Permutation::Prost256Permutation(const Prost256Permutation& other) : Permutation(other) { 30 | for(unsigned int i = 0; i< 2*rounds_ +1; ++i) { 31 | this->saved_state_masks_[i].reset(new Prost256State); 32 | } 33 | for (unsigned int i = 0; i < rounds_; ++i) { 34 | this->saved_sbox_layers_[i].reset(new Prost256SboxLayer); 35 | this->saved_sbox_layers_[i]->SetMasks(this->saved_state_masks_[2*i].get(), this->saved_state_masks_[2*i + 1].get()); 36 | if ((i & 1) == 1) 37 | this->saved_linear_layers_[i].reset(new Prost256LinearLayer<1>); 38 | else 39 | this->saved_linear_layers_[i].reset(new Prost256LinearLayer<0>); 40 | this->saved_linear_layers_[i]->SetMasks(this->saved_state_masks_[2*i + 1].get(), this->saved_state_masks_[2*i + 2].get()); 41 | } 42 | } 43 | 44 | 45 | 46 | 47 | //Prost256Permutation& Prost256Permutation::operator=(const Prost256Permutation& rhs){ 48 | // for(unsigned int i = 0; i< 2*rounds_ +1; ++i){ 49 | // this->state_masks_[i].reset(rhs.state_masks_[i]->clone()); 50 | // } 51 | // this->toupdate_linear = rhs.toupdate_linear; 52 | // this->toupdate_nonlinear = rhs.toupdate_nonlinear; 53 | // for (unsigned int i = 0; i < rounds_; ++i) { 54 | // this->linear_layers_[i].reset(new Prost256LinearLayer); 55 | // this->linear_layers_[i]->SetMasks(this->state_masks_[2*i].get(), this->state_masks_[2*i + 1].get()); 56 | // this->sbox_layers_[i].reset(new Prost256SboxLayer); 57 | // this->sbox_layers_[i]->SetMasks(this->state_masks_[2*i + 1].get(), this->state_masks_[2*i + 2].get()); 58 | // } 59 | // return *this; 60 | //} 61 | 62 | 63 | 64 | Permutation::PermPtr Prost256Permutation::clone() const { 65 | return PermPtr(new Prost256Permutation(*this)); 66 | } 67 | 68 | 69 | void Prost256Permutation::PrintWithProbability(std::ostream& stream, 70 | unsigned int offset) { 71 | Permutation::PrintWithProbability(stream, 0); 72 | } 73 | 74 | 75 | void Prost256Permutation::touchall() { 76 | Permutation::touchall(); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tool/permutation.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef PERMUTATION_H_ 28 | #define PERMUTATION_H_ 29 | 30 | #include 31 | #include 32 | 33 | #include "layer.h" 34 | #include "statemask.h" 35 | 36 | 37 | struct Permutation { 38 | typedef std::unique_ptr PermPtr; 39 | Permutation(unsigned int rounds); 40 | Permutation(const Permutation& other); 41 | virtual ~Permutation(){}; 42 | virtual bool checkchar(std::ostream& stream = std::cout); 43 | virtual bool update(); 44 | virtual void print(std::ostream& stream); 45 | virtual PermPtr clone() const = 0; 46 | virtual void set(Permutation* perm); 47 | virtual void save(); 48 | virtual void restore(); 49 | virtual void SboxStatus(std::vector& active, std::vector& inactive); 50 | virtual void SboxStatus(std::vector>& active, std::vector>& inactive); 51 | virtual bool isActive(SboxPos pos); 52 | virtual bool guessbestsbox(SboxPos pos, std::function rating); 53 | virtual bool guessbestsboxrandom(SboxPos pos, std::function rating, int num_alternatives); 54 | virtual bool guessbestsbox(SboxPos pos, std::function rating, int num_alternatives); 55 | virtual void PrintWithProbability(std::ostream& stream = std::cout, unsigned int offset = 0); 56 | virtual void touchall(); 57 | virtual double GetProbability(); 58 | virtual unsigned int GetActiveSboxes(); 59 | virtual bool setBit(BitMask cond, unsigned int bit); 60 | bool setBit(const char cond, unsigned int bit, unsigned char num_words, unsigned char num_bits); 61 | virtual bool setBox(bool active, unsigned int box_num); 62 | 63 | std::vector> state_masks_; 64 | std::vector> sbox_layers_; 65 | std::vector> linear_layers_; 66 | bool toupdate_linear; 67 | bool toupdate_nonlinear; 68 | unsigned int rounds_; 69 | 70 | std::vector> saved_state_masks_; 71 | std::vector> saved_sbox_layers_; 72 | std::vector> saved_linear_layers_; 73 | bool saved_toupdate_linear; 74 | bool saved_toupdate_nonlinear; 75 | }; 76 | 77 | 78 | #endif // PERMUTATION_H_ 79 | -------------------------------------------------------------------------------- /target/ascon_permutation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include 28 | #include "ascon_permutation.h" 29 | 30 | AsconPermutation::AsconPermutation(unsigned int rounds) 31 | : Permutation(rounds) { 32 | for (unsigned int i = 0; i < 2 * rounds + 1; ++i) { 33 | this->state_masks_[i].reset(new AsconState); 34 | this->saved_state_masks_[i].reset(new AsconState); 35 | } 36 | for (unsigned int i = 0; i < rounds; ++i) { 37 | this->sbox_layers_[i].reset(new AsconSboxLayer); 38 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2 * i].get(), 39 | this->state_masks_[2 * i + 1].get()); 40 | this->linear_layers_[i].reset(new AsconLinearLayer); 41 | this->linear_layers_[i]->SetMasks(this->state_masks_[2 * i + 1].get(), 42 | this->state_masks_[2 * i + 2].get()); 43 | this->saved_sbox_layers_[i].reset(new AsconSboxLayer); 44 | this->saved_sbox_layers_[i]->SetMasks( 45 | this->saved_state_masks_[2 * i].get(), 46 | this->saved_state_masks_[2 * i + 1].get()); 47 | this->saved_linear_layers_[i].reset(new AsconLinearLayer); 48 | this->saved_linear_layers_[i]->SetMasks( 49 | this->saved_state_masks_[2 * i + 1].get(), 50 | this->saved_state_masks_[2 * i + 2].get()); 51 | } 52 | touchall(); 53 | } 54 | 55 | AsconPermutation::AsconPermutation(const AsconPermutation& other) 56 | : Permutation(other) { 57 | 58 | for (unsigned int i = 0; i < 2 * rounds_ + 1; ++i) { 59 | this->saved_state_masks_[i].reset(new AsconState); 60 | } 61 | for (unsigned int i = 0; i < rounds_; ++i) { 62 | this->saved_sbox_layers_[i].reset(new AsconSboxLayer); 63 | this->saved_sbox_layers_[i]->SetMasks( 64 | this->saved_state_masks_[2 * i].get(), 65 | this->saved_state_masks_[2 * i + 1].get()); 66 | this->saved_linear_layers_[i].reset(new AsconLinearLayer); 67 | this->saved_linear_layers_[i]->SetMasks( 68 | this->saved_state_masks_[2 * i + 1].get(), 69 | this->saved_state_masks_[2 * i + 2].get()); 70 | } 71 | } 72 | 73 | Permutation::PermPtr AsconPermutation::clone() const { 74 | return PermPtr(new AsconPermutation(*this)); 75 | } 76 | 77 | void AsconPermutation::PrintWithProbability(std::ostream& stream, 78 | unsigned int offset) { 79 | Permutation::PrintWithProbability(stream, 0); 80 | } 81 | 82 | void AsconPermutation::touchall() { 83 | Permutation::touchall(); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /target/ascon.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef ASCON_H_ 28 | #define ASCON_H_ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "layer.h" 37 | #include "mask.h" 38 | #include "statemask.h" 39 | #include "step_linear.h" 40 | #include "step_nonlinear.h" 41 | #include "lrucache.h" 42 | 43 | 44 | struct AsconState : public StateMask<5,64> { 45 | AsconState(); 46 | friend std::ostream& operator<<(std::ostream& stream, const AsconState& statemask); 47 | void print(std::ostream& stream); 48 | virtual AsconState* clone(); 49 | }; 50 | 51 | 52 | #define ROTR(x,n) (((x)>>(n))|((x)<<(64-(n)))) 53 | //#define ROTL(x,n) (((x)<<(n))|((x)>>(64-(n)))) 54 | 55 | template 56 | std::array AsconSigma(std::array in) { 57 | switch (round) { 58 | case 0: 59 | return {in[0] ^ ROTR(in[0], 19) ^ ROTR(in[0], 28)}; 60 | case 1: 61 | return {in[0] ^ ROTR(in[0], 61) ^ ROTR(in[0], 39)}; 62 | case 2: 63 | return {in[0] ^ ROTR(in[0], 1) ^ ROTR(in[0], 6)}; 64 | case 3: 65 | return {in[0] ^ ROTR(in[0], 10) ^ ROTR(in[0], 17)}; 66 | case 4: 67 | return {in[0] ^ ROTR(in[0], 7) ^ ROTR(in[0], 41)}; 68 | default: 69 | return {0}; 70 | } 71 | } 72 | 73 | 74 | struct AsconLinearLayer : public LinearLayer { 75 | AsconLinearLayer& operator=(const AsconLinearLayer& rhs); 76 | AsconLinearLayer(); 77 | virtual AsconLinearLayer* clone(); 78 | void Init(); 79 | AsconLinearLayer(StateMaskBase *in, StateMaskBase *out); 80 | // bool Update(); 81 | virtual bool updateStep(unsigned int step_pos); 82 | unsigned int GetNumSteps(); 83 | virtual void copyValues(LinearLayer* other); 84 | 85 | static const unsigned int word_size_ = { 64 }; 86 | static const unsigned int words_per_step_ = { 1 }; 87 | static const unsigned int linear_steps_ = { 5 }; 88 | std::array, linear_steps_> sigmas; 89 | }; 90 | 91 | 92 | struct AsconSboxLayer : public SboxLayer<5, 64> { 93 | AsconSboxLayer& operator=(const AsconSboxLayer& rhs); 94 | AsconSboxLayer(); 95 | AsconSboxLayer(StateMaskBase *in, StateMaskBase *out); 96 | virtual AsconSboxLayer* clone(); 97 | // virtual bool Update(); 98 | virtual bool updateStep(unsigned int step_pos); 99 | Mask GetVerticalMask(unsigned int b, const StateMaskBase& s) const; 100 | void SetVerticalMask(unsigned int b, StateMaskBase& s, const Mask& mask); 101 | 102 | static const unsigned int cache_size_ = { 0x1000 }; 103 | static std::unique_ptr> cache_; 104 | static std::shared_ptr> ldt_; 105 | }; 106 | 107 | 108 | 109 | #endif // ASCON_H_ 110 | -------------------------------------------------------------------------------- /tool/statemask.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef STATEMASK_H_ 28 | #define STATEMASK_H_ 29 | 30 | #include 31 | 32 | struct StateMaskBase { 33 | virtual ~StateMaskBase(){}; 34 | virtual StateMaskBase* clone() = 0; 35 | virtual void print(std::ostream& stream) = 0; 36 | virtual void SetState(BitMask value) = 0; 37 | virtual void SetBit(BitMask value, int word_pos, int bit_pos) = 0; 38 | virtual bool diffLinear(const StateMaskBase& other) = 0; 39 | virtual bool diffSbox(const StateMaskBase& other) = 0; 40 | virtual void copyValues(const StateMaskBase* other) = 0; 41 | virtual void resetChangesLinear() = 0; 42 | virtual void resetChangesSbox() = 0; 43 | virtual bool changesforLinear() = 0; 44 | virtual bool changesforSbox() = 0; 45 | virtual unsigned long long& getWordLinear(const int index) = 0; 46 | virtual unsigned long long& getWordSbox(const int index) = 0; 47 | virtual Mask& operator[](const int index) = 0; 48 | virtual const Mask& operator[](const int index) const = 0; 49 | virtual const unsigned int getnumwords() const = 0; 50 | virtual const unsigned int getnumbits() const = 0; 51 | // TODO: Work on faster update 52 | // virtual unsigned long long int getChangesforLinearLayer(const int i) const = 0; 53 | // virtual unsigned long long getChangesforSboxLayer(const int i) const = 0; 54 | }; 55 | 56 | template 57 | struct StateMask : public StateMaskBase { 58 | StateMask(); 59 | virtual ~StateMask(){}; 60 | virtual StateMask* clone() = 0; 61 | virtual void print(std::ostream& stream) = 0; 62 | virtual void SetState(BitMask value); 63 | virtual void SetBit(BitMask value, int word_pos, int bit_pos); 64 | virtual bool diffLinear(const StateMaskBase& other); 65 | virtual bool diffSbox(const StateMaskBase& other); 66 | virtual void copyValues(const StateMaskBase* other); 67 | virtual void resetChangesLinear(); 68 | virtual void resetChangesSbox(); 69 | void resetChanges(std::array& changes); 70 | virtual bool changesforLinear(); 71 | virtual bool changesforSbox(); 72 | virtual unsigned long long& getWordLinear(const int index); 73 | virtual unsigned long long& getWordSbox(const int index); 74 | virtual Mask& operator[](const int index); 75 | virtual const Mask& operator[](const int index) const ; 76 | virtual const unsigned int getnumwords() const {return words;}; 77 | virtual const unsigned int getnumbits() const {return bits;}; 78 | // TODO: Work on faster update 79 | // virtual unsigned long long int getChangesforLinearLayer(const int i) const; 80 | // virtual unsigned long long getChangesforSboxLayer(const int i) const; 81 | 82 | protected: 83 | bool diff(const StateMaskBase& other, std::array& changes); 84 | 85 | public: 86 | std::array words_; 87 | std::array changes_for_linear_layer_; 88 | std::array changes_for_sbox_layer_; 89 | }; 90 | 91 | #include "statemask.hpp" 92 | 93 | #endif /* STATEMASK_H_ */ 94 | -------------------------------------------------------------------------------- /tool/commandlineparser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include 28 | #include "commandlineparser.h" 29 | 30 | 31 | Parameter::Parameter(std::string name, std::string helptext, const char *defaultvalue, const char* value) 32 | : name(name) 33 | , helptext(helptext) 34 | , defaultvalue(defaultvalue) 35 | , value(value) { 36 | } 37 | 38 | 39 | Commandlineparser::Commandlineparser(std::string description) 40 | : description_(description) 41 | , maxlen_(1) { 42 | } 43 | 44 | void Commandlineparser::addParameter(std::string parameter_switch, 45 | std::string helptext, 46 | const char* parameter) { 47 | auto added_parameter = params_.emplace(parameter_switch, Parameter(parameter_switch, helptext, parameter, parameter)); 48 | maxlen_ = std::max(maxlen_, (unsigned)parameter_switch.length()); 49 | assert(added_parameter.second); 50 | } 51 | 52 | const char* Commandlineparser::getParameter(std::string parameter_switch) { 53 | auto it = params_.find(parameter_switch); 54 | assert(it != params_.end()); 55 | return it->second.value; 56 | } 57 | 58 | int Commandlineparser::getIntParameter(std::string parameter_switch) { 59 | return atoi(getParameter(parameter_switch)); 60 | } 61 | 62 | float Commandlineparser::getFloatParameter(std::string parameter_switch) { 63 | return atof(getParameter(parameter_switch)); 64 | } 65 | 66 | bool Commandlineparser::getBoolParameter(std::string parameter_switch) { 67 | return getParameter(parameter_switch) != nullptr; 68 | } 69 | 70 | void Commandlineparser::parse(int& argc, const char* argv[]) { 71 | for (int i = 1; i < argc; ++i) { 72 | auto it = params_.find(std::string (argv[i])); 73 | if (it == params_.end()) 74 | print_fatal_error(std::string("Invalid parameter '") + argv[i] + "'!"); 75 | if (it->second.defaultvalue != nullptr) { 76 | ++i; 77 | if(i >= argc) 78 | print_fatal_error(std::string("Parameter for switch '") + argv[i-1] + "' is missing!"); 79 | it->second.value = argv[i]; 80 | } else { 81 | it->second.value = "true"; 82 | } 83 | } 84 | } 85 | 86 | void Commandlineparser::print_pars() { 87 | for (auto& entry : params_) { 88 | const Parameter& par = entry.second; 89 | std::string pad = " "; 90 | for (unsigned l = maxlen_; l >= par.name.length(); l--) 91 | pad += " "; 92 | std::string defaulttext = (par.defaultvalue == nullptr) ? "" : std::string(" (default '") + par.defaultvalue + "')"; 93 | std::cout << par.name << pad << par.helptext << defaulttext << std::endl; 94 | } 95 | } 96 | 97 | void Commandlineparser::print_fatal_error(std::string errmsg) { 98 | std::cout << "ERROR: " << errmsg << std::endl; 99 | std::cout << "Usage:" << std::endl; 100 | print_pars(); 101 | exit(-1); 102 | } 103 | 104 | void Commandlineparser::print_help() { 105 | std::cout << description_ << std::endl; 106 | std::cout << "Usage:" << std::endl; 107 | print_pars(); 108 | } 109 | -------------------------------------------------------------------------------- /tool/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "mask.h" 34 | #include "step_linear.h" 35 | #include "step_nonlinear.h" 36 | #include "ascon.h" 37 | #include "ascon_permutation.h" 38 | #include "search.h" 39 | #include "configparser.h" 40 | #include "commandlineparser.h" 41 | 42 | 43 | void config_search(Commandlineparser& args) { 44 | Configparser parser; 45 | 46 | bool config_ok = parser.parseFile(args.getParameter("-i")); 47 | 48 | if(config_ok == false) 49 | exit(config_ok); 50 | 51 | Search my_search(*parser.getPermutation()); 52 | my_search.StackSearch1(args, parser); 53 | } 54 | 55 | void config_search_keccak(Commandlineparser& args) { 56 | Configparser parser; 57 | 58 | bool config_ok = parser.parseFile(args.getParameter("-i")); 59 | 60 | if(config_ok == false) 61 | exit(config_ok); 62 | 63 | Search my_search(*parser.getPermutation()); 64 | my_search.StackSearchKeccak(args, parser); 65 | } 66 | 67 | void checkchar(Commandlineparser& args) { 68 | Configparser parser; 69 | 70 | bool config_ok = parser.parseFile(args.getParameter("-i")); 71 | 72 | if(config_ok == false) 73 | exit(config_ok); 74 | 75 | if (parser.getPermutation()->checkchar()) 76 | std::cout << "checkchar worked" << std::endl; 77 | else 78 | std::cout << "checkchar failed" << std::endl; 79 | } 80 | 81 | // ==== Main / Search ==== 82 | int main(int argc, const char* argv[]) { 83 | 84 | Commandlineparser args("Tool to automatically search for linear characteristics"); 85 | 86 | args.addParameter("-iter", "max number of iterations or -1 for unlimited", "-1"); 87 | args.addParameter("-S", "Multiple of -I where current characteristic is printed", "5"); 88 | args.addParameter("-I", "Status update interval", "2"); 89 | 90 | args.addParameter("-i", "characteristic input file", "examples/ascon_3_rounds_typeI.xml"); 91 | args.addParameter("-u", "requested function: checkchar, search", "search"); 92 | 93 | args.addParameter("-h", "display help", nullptr); 94 | 95 | args.parse(argc, argv); 96 | 97 | if (args.getBoolParameter("-h") || argc == 1) { 98 | args.print_help(); 99 | } else if (std::strcmp(args.getParameter("-u"), "checkchar") == 0) { 100 | std::cout << "Checking characteristic ... " << std::endl; 101 | std::cout << "Configfile: " << args.getParameter("-i") << std::endl; 102 | checkchar(args); 103 | } else if (std::strcmp(args.getParameter("-u"), "keccak") == 0) { 104 | std::cout << "Searching ... " << std::endl; 105 | std::cout << "Configfile: " << args.getParameter("-i") << std::endl; 106 | std::cout << "Iterations: " << args.getIntParameter("-iter") << std::endl; 107 | config_search_keccak(args); 108 | } else { 109 | std::cout << "Searching ... " << std::endl; 110 | std::cout << "Configfile: " << args.getParameter("-i") << std::endl; 111 | std::cout << "Iterations: " << args.getIntParameter("-iter") << std::endl; 112 | config_search(args); 113 | } 114 | 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /tool/step_nonlinear.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef STEPNONLINEAR_H_ 28 | #define STEPNONLINEAR_H_ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "cache.h" 43 | #include "mask.h" 44 | 45 | struct NonlinearStepUpdateInfo{ 46 | bool is_active_; 47 | bool is_guessable_; 48 | WordMask inmask_; 49 | WordMask outmask_; 50 | }; 51 | 52 | template struct LinearDistributionTable; 53 | template std::ostream& operator<<(std::ostream& stream, const LinearDistributionTable& ldt); 54 | 55 | template 56 | struct LinearDistributionTable { 57 | LinearDistributionTable() = default; 58 | LinearDistributionTable(std::function fun); 59 | void Initialize(std::function fun); 60 | LinearDistributionTable& operator=(const LinearDistributionTable& rhs); 61 | 62 | friend std::ostream& operator<<<>(std::ostream& stream, const LinearDistributionTable& ldt); 63 | 64 | std::vector> ldt; // TODO check datatype! 65 | std::vector> ldt_bool; // TODO check datatype! 66 | }; 67 | 68 | template struct NonlinearStep; 69 | template std::ostream& operator<<(std::ostream& stream, const NonlinearStep& step); 70 | 71 | template 72 | struct NonlinearStep { 73 | // static_assert((bitsize == 3 || bitsize == 5), "Check if nonlinearstep supports your bitsize."); 74 | 75 | NonlinearStep() = default; 76 | NonlinearStep(std::function fun); 77 | void Initialize(std::function fun); 78 | void Initialize(std::shared_ptr> ldt); 79 | double GetProbability(Mask& x, Mask& y); 80 | bool Update(Mask& x, Mask& y); 81 | bool Update(Mask& x, Mask& y, Cache* box_cache); 82 | void TakeBestBox(Mask& x, Mask& y, std::function rating); 83 | int TakeBestBox(Mask& x, Mask& y, std::function rating, int pos); 84 | void TakeBestBoxRandom(Mask& x, Mask& y, std::function rating); 85 | unsigned long long getKey(Mask& in, Mask& out); 86 | void create_masks(std::vector &masks, Mask& reference, unsigned int pos = 0, unsigned int current_mask = 0); 87 | NonlinearStep& operator=(const NonlinearStep& rhs); 88 | 89 | friend std::ostream& operator<<<>(std::ostream& stream, const NonlinearStep& step); 90 | 91 | std::shared_ptr> ldt_; 92 | bool is_active_; 93 | bool is_guessable_; 94 | bool has_to_be_active_; 95 | static std::vector inmasks_, outmasks_; 96 | static std::multimap, std::greater> valid_masks_; 97 | }; 98 | 99 | #include "step_nonlinear.hpp" 100 | 101 | #endif // STEPLINEAR_H_ 102 | -------------------------------------------------------------------------------- /tool/mask.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include "mask.h" 28 | 29 | WordMaskCare& WordMaskCare::operator=(const WordMaskCare& rhs) 30 | { 31 | canbe1 = rhs.canbe1; 32 | care = rhs.care; 33 | return *this; 34 | } 35 | 36 | WordMaskCare::WordMaskCare(unsigned bitsize) : canbe1(~0ULL >> (64 - bitsize)), care(0) { 37 | } 38 | 39 | WordMaskCare::WordMaskCare(const WordMaskCare& other) : canbe1(other.canbe1), care(other.care) { 40 | } 41 | 42 | WordMaskCare::WordMaskCare(BitVector canbe1, BitVector care) : canbe1(canbe1), care(care) { 43 | } 44 | 45 | void WordMaskCare::Reset() { 46 | canbe1 |= care; 47 | canbe1 |= (canbe1 >> 1); 48 | canbe1 |= (canbe1 >> 2); 49 | canbe1 |= (canbe1 >> 4); 50 | canbe1 |= (canbe1 >> 8); 51 | canbe1 |= (canbe1 >> 16); 52 | canbe1 |= (canbe1 >> 32); 53 | care = 0; 54 | } 55 | 56 | //----------------------------------------------------------------------------- 57 | Mask& Mask::operator=(const Mask& rhs) 58 | { 59 | bitmasks = rhs.bitmasks; 60 | caremask = rhs.caremask; 61 | bitsize_ = rhs.bitsize_; 62 | changes_ = rhs.changes_; 63 | return *this; 64 | } 65 | 66 | Mask::Mask() : caremask(64), bitsize_(64), changes_(~0ULL) { 67 | } 68 | 69 | Mask::Mask(unsigned bitsize) : caremask(bitsize), bitsize_(bitsize), changes_(~0ULL) { 70 | init_bitmasks(); 71 | } 72 | 73 | Mask::Mask(const Mask& other) : bitmasks(other.bitmasks), caremask(other.caremask), bitsize_(other.bitsize_), changes_(~0ULL) { 74 | } 75 | 76 | Mask::Mask(std::initializer_list other) : bitmasks(other), caremask(other.size()), bitsize_(other.size()), changes_(~0ULL) { 77 | init_caremask(); 78 | } 79 | 80 | Mask::Mask(WordMask& other) : bitmasks(other), caremask(other.size()), bitsize_(other.size()), changes_(~0ULL) { 81 | init_caremask(); 82 | } 83 | 84 | 85 | void Mask::set_bit(BitMask bit, const int index){ 86 | assert(bit <= 3 && bit >=0 && index >= 0 && index < 64); 87 | bitmasks[index] = bit; 88 | changes_ |= 1 << index; 89 | BitVector hole = ~0ULL - 1; 90 | hole = (hole << index) | (hole >> (64-index)); 91 | caremask.canbe1 &= hole; 92 | caremask.care &= hole; 93 | caremask.canbe1 |= ((BitVector)(bit & 1)) << index; 94 | caremask.care |= (((BitVector)(bit != BM_DUNNO)) << index); 95 | 96 | } 97 | 98 | void Mask::reinit_caremask(){ 99 | BitVector canbe1 = 0; 100 | BitVector care = 0; 101 | for (unsigned i = 0; i < bitmasks.size(); ++i) { 102 | canbe1 |= ((((BitVector)(bitmasks[i] != BM_0)) << i)); 103 | care |= (((BitVector)(bitmasks[i] != BM_DUNNO)) << i); 104 | } 105 | changes_ = caremask.canbe1 ^ canbe1; 106 | changes_ |= caremask.care ^ care; 107 | caremask.canbe1 = canbe1; 108 | caremask.care = care; 109 | } 110 | 111 | void Mask::init_caremask() { 112 | caremask.Reset(); 113 | for (unsigned i = 0; i < bitmasks.size(); ++i) { 114 | caremask.canbe1 &= (~0ULL ^ (((BitVector)(bitmasks[i] == BM_0)) << i)); 115 | caremask.care |= (((BitVector)(bitmasks[i] != BM_DUNNO)) << i); 116 | } 117 | } 118 | 119 | void Mask::init_bitmasks() { 120 | bitmasks.resize(bitsize_); 121 | for(auto& bitmask : bitmasks ) 122 | bitmask = BM_DUNNO; 123 | } 124 | 125 | void Mask::reinit_bitmasks() { 126 | BitVector canbe1 = caremask.canbe1; 127 | BitVector care = caremask.care; 128 | 129 | int i = 0; 130 | 131 | changes_ = 0; 132 | 133 | while (canbe1 | care) { 134 | unsigned char bitval = ((canbe1 & 1) | ((!(canbe1 & care & 1)) << 1)); 135 | changes_ |= (( (BitVector) (bitmasks[i] != bitval))&1) << i; 136 | bitmasks[i++] = bitval; 137 | canbe1 >>= 1; 138 | care >>= 1; 139 | } 140 | 141 | } 142 | 143 | void Mask::reset(int bitsize) { 144 | bitsize_ = bitsize; 145 | caremask.canbe1 = ~0ULL >> (64 - bitsize); 146 | caremask.care = 0; 147 | init_bitmasks(); 148 | } 149 | 150 | std::ostream& operator<<(std::ostream& stream, const Mask& mask) { 151 | char symbol[4] {'#', '1', '0', '?'}; 152 | for (BitMask m : mask.bitmasks) 153 | stream << symbol[m % 4]; 154 | return stream; 155 | } 156 | -------------------------------------------------------------------------------- /tool/step_linear.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef STEPLINEAR_H_ 28 | #define STEPLINEAR_H_ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "cache.h" 37 | #include "mask.h" 38 | 39 | template struct Row; // forward declaration for friends below 40 | template Row operator^(const Row& left, const Row& right); 41 | template Row operator&(const Row& left, const Row& right); 42 | template Row operator|(const Row& left, const Row& right); 43 | template bool operator==(const Row& left, const Row& right); 44 | template std::ostream& operator<<(std::ostream& stream, const Row& row); 45 | 46 | template 47 | struct Row { 48 | static_assert((bitsize == 64 || bitsize == 32 || bitsize == 8 || bitsize == 2), "Check if linearstep supports your bitsize."); 49 | 50 | Row(std::array x, std::array y, bool rhs); 51 | Row GetPivotRow(); 52 | bool IsContradiction(); 53 | bool IsEmpty(); 54 | bool IsXSingleton(); 55 | bool IsYSingleton(); 56 | bool CommonVariableWith(const Row& other); 57 | bool ExtractMaskInfoX(std::array& x); 58 | bool ExtractMaskInfoY(std::array& y); 59 | Row& operator^=(const Row& right); 60 | Row& operator&=(const Row& right); 61 | Row& operator|=(const Row& right); 62 | 63 | friend Row operator^<>(const Row& left, const Row& right); 64 | friend Row operator&<>(const Row& left, const Row& right); 65 | friend Row operator|<>(const Row& left, const Row& right); 66 | friend bool operator==<>(const Row& left, const Row& right); 67 | friend std::ostream& operator<<<>(std::ostream& stream, const Row& row); 68 | 69 | private: 70 | std::array x; 71 | std::array y; 72 | bool rhs; 73 | }; 74 | 75 | //----------------------------------------------------------------------------- 76 | 77 | template 78 | struct LinearStepUpdateInfo{ 79 | std::vector> rows; 80 | std::array inmask_; 81 | std::array outmask_; 82 | }; 83 | 84 | //----------------------------------------------------------------------------- 85 | 86 | template struct LinearStep; // template for friends below 87 | template std::ostream& operator<<(std::ostream& stream, const LinearStep& sys); 88 | 89 | template 90 | struct LinearStep { 91 | static_assert((bitsize == 64 || bitsize == 32 || bitsize == 8 || bitsize == 2), "Check if linearstep supports your bitsize."); 92 | 93 | LinearStep(); 94 | LinearStep(std::function(std::array)> fun); 95 | void Initialize(std::function(std::array)> fun); 96 | bool AddMasks(std::array& x, std::array& y); 97 | bool AddRow(const Row& row); 98 | bool ExtractMasks(std::array& x, std::array& y); 99 | bool Update(std::array x, std::array y); 100 | LinearStep& operator=(const LinearStep& rhs); 101 | 102 | friend std::ostream& operator<<<>(std::ostream& stream, const LinearStep& sys); 103 | 104 | std::function(std::array)> fun_; 105 | std::vector> rows; 106 | }; 107 | 108 | #include "step_linear.hpp" 109 | 110 | #endif // STEPLINEAR_H_ 111 | -------------------------------------------------------------------------------- /tool/statemask.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | template 28 | StateMask::StateMask() { 29 | for (unsigned int i = 0; i < words; ++i){ 30 | words_[i].reset(bits); 31 | changes_for_linear_layer_[i] = ~0ULL; 32 | changes_for_sbox_layer_[i] = ~0ULL; 33 | } 34 | } 35 | 36 | template 37 | Mask& StateMask::operator[](const int index) { 38 | return words_[index]; 39 | } 40 | 41 | template 42 | const Mask& StateMask::operator[](const int index) const { 43 | return words_[index]; 44 | } 45 | 46 | template 47 | void StateMask::SetState(BitMask value) { 48 | for (unsigned int j = 0; j < words; ++j) { 49 | for (unsigned int i = 0; i < bits; ++i) 50 | words_[j].bitmasks[i] = value; 51 | words_[j].reinit_caremask(); 52 | } 53 | } 54 | 55 | template 56 | void StateMask::SetBit(BitMask value, int word_pos, int bit_pos) { 57 | words_.at(word_pos).set_bit(value, bit_pos); 58 | } 59 | 60 | template 61 | bool StateMask::diffLinear(const StateMaskBase& other) { 62 | return diff(other, changes_for_linear_layer_); 63 | } 64 | 65 | template 66 | bool StateMask::diffSbox(const StateMaskBase& other) { 67 | return diff(other, changes_for_sbox_layer_); 68 | } 69 | 70 | template 71 | bool StateMask::diff( 72 | const StateMaskBase& other, 73 | std::array& changes) { 74 | 75 | for (unsigned int i = 0; i < words; ++i) { 76 | changes[i] |= (words_[i].caremask.canbe1 ^ other[i].caremask.canbe1) 77 | | (words_[i].caremask.care ^ other[i].caremask.care); 78 | } 79 | 80 | //TODO: Maybe do not need this if using a better update 81 | for (unsigned int i = 0; i < words; ++i) 82 | if(changes[i] != 0) 83 | return true; 84 | 85 | return false; 86 | } 87 | 88 | template 89 | bool StateMask::changesforLinear() { 90 | for (unsigned int i = 0; i < words; ++i) 91 | if(changes_for_linear_layer_[i] != 0) 92 | return true; 93 | 94 | return false; 95 | } 96 | 97 | template 98 | bool StateMask::changesforSbox() { 99 | for (unsigned int i = 0; i < words; ++i) 100 | if(changes_for_sbox_layer_[i] != 0) 101 | return true; 102 | 103 | return false; 104 | } 105 | 106 | template 107 | void StateMask::copyValues(const StateMaskBase* other) { 108 | //TODO: maybe use static cast 109 | const StateMask* ptr = dynamic_cast*>(other); 110 | words_ = ptr->words_; 111 | changes_for_linear_layer_ = ptr->changes_for_linear_layer_; 112 | changes_for_sbox_layer_ = ptr->changes_for_sbox_layer_; 113 | 114 | // TODO: Work on faster update 115 | // for(int i = 0; i< words ; ++i){ 116 | // words_[i] = other[i]; 117 | // changes_for_linear_layer_[i] = other.getChangesforLinearLayer(i); 118 | // changes_for_sbox_layer_[i] = other.getChangesforSboxLayer(i); 119 | // } 120 | } 121 | 122 | template 123 | void StateMask::resetChangesLinear() { 124 | resetChanges(changes_for_linear_layer_); 125 | } 126 | 127 | template 128 | void StateMask::resetChangesSbox() { 129 | resetChanges(changes_for_sbox_layer_); 130 | } 131 | 132 | template 133 | void StateMask::resetChanges( 134 | std::array& changes) { 135 | for (unsigned int i = 0; i < words; ++i) 136 | changes[i] = 0; 137 | } 138 | 139 | template 140 | unsigned long long& StateMask::getWordLinear( 141 | const int index) { 142 | 143 | return changes_for_linear_layer_[index]; 144 | } 145 | 146 | template 147 | unsigned long long& StateMask::getWordSbox( 148 | const int index) { 149 | 150 | return changes_for_sbox_layer_[index]; 151 | } 152 | 153 | // TODO: Work on faster update 154 | //template 155 | //unsigned long long int StateMask::getChangesforLinearLayer( 156 | // int index) { 157 | // 158 | // return changes_for_linear_layer_[index]; 159 | //} 160 | // 161 | //template 162 | //unsigned long long StateMask::getChangesforSboxLayer( 163 | // int index) { 164 | // 165 | // return changes_for_sbox_layer_[index]; 166 | //} 167 | 168 | -------------------------------------------------------------------------------- /examples/prost256_4_rounds_typeI.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /target/prost256.cpp: -------------------------------------------------------------------------------- 1 | #include "prost256.h" 2 | 3 | //#define HEXOUTPUT 4 | //#define LATEX 5 | 6 | Prost256State::Prost256State() 7 | : StateMask() { 8 | } 9 | 10 | Prost256State* Prost256State::clone() { 11 | Prost256State* obj = new Prost256State(); 12 | for (size_t j = 0; j < words_.size(); ++j) { 13 | obj->words_[j] = words_[j]; 14 | obj->changes_for_linear_layer_[j] = changes_for_linear_layer_[j]; 15 | obj->changes_for_sbox_layer_[j] = changes_for_sbox_layer_[j]; 16 | } 17 | return obj; 18 | } 19 | 20 | void Prost256State::print(std::ostream& stream) { 21 | stream << *this; 22 | } 23 | 24 | #ifdef HEXOUTPUT 25 | #ifdef LATEX 26 | std::ostream& operator<<(std::ostream& stream, const Prost256State& statemask) { 27 | 28 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 29 | unsigned long long outword = 0; 30 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 31 | outword <<= 1; 32 | if (*it % 4 == 1) 33 | outword |=1; 34 | } 35 | stream << " & \\texttt{" << std::hex << std::setfill('0') << std::setw(8) << outword << std::dec << "}"; 36 | if(i%4 == 3) 37 | stream << " \\\\ "<< std::endl; 38 | } 39 | // stream << " \\\\ "<< std::endl; 40 | return stream; 41 | } 42 | #else 43 | std::ostream& operator<<(std::ostream& stream, const Prost256State& statemask) { 44 | 45 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 46 | unsigned long long outword = 0; 47 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 48 | outword <<= 1; 49 | if (*it % 4 == 1) 50 | outword |=1; 51 | } 52 | stream << std::hex << std::setfill('0') << std::setw(8) << outword << std::dec << "\t"; 53 | if(i%4 == 3) 54 | stream << std::endl; 55 | } 56 | return stream; 57 | } 58 | #endif 59 | #else 60 | std::ostream& operator<<(std::ostream& stream, const Prost256State& statemask) { 61 | #ifndef TERMINALCOLORS 62 | char symbol[4] {'#', '1', '0', '?'}; 63 | #else 64 | std::string symbol[4] { "\033[1;35m#\033[0m", "\033[1;31m1\033[0m", "0", 65 | "\033[1;33m?\033[0m" }; 66 | #endif 67 | for (Mask word : statemask.words_) { 68 | for (auto it = word.bitmasks.rbegin(); it != word.bitmasks.rend(); ++it) { 69 | stream << symbol[*it % 4]; 70 | } 71 | stream << std::endl; 72 | } 73 | return stream; 74 | } 75 | #endif 76 | 77 | 78 | //----------------------------------------------------------------------------- 79 | 80 | BitVector Prost256Sbox(BitVector in) { 81 | static const BitVector sbox[16] = { 82 | 0,4,8,0xf,1,5,0xe,9,2,7,0xa,0xc,0xb,0xd,6,3}; 83 | return sbox[in % 16] & 0xf; 84 | } 85 | 86 | std::unique_ptr> Prost256SboxLayer::cache_; 87 | std::shared_ptr> Prost256SboxLayer::ldt_; 88 | 89 | Prost256SboxLayer& Prost256SboxLayer::operator=(const Prost256SboxLayer& rhs) { 90 | sboxes = rhs.sboxes; 91 | return *this; 92 | } 93 | 94 | Prost256SboxLayer::Prost256SboxLayer() { 95 | if(ldt_ == nullptr) 96 | ldt_.reset(new LinearDistributionTable<4>(Prost256Sbox)); 97 | InitSboxes(ldt_); 98 | if (this->cache_.get() == nullptr) 99 | this->cache_.reset( 100 | new LRU_Cache( 101 | cache_size_)); 102 | } 103 | 104 | Prost256SboxLayer::Prost256SboxLayer(StateMaskBase *in, StateMaskBase *out) 105 | : SboxLayer(in, out) { 106 | if(ldt_ == nullptr) 107 | ldt_.reset(new LinearDistributionTable<4>(Prost256Sbox)); 108 | InitSboxes(ldt_); 109 | if (this->cache_.get() == nullptr) 110 | this->cache_.reset( 111 | new LRU_Cache( 112 | cache_size_)); 113 | } 114 | 115 | Prost256SboxLayer* Prost256SboxLayer::clone() { 116 | //TODO: write copy constructor 117 | Prost256SboxLayer* obj = new Prost256SboxLayer(in, out); 118 | obj->sboxes = this->sboxes; 119 | return obj; 120 | } 121 | 122 | bool Prost256SboxLayer::updateStep(unsigned int step_pos) { 123 | assert(step_pos < sboxes.size()); 124 | bool ret_val; 125 | Mask copyin(GetVerticalMask(step_pos, *in)); 126 | Mask copyout(GetVerticalMask(step_pos, *out)); 127 | ret_val = sboxes[step_pos].Update(copyin, copyout, cache_.get()); 128 | SetVerticalMask(step_pos, *in, copyin); 129 | SetVerticalMask(step_pos, *out, copyout); 130 | return ret_val; 131 | } 132 | 133 | Mask Prost256SboxLayer::GetVerticalMask(unsigned int b, 134 | const StateMaskBase& s) const { 135 | return Mask( 136 | { s[((b/32)*4)+3].bitmasks[b%32], s[((b/32)*4)+2].bitmasks[b%32], s[((b/32)*4)+1].bitmasks[b%32], 137 | s[((b/32)*4)+0].bitmasks[b%32] }); 138 | } 139 | 140 | void Prost256SboxLayer::SetVerticalMask(unsigned int b, StateMaskBase& s, 141 | const Mask& mask) { 142 | 143 | // TODO: Test faster update 144 | // s.getWordLinear(((b/32)*4)+0) |= ((mask.changes_>>(3))&1) << b%32; 145 | // s.getWordLinear(((b/32)*4)+1) |= ((mask.changes_>>(2))&1) << b%32; 146 | // s.getWordLinear(((b/32)*4)+2) |= ((mask.changes_>>(1))&1) << b%32; 147 | // s.getWordLinear(((b/32)*4)+3) |= ((mask.changes_>>(0))&1) << b%32; 148 | 149 | s[((b/32)*4)+0].bitmasks[b%32] = mask.bitmasks[3]; 150 | s[((b/32)*4)+1].bitmasks[b%32] = mask.bitmasks[2]; 151 | s[((b/32)*4)+2].bitmasks[b%32] = mask.bitmasks[1]; 152 | s[((b/32)*4)+3].bitmasks[b%32] = mask.bitmasks[0]; 153 | BitVector m = ~(1ULL << (b%32)); 154 | s[((b/32)*4)+0].caremask.canbe1 = (s[((b/32)*4)+0].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 3) & 1) << (b%32)); 155 | s[((b/32)*4)+1].caremask.canbe1 = (s[((b/32)*4)+1].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 2) & 1) << (b%32)); 156 | s[((b/32)*4)+2].caremask.canbe1 = (s[((b/32)*4)+2].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 1) & 1) << (b%32)); 157 | s[((b/32)*4)+3].caremask.canbe1 = (s[((b/32)*4)+3].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 0) & 1) << (b%32)); 158 | 159 | s[((b/32)*4)+0].caremask.care = (s[((b/32)*4)+0].caremask.care & m) | (((mask.caremask.care >> 3) & 1) << (b%32)); 160 | s[((b/32)*4)+1].caremask.care = (s[((b/32)*4)+1].caremask.care & m) | (((mask.caremask.care >> 2) & 1) << (b%32)); 161 | s[((b/32)*4)+2].caremask.care = (s[((b/32)*4)+2].caremask.care & m) | (((mask.caremask.care >> 1) & 1) << (b%32)); 162 | s[((b/32)*4)+3].caremask.care = (s[((b/32)*4)+3].caremask.care & m) | (((mask.caremask.care >> 0) & 1) << (b%32)); 163 | } 164 | 165 | -------------------------------------------------------------------------------- /target/icepole_permutation.cpp: -------------------------------------------------------------------------------- 1 | #include "icepole_permutation.h" 2 | 3 | 4 | IcepolePermutation::IcepolePermutation(unsigned int rounds) : Permutation(rounds) { 5 | for(unsigned int i = 0; i< 2*rounds +1; ++i){ 6 | this->state_masks_[i].reset(new IcepoleState); 7 | this->saved_state_masks_[i].reset(new IcepoleState); 8 | } 9 | for (unsigned int i = 0; i < rounds; ++i) { 10 | this->linear_layers_[i].reset(new IcepoleLinearLayer); 11 | this->linear_layers_[i]->SetMasks(this->state_masks_[2*i].get(), this->state_masks_[2*i + 1].get()); 12 | this->sbox_layers_[i].reset(new IcepoleSboxLayer); 13 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2*i + 1].get(), this->state_masks_[2*i + 2].get()); 14 | this->saved_linear_layers_[i].reset(new IcepoleLinearLayer); 15 | this->saved_linear_layers_[i]->SetMasks(this->saved_state_masks_[2*i].get(), this->saved_state_masks_[2*i + 1].get()); 16 | this->saved_sbox_layers_[i].reset(new IcepoleSboxLayer); 17 | this->saved_sbox_layers_[i]->SetMasks(this->saved_state_masks_[2*i + 1].get(), this->saved_state_masks_[2*i + 2].get()); 18 | } 19 | touchall(); 20 | } 21 | 22 | 23 | IcepolePermutation::IcepolePermutation(const IcepolePermutation& other) : Permutation(other.rounds_) { 24 | for (unsigned int i = 0; i < 2 * rounds_ + 1; ++i) { 25 | this->state_masks_[i].reset(other.state_masks_[i]->clone()); 26 | } 27 | 28 | for (unsigned int i = 0; i < rounds_; ++i) { 29 | this->sbox_layers_[i].reset(other.sbox_layers_[i]->clone()); 30 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2 * i +1].get(), 31 | this->state_masks_[2 * i + 2].get()); 32 | this->linear_layers_[i].reset(other.linear_layers_[i]->clone()); 33 | this->linear_layers_[i]->SetMasks(this->state_masks_[2 * i + 0].get(), 34 | this->state_masks_[2 * i + 1].get()); 35 | } 36 | this->toupdate_linear = other.toupdate_linear; 37 | this->toupdate_nonlinear = other.toupdate_nonlinear; 38 | 39 | for(unsigned int i = 0; i< 2*rounds_ +1; ++i){ 40 | this->saved_state_masks_[i].reset(new IcepoleState); 41 | } 42 | for (unsigned int i = 0; i < rounds_; ++i) { 43 | this->saved_linear_layers_[i].reset(new IcepoleLinearLayer); 44 | this->saved_linear_layers_[i]->SetMasks(this->saved_state_masks_[2*i].get(), this->saved_state_masks_[2*i + 1].get()); 45 | this->saved_sbox_layers_[i].reset(new IcepoleSboxLayer); 46 | this->saved_sbox_layers_[i]->SetMasks(this->saved_state_masks_[2*i + 1].get(), this->saved_state_masks_[2*i + 2].get()); 47 | } 48 | } 49 | 50 | 51 | void IcepolePermutation::set(Permutation* perm) { 52 | for (unsigned int i = 0; i < 2 * rounds_ + 1; ++i) { 53 | this->state_masks_[i].reset(perm->state_masks_[i]->clone()); 54 | } 55 | 56 | for (unsigned int i = 0; i < rounds_; ++i) { 57 | this->sbox_layers_[i].reset(perm->sbox_layers_[i]->clone()); 58 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2 * i +1].get(), 59 | this->state_masks_[2 * i + 2].get()); 60 | this->linear_layers_[i].reset(perm->linear_layers_[i]->clone()); 61 | this->linear_layers_[i]->SetMasks(this->state_masks_[2 * i + 0].get(), 62 | this->state_masks_[2 * i + 1].get()); 63 | } 64 | this->toupdate_linear = perm->toupdate_linear; 65 | this->toupdate_nonlinear = perm->toupdate_nonlinear; 66 | } 67 | 68 | 69 | IcepolePermutation& IcepolePermutation::operator=(const IcepolePermutation& rhs){ 70 | for(unsigned int i = 0; i< 2*rounds_ +1; ++i){ 71 | this->state_masks_[i].reset(rhs.state_masks_[i]->clone()); 72 | } 73 | this->toupdate_linear = rhs.toupdate_linear; 74 | this->toupdate_nonlinear = rhs.toupdate_nonlinear; 75 | for (unsigned int i = 0; i < rounds_; ++i) { 76 | this->linear_layers_[i].reset(new IcepoleLinearLayer); 77 | this->linear_layers_[i]->SetMasks(this->state_masks_[2*i].get(), this->state_masks_[2*i + 1].get()); 78 | this->sbox_layers_[i].reset(new IcepoleSboxLayer); 79 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2*i + 1].get(), this->state_masks_[2*i + 2].get()); 80 | } 81 | return *this; 82 | } 83 | 84 | 85 | bool IcepolePermutation::update() { 86 | std::unique_ptr tempin, tempout; 87 | bool update_before, update_after; 88 | while (this->toupdate_linear == true || this->toupdate_nonlinear == true) { 89 | if (this->toupdate_nonlinear == true) { 90 | this->toupdate_nonlinear = false; 91 | for (unsigned int layer = 0; layer < rounds_; ++layer) { 92 | tempin.reset(this->sbox_layers_[layer]->in->clone()); 93 | tempout.reset(this->sbox_layers_[layer]->out->clone()); 94 | if (this->sbox_layers_[layer]->Update() == false) 95 | return false; 96 | update_before = this->sbox_layers_[layer]->in->diffLinear(*(tempin)); 97 | update_after = this->sbox_layers_[layer]->out->diffLinear(*(tempout)); 98 | // update_before = this->sbox_layers_[layer]->in->changesforLinear(); 99 | // update_after = this->sbox_layers_[layer]->out->changesforLinear(); 100 | if(((update_after == true) && (layer != rounds_ - 1)) || update_before) 101 | this->toupdate_linear = true; 102 | } 103 | } 104 | if (this->toupdate_linear == true) { 105 | this->toupdate_linear = false; 106 | for (unsigned int layer = 0; layer < rounds_; ++layer) { 107 | tempin.reset(this->linear_layers_[layer]->in->clone()); 108 | tempout.reset(this->linear_layers_[layer]->out->clone()); 109 | if (this->linear_layers_[layer]->Update() == false) 110 | return false; 111 | update_before = this->linear_layers_[layer]->in->diffSbox(*(tempin)); 112 | update_after = this->linear_layers_[layer]->out->diffSbox(*(tempout)); 113 | // update_before = this->sbox_layers_[layer]->in->changesforSbox(); 114 | // update_after = this->sbox_layers_[layer]->out->changesforSbox(); 115 | if(((update_before == true) && (layer != 0)) || update_after) 116 | this->toupdate_nonlinear = true; 117 | } 118 | } 119 | } 120 | return true; 121 | } 122 | 123 | 124 | Permutation::PermPtr IcepolePermutation::clone() const { 125 | return PermPtr(new IcepolePermutation(*this)); 126 | } 127 | 128 | 129 | void IcepolePermutation::PrintWithProbability(std::ostream& stream, 130 | unsigned int offset) { 131 | Permutation::PrintWithProbability(stream, 1); 132 | } 133 | 134 | 135 | void IcepolePermutation::touchall() { 136 | Permutation::touchall(); 137 | } 138 | 139 | -------------------------------------------------------------------------------- /target/keccak1600_permutation.cpp: -------------------------------------------------------------------------------- 1 | #include "keccak1600_permutation.h" 2 | 3 | 4 | Keccak1600Permutation::Keccak1600Permutation(unsigned int rounds) : Permutation(rounds) { 5 | for(unsigned int i = 0; i< 2*rounds +1; ++i){ 6 | this->state_masks_[i].reset(new Keccak1600State); 7 | this->saved_state_masks_[i].reset(new Keccak1600State); 8 | } 9 | for (unsigned int i = 0; i < rounds; ++i) { 10 | this->linear_layers_[i].reset(new Keccak1600LinearLayer); 11 | this->linear_layers_[i]->SetMasks(this->state_masks_[2*i].get(), this->state_masks_[2*i + 1].get()); 12 | this->sbox_layers_[i].reset(new Keccak1600SboxLayer); 13 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2*i + 1].get(), this->state_masks_[2*i + 2].get()); 14 | this->saved_linear_layers_[i].reset(new Keccak1600LinearLayer); 15 | this->saved_linear_layers_[i]->SetMasks(this->saved_state_masks_[2*i].get(), this->saved_state_masks_[2*i + 1].get()); 16 | this->saved_sbox_layers_[i].reset(new Keccak1600SboxLayer); 17 | this->saved_sbox_layers_[i]->SetMasks(this->saved_state_masks_[2*i + 1].get(), this->saved_state_masks_[2*i + 2].get()); 18 | } 19 | touchall(); 20 | } 21 | 22 | 23 | Keccak1600Permutation::Keccak1600Permutation(const Keccak1600Permutation& other) : Permutation(other.rounds_) { 24 | for (unsigned int i = 0; i < 2 * rounds_ + 1; ++i) { 25 | this->state_masks_[i].reset(other.state_masks_[i]->clone()); 26 | } 27 | 28 | for (unsigned int i = 0; i < rounds_; ++i) { 29 | this->sbox_layers_[i].reset(other.sbox_layers_[i]->clone()); 30 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2 * i +1].get(), 31 | this->state_masks_[2 * i + 2].get()); 32 | this->linear_layers_[i].reset(other.linear_layers_[i]->clone()); 33 | this->linear_layers_[i]->SetMasks(this->state_masks_[2 * i + 0].get(), 34 | this->state_masks_[2 * i + 1].get()); 35 | } 36 | this->toupdate_linear = other.toupdate_linear; 37 | this->toupdate_nonlinear = other.toupdate_nonlinear; 38 | 39 | for(unsigned int i = 0; i< 2*rounds_ +1; ++i){ 40 | this->saved_state_masks_[i].reset(new Keccak1600State); 41 | } 42 | for (unsigned int i = 0; i < rounds_; ++i) { 43 | this->saved_linear_layers_[i].reset(new Keccak1600LinearLayer); 44 | this->saved_linear_layers_[i]->SetMasks(this->saved_state_masks_[2*i].get(), this->saved_state_masks_[2*i + 1].get()); 45 | this->saved_sbox_layers_[i].reset(new Keccak1600SboxLayer); 46 | this->saved_sbox_layers_[i]->SetMasks(this->saved_state_masks_[2*i + 1].get(), this->saved_state_masks_[2*i + 2].get()); 47 | } 48 | } 49 | 50 | 51 | void Keccak1600Permutation::set(Permutation* perm) { 52 | for (unsigned int i = 0; i < 2 * rounds_ + 1; ++i) { 53 | this->state_masks_[i].reset(perm->state_masks_[i]->clone()); 54 | } 55 | 56 | for (unsigned int i = 0; i < rounds_; ++i) { 57 | this->sbox_layers_[i].reset(perm->sbox_layers_[i]->clone()); 58 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2 * i +1].get(), 59 | this->state_masks_[2 * i + 2].get()); 60 | this->linear_layers_[i].reset(perm->linear_layers_[i]->clone()); 61 | this->linear_layers_[i]->SetMasks(this->state_masks_[2 * i + 0].get(), 62 | this->state_masks_[2 * i + 1].get()); 63 | } 64 | this->toupdate_linear = perm->toupdate_linear; 65 | this->toupdate_nonlinear = perm->toupdate_nonlinear; 66 | } 67 | 68 | 69 | Keccak1600Permutation& Keccak1600Permutation::operator=(const Keccak1600Permutation& rhs){ 70 | for(unsigned int i = 0; i< 2*rounds_ +1; ++i){ 71 | this->state_masks_[i].reset(rhs.state_masks_[i]->clone()); 72 | } 73 | this->toupdate_linear = rhs.toupdate_linear; 74 | this->toupdate_nonlinear = rhs.toupdate_nonlinear; 75 | for (unsigned int i = 0; i < rounds_; ++i) { 76 | this->linear_layers_[i].reset(new Keccak1600LinearLayer); 77 | this->linear_layers_[i]->SetMasks(this->state_masks_[2*i].get(), this->state_masks_[2*i + 1].get()); 78 | this->sbox_layers_[i].reset(new Keccak1600SboxLayer); 79 | this->sbox_layers_[i]->SetMasks(this->state_masks_[2*i + 1].get(), this->state_masks_[2*i + 2].get()); 80 | } 81 | return *this; 82 | } 83 | 84 | 85 | bool Keccak1600Permutation::update() { 86 | std::unique_ptr tempin, tempout; 87 | bool update_before, update_after; 88 | while (this->toupdate_linear == true || this->toupdate_nonlinear == true) { 89 | if (this->toupdate_nonlinear == true) { 90 | this->toupdate_nonlinear = false; 91 | for (unsigned int layer = 0; layer < rounds_; ++layer) { 92 | tempin.reset(this->sbox_layers_[layer]->in->clone()); 93 | tempout.reset(this->sbox_layers_[layer]->out->clone()); 94 | if (this->sbox_layers_[layer]->Update() == false) 95 | return false; 96 | update_before = this->sbox_layers_[layer]->in->diffLinear(*(tempin)); 97 | update_after = this->sbox_layers_[layer]->out->diffLinear(*(tempout)); 98 | // update_before = this->sbox_layers_[layer]->in->changesforLinear(); 99 | // update_after = this->sbox_layers_[layer]->out->changesforLinear(); 100 | if(((update_after == true) && (layer != rounds_ - 1)) || update_before) 101 | this->toupdate_linear = true; 102 | } 103 | } 104 | if (this->toupdate_linear == true) { 105 | this->toupdate_linear = false; 106 | for (unsigned int layer = 0; layer < rounds_; ++layer) { 107 | tempin.reset(this->linear_layers_[layer]->in->clone()); 108 | tempout.reset(this->linear_layers_[layer]->out->clone()); 109 | if (this->linear_layers_[layer]->Update() == false) 110 | return false; 111 | update_before = this->linear_layers_[layer]->in->diffSbox(*(tempin)); 112 | update_after = this->linear_layers_[layer]->out->diffSbox(*(tempout)); 113 | // update_before = this->sbox_layers_[layer]->in->changesforSbox(); 114 | // update_after = this->sbox_layers_[layer]->out->changesforSbox(); 115 | if(((update_before == true) && (layer != 0)) || update_after) 116 | this->toupdate_nonlinear = true; 117 | } 118 | } 119 | } 120 | return true; 121 | } 122 | 123 | 124 | Permutation::PermPtr Keccak1600Permutation::clone() const { 125 | return PermPtr(new Keccak1600Permutation(*this)); 126 | } 127 | 128 | 129 | void Keccak1600Permutation::PrintWithProbability(std::ostream& stream, 130 | unsigned int offset) { 131 | Permutation::PrintWithProbability(stream, 1); 132 | } 133 | 134 | 135 | void Keccak1600Permutation::touchall() { 136 | Permutation::touchall(); 137 | } 138 | 139 | -------------------------------------------------------------------------------- /tool/mask.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #ifndef MASK_H_ 28 | #define MASK_H_ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #define BM_DUNNO 3 37 | #define BM_0 2 38 | #define BM_1 1 39 | #define BM_CONTRA 0 40 | 41 | typedef char BitMask; // mask for 1 bit (10=0, 01=1, 11=?) 42 | typedef std::vector WordMask; 43 | typedef uint64_t BitVector; // n-bit vector 44 | 45 | 46 | 47 | 48 | template 49 | struct WordMaskPair { 50 | 51 | WordMaskPair(WordMask in, WordMask out) : in(in), out(out) { } 52 | bool operator==(const WordMaskPair &other) const { 53 | bool ret_val = true; 54 | for(int i = 0; iin[i] & 3) == (other.in[i] & 3)); 56 | ret_val &= ((this->out[i] & 3) ==(other.out[i]& 3)); 57 | } 58 | return ret_val; 59 | } 60 | 61 | WordMask in; 62 | WordMask out; 63 | }; 64 | 65 | namespace std { 66 | template 67 | struct hash> { 68 | std::size_t operator()(const WordMaskPair& k) const { 69 | uint64_t v0, v1, v2, v3; 70 | uint64_t message; 71 | v0 = v1 = v2 = v3 = 0; 72 | 73 | for (int i = 0; i < bitsize; i += 16) { 74 | message = 0; 75 | for (int j = i; j < i + 16; ++j) { 76 | message <<= 2; 77 | //TODO: Maybe get rid of the & 3 78 | message |= (k.in[j] & 3); 79 | message <<= 2; 80 | message |= (k.out[j] & 3); 81 | } 82 | v0 ^= message; 83 | for (int j = 0; j < 2; j++) { 84 | v0 += v1; 85 | v2 += v3; 86 | v1 = (v1 << 13) | (v1 >> (64 - 13)); 87 | v3 = (v3 << 16) | (v3 >> (64 - 16)); 88 | v1 ^= v0; 89 | v3 ^= v2; 90 | v0 = (v0 << 32) | (v0 >> 32); 91 | v2 += v1; 92 | v0 += v3; 93 | v1 = (v1 << 17) | (v1 >> (64 - 17)); 94 | v3 = (v3 << 21) | (v3 >> (64 - 21)); 95 | v1 ^= v2; 96 | v3 ^= v0; 97 | v2 = (v2 << 32) | (v2 >> 32); 98 | } 99 | v3 ^= message; 100 | } 101 | 102 | return v0 ^ v1 ^ v2 ^ v3; 103 | } 104 | }; 105 | } 106 | 107 | template 108 | struct WordMaskArray { 109 | 110 | WordMaskArray(std::array in, std::array out) : in(in), out(out) { } 111 | bool operator==(const WordMaskArray &other) const { 112 | bool ret_val = true; 113 | for(int w = 0; w < words; ++w) 114 | for(int i = 0; iin[w][i] & 3) == (other.in[w][i] & 3)); 116 | ret_val &= ((this->out[w][i] & 3) ==(other.out[w][i]& 3)); 117 | } 118 | return ret_val; 119 | } 120 | 121 | std::array in; 122 | std::array out; 123 | }; 124 | 125 | namespace std { 126 | template 127 | struct hash> { 128 | std::size_t operator()(const WordMaskArray& k) const { 129 | uint64_t v0, v1, v2, v3; 130 | uint64_t message; 131 | v0 = v1 = v2 = v3 = 0; 132 | 133 | for (int w = 0; w < words; ++w) { 134 | for (int i = 0; i < bitsize; i += 16) { 135 | message = 0; 136 | for (int j = i; j < i + 16; ++j) { 137 | message <<= 2; 138 | //TODO: Maybe get rid of the & 3 139 | message |= (k.in[w][j] & 3); 140 | message <<= 2; 141 | message |= (k.out[w][j] & 3); 142 | } 143 | v0 ^= message; 144 | for (int j = 0; j < 2; j++) { 145 | v0 += v1; 146 | v2 += v3; 147 | v1 = (v1 << 13) | (v1 >> (64 - 13)); 148 | v3 = (v3 << 16) | (v3 >> (64 - 16)); 149 | v1 ^= v0; 150 | v3 ^= v2; 151 | v0 = (v0 << 32) | (v0 >> 32); 152 | v2 += v1; 153 | v0 += v3; 154 | v1 = (v1 << 17) | (v1 >> (64 - 17)); 155 | v3 = (v3 << 21) | (v3 >> (64 - 21)); 156 | v1 ^= v2; 157 | v3 ^= v0; 158 | v2 = (v2 << 32) | (v2 >> 32); 159 | } 160 | v3 ^= message; 161 | } 162 | } 163 | 164 | return v0 ^ v1 ^ v2 ^ v3; 165 | } 166 | }; 167 | } 168 | 169 | struct WordMaskCare { 170 | WordMaskCare& operator=(const WordMaskCare& rhs); 171 | WordMaskCare(unsigned bitsize); 172 | WordMaskCare(const WordMaskCare& other); 173 | WordMaskCare(BitVector canbe1, BitVector care); 174 | void Reset(); 175 | 176 | BitVector canbe1; // 1=canbe1, 0=mustbe1 // LSB = WordMask[0]!!! 177 | BitVector care; // 1=0/1, 0=?) 178 | }; 179 | 180 | 181 | struct Mask { 182 | Mask& operator=(const Mask& rhs); 183 | Mask(); 184 | Mask(unsigned bitsize); 185 | Mask(const Mask& other); 186 | Mask(std::initializer_list other); 187 | Mask(WordMask& other); 188 | // Mask(WordMaskCare& other); 189 | void init_caremask(); 190 | void reinit_caremask(); 191 | void init_bitmasks(); 192 | void reinit_bitmasks(); 193 | void set_bit(BitMask bit, const int index); 194 | void reset(int bitsize); 195 | 196 | friend std::ostream& operator<<(std::ostream& stream, const Mask& mask); 197 | 198 | WordMask bitmasks; // maybe don't store this & use just for initialization 199 | WordMaskCare caremask; 200 | unsigned char bitsize_; 201 | BitVector changes_; 202 | }; 203 | 204 | 205 | #endif // MASK_H_ 206 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | lineartrails 2 | ============ 3 | 4 | Tool to automatically search for linear characteristics. There exists a research 5 | paper about this tool called "Heuristic Tool for Linear Cryptanalysis with 6 | Applications to CAESAR Candidates", which is presented at AsiaCrypt 2015, an 7 | online version is available [here](https://eprint.iacr.org/2015/1200). If you 8 | use this tool in your work, it would be nice to cite the research paper. 9 | 10 | Authors 11 | ------- 12 | - Christoph Dobraunig () 13 | - Maria Eichlseder () 14 | - Florian Mendel () 15 | 16 | Build 17 | ----- 18 | 19 | `lineartools` requires `tiny2xml` as submodule, so do after `git clone`: 20 | 21 | ``` 22 | git submodule init && git submodule update 23 | ``` 24 | 25 | To build: 26 | 27 | ``` 28 | make 29 | ``` 30 | 31 | 32 | Usage 33 | ----- 34 | 35 | The folder ./examples contains example search configuration for Ascon, ICEPOLE, 36 | Keyak, Minalpher and Proest. To start a search simply call for instance: 37 | 38 | ``` 39 | ./lin -I 10 -S 2 -i examples/ascon_3_rounds_typeI.xml 40 | ``` 41 | 42 | * `-I` determines how often status information of the search is displayed. 43 | `-I -1` deactivates it. 44 | * `-S` determines how often the current and probably partial determined linear 45 | characteristic is put out. `-S -1` deactivates it. 46 | * `-i` specifies the used xml based search file. 47 | 48 | The output of the search are linear characteristics, where Round 0 tags the 49 | linear mask of the input of the first round, Round 1 the output of the first 50 | round, which is also the input for the second round and so on. Half Rounds, e.g. 51 | 1.5 represent intermediate result within one round. For instance if one round 52 | consists of a substitution layer followed by a permutation layer, a half round 53 | marks the output of the substitution layer and the input of the permutation 54 | layer. 55 | 56 | A search file looks like follows: 57 | 58 | ``` 59 | 60 | 61 | 62 | 63 | 64 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | ``` 123 | 124 | In this file, the field `char value` contains the starting point of the search, 125 | where all intermediate masks are considered. Incomplete starting points are 126 | padded with '?'. 127 | 128 | The field `credits` determines, how often a contradiction during the search is 129 | backtracked until the current search is re-started. To provide a clear view, the 130 | search only prints better characteristics than already found. With 131 | `print_active` it is determined whether this "best" metric targets active 132 | S-boxes or the bias. 133 | 134 | Settings define which S-boxes are guessed and are treated subsequently. So if 135 | there is no guessable S-box in a current setting, the next one is taken. 136 | `push_stack` defines the probability that the current characteristic is pushed 137 | to the stack for a possible later backtracking. `alternative_sbox_guesses` 138 | defines how many other contradicting assignments of linear masks than the best 139 | one defined according to `sbox_weight_probability` and `sbox_weight_hamming` 140 | have to be taken into account until the characteristic is treaded as impossible. 141 | `sbox_weight_probability` and `sbox_weight_hamming` are used to rate masks for 142 | S-boxes. A high value for `sbox_weight_probability` prefers masks that have a 143 | high bias, whereas a high value `sbox_weight_hamming` prefers masks that have a 144 | low hamming weight. 145 | 146 | `active_weight` determines the probability that an active S-box will be guessed 147 | (higher values mean higher chance). `inactive_weight` does the same for inactive 148 | S-boxes. 149 | 150 | The code snippets describing the behavior of the linear and S-box layer of the 151 | implemented ciphers are taken from their reference implementations, which are 152 | available at . 153 | 154 | The tool is tested under 155 | - Xubuntu 14.04 (64 bit) using gcc version 4.8.2 156 | - Xubuntu 14.10 (64 bit) using gcc version 4.9.1 157 | - Xubuntu 14.10 (64 bit) using clang (3.8 trunk, Revision 254516) 158 | - Ubuntu 15.04 (64 bit) using gcc version 4.9.2 159 | - OSX Yosemite using Apple LLVM version 6.0 160 | 161 | -------------------------------------------------------------------------------- /target/prost256.h: -------------------------------------------------------------------------------- 1 | #ifndef PROST256_H_ 2 | #define PROST256_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "layer.h" 11 | #include "mask.h" 12 | #include "statemask.h" 13 | #include "step_linear.h" 14 | #include "step_nonlinear.h" 15 | #include "lrucache.h" 16 | 17 | 18 | struct Prost256State : public StateMask<16,32> { 19 | Prost256State(); 20 | friend std::ostream& operator<<(std::ostream& stream, const Prost256State& statemask); 21 | void print(std::ostream& stream); 22 | virtual Prost256State* clone(); 23 | }; 24 | 25 | 26 | #define ROTR32(x,n) ((((x)>>(n))|((x)<<(32-(n))))&(~0ULL >> (32))) 27 | 28 | 29 | struct Prost256SboxLayer : public SboxLayer<4, 128> { 30 | Prost256SboxLayer& operator=(const Prost256SboxLayer& rhs); 31 | Prost256SboxLayer(); 32 | Prost256SboxLayer(StateMaskBase *in, StateMaskBase *out); 33 | virtual Prost256SboxLayer* clone(); 34 | virtual bool updateStep(unsigned int step_pos); 35 | Mask GetVerticalMask(unsigned int b, const StateMaskBase& s) const; 36 | void SetVerticalMask(unsigned int b, StateMaskBase& s, const Mask& mask); 37 | 38 | static const unsigned int cache_size_ = { 0x1000 }; 39 | static std::unique_ptr> cache_; 40 | static std::shared_ptr> ldt_; 41 | }; 42 | 43 | template 44 | struct Prost256LinearLayer : public LinearLayer { 45 | Prost256LinearLayer& operator=(const Prost256LinearLayer& rhs); 46 | Prost256LinearLayer(); 47 | virtual Prost256LinearLayer* clone(); 48 | void Init(); 49 | Prost256LinearLayer(StateMaskBase *in, StateMaskBase *out); 50 | virtual bool updateStep(unsigned int step_pos); 51 | unsigned int GetNumSteps(); 52 | virtual void copyValues(LinearLayer* other); 53 | 54 | static const unsigned int word_size_ = { 32 }; 55 | static const unsigned int words_per_step_ = { 16 }; 56 | static const unsigned int linear_steps_ = {1 }; 57 | std::array, linear_steps_> prost256_linear_; 58 | }; 59 | 60 | //----------------------------------------------------------------------------- 61 | template 62 | std::array Prost256Linear(std::array in) { 63 | std::array tmp; 64 | //the code used in this function is taken and modified from the reference version of Proest available at 65 | //http://bench.cr.yp.to/ebash.html 66 | 67 | /* Multiply by MDS Matrix */ 68 | /*1000100100101011*/ 69 | tmp[ 0] = in[ 0] ^ in[ 4] ^ in[ 7] ^ in[10] ^ in[12] ^ in[14] ^ in[15]; 70 | /*0100100000011001*/ 71 | tmp[ 1] = in[ 1] ^ in[ 4] ^ in[11] ^ in[12] ^ in[15]; 72 | /*0010010011001000*/ 73 | tmp[ 2] = in[ 2] ^ in[ 5] ^ in[ 8] ^ in[ 9] ^ in[12]; 74 | /*0001001001100100*/ 75 | tmp[ 3] = in[ 3] ^ in[ 6] ^ in[ 9] ^ in[10] ^ in[13]; 76 | /*1001100010110010*/ 77 | tmp[ 4] = in[ 0] ^ in[ 3] ^ in[ 4] ^ in[ 8] ^ in[10] ^ in[11] ^ in[14]; 78 | /*1000010010010001*/ 79 | tmp[ 5] = in[ 0] ^ in[ 5] ^ in[ 8] ^ in[11] ^ in[15]; 80 | /*0100001010001100*/ 81 | tmp[ 6] = in[ 1] ^ in[ 6] ^ in[ 8] ^ in[12] ^ in[13]; 82 | /*0010000101000110*/ 83 | tmp[ 7] = in[ 2] ^ in[ 7] ^ in[ 9] ^ in[13] ^ in[14]; 84 | /*0010101110001001*/ 85 | tmp[ 8] = in[ 2] ^ in[ 4] ^ in[ 6] ^ in[ 7] ^ in[ 8] ^ in[12] ^ in[15]; 86 | /*0001100101001000*/ 87 | tmp[ 9] = in[ 3] ^ in[ 4] ^ in[ 7] ^ in[ 9] ^ in[12]; 88 | /*1100100000100100*/ 89 | tmp[10] = in[ 0] ^ in[ 1] ^ in[ 4] ^ in[10] ^ in[13]; 90 | /*0110010000010010*/ 91 | tmp[11] = in[ 1] ^ in[ 2] ^ in[ 5] ^ in[11] ^ in[14]; 92 | /*1011001010011000*/ 93 | tmp[12] = in[ 0] ^ in[ 2] ^ in[ 3] ^ in[ 6] ^ in[ 8] ^ in[11] ^ in[12]; 94 | /*1001000110000100*/ 95 | tmp[13] = in[ 0] ^ in[ 3] ^ in[ 7] ^ in[ 8] ^ in[13]; 96 | /*1000110001000010*/ 97 | tmp[14] = in[ 0] ^ in[ 4] ^ in[ 5] ^ in[ 9] ^ in[14]; 98 | /*0100011000100001*/ 99 | tmp[15] = in[ 1] ^ in[ 5] ^ in[ 6] ^ in[10] ^ in[15]; 100 | 101 | if(!(parity & 1)) // even rounds 102 | { 103 | in[0*4+0] = tmp[0*4+0]; 104 | in[0*4+1] = tmp[0*4+1]; 105 | in[0*4+2] = tmp[0*4+2]; 106 | in[0*4+3] = tmp[0*4+3]; 107 | 108 | in[1*4+0] = ROTR32(tmp[1*4+0],4); 109 | in[1*4+1] = ROTR32(tmp[1*4+1],4); 110 | in[1*4+2] = ROTR32(tmp[1*4+2],4); 111 | in[1*4+3] = ROTR32(tmp[1*4+3],4); 112 | 113 | in[2*4+0] = ROTR32(tmp[2*4+0],12); 114 | in[2*4+1] = ROTR32(tmp[2*4+1],12); 115 | in[2*4+2] = ROTR32(tmp[2*4+2],12); 116 | in[2*4+3] = ROTR32(tmp[2*4+3],12); 117 | 118 | in[3*4+0] = ROTR32(tmp[3*4+0],26); 119 | in[3*4+1] = ROTR32(tmp[3*4+1],26); 120 | in[3*4+2] = ROTR32(tmp[3*4+2],26); 121 | in[3*4+3] = ROTR32(tmp[3*4+3],26); 122 | } 123 | else 124 | { 125 | in[0*4+0] = ROTR32(tmp[0*4+0],1); 126 | in[0*4+1] = ROTR32(tmp[0*4+1],1); 127 | in[0*4+2] = ROTR32(tmp[0*4+2],1); 128 | in[0*4+3] = ROTR32(tmp[0*4+3],1); 129 | 130 | in[1*4+0] = ROTR32(tmp[1*4+0],24); 131 | in[1*4+1] = ROTR32(tmp[1*4+1],24); 132 | in[1*4+2] = ROTR32(tmp[1*4+2],24); 133 | in[1*4+3] = ROTR32(tmp[1*4+3],24); 134 | 135 | in[2*4+0] = ROTR32(tmp[2*4+0],26); 136 | in[2*4+1] = ROTR32(tmp[2*4+1],26); 137 | in[2*4+2] = ROTR32(tmp[2*4+2],26); 138 | in[2*4+3] = ROTR32(tmp[2*4+3],26); 139 | 140 | in[3*4+0] = ROTR32(tmp[3*4+0],31); 141 | in[3*4+1] = ROTR32(tmp[3*4+1],31); 142 | in[3*4+2] = ROTR32(tmp[3*4+2],31); 143 | in[3*4+3] = ROTR32(tmp[3*4+3],31); 144 | } 145 | 146 | return in; 147 | } 148 | 149 | template 150 | Prost256LinearLayer& Prost256LinearLayer::operator=(const Prost256LinearLayer& rhs) { 151 | prost256_linear_ = rhs.prost256_linear_; 152 | return *this; 153 | } 154 | 155 | template 156 | Prost256LinearLayer::Prost256LinearLayer() { 157 | Init(); 158 | } 159 | 160 | template 161 | unsigned int Prost256LinearLayer::GetNumSteps() { 162 | return linear_steps_; 163 | } 164 | 165 | template 166 | Prost256LinearLayer* Prost256LinearLayer::clone() { 167 | //TODO: write copy constructor 168 | Prost256LinearLayer* obj = new Prost256LinearLayer(in, out); 169 | obj->prost256_linear_ = this->prost256_linear_; 170 | return obj; 171 | } 172 | 173 | template 174 | Prost256LinearLayer::Prost256LinearLayer(StateMaskBase *in, StateMaskBase *out) 175 | : LinearLayer(in, out) { 176 | Init(); 177 | } 178 | 179 | template 180 | void Prost256LinearLayer::Init() { 181 | prost256_linear_[0].Initialize(Prost256Linear); 182 | 183 | } 184 | 185 | template 186 | bool Prost256LinearLayer::updateStep(unsigned int step_pos) { 187 | assert(step_pos <= linear_steps_); 188 | bool ret_val; 189 | ret_val = prost256_linear_[step_pos].Update( { 190 | &((*in)[0]), &((*in)[1]), &((*in)[2]), &((*in)[3]), &((*in)[4]), 191 | &((*in)[5]), &((*in)[6]), &((*in)[7]), &((*in)[8]), &((*in)[9]), 192 | &((*in)[10]), &((*in)[11]), &((*in)[12]), &((*in)[13]), &((*in)[14]), &((*in)[15])}, 193 | {&((*out)[0]), &((*out)[1]), &((*out)[2]), &((*out)[3]), &((*out)[4]), 194 | &((*out)[5]), &((*out)[6]), &((*out)[7]), &((*out)[8]), &((*out)[9]), 195 | &((*out)[10]), &((*out)[11]), &((*out)[12]), &((*out)[13]), &((*out)[14]), &((*out)[15])}); 196 | 197 | 198 | // TODO: Test faster update 199 | //for(int i = 0; i < 16; ++i){ 200 | // in->getWordSbox(i) |= (*in)[i].changes_; 201 | // out->getWordSbox(i) |= (*out)[i].changes_; 202 | //} 203 | return ret_val; 204 | } 205 | 206 | template 207 | void Prost256LinearLayer::copyValues(LinearLayer* other){ 208 | Prost256LinearLayer* ptr = dynamic_cast (other); 209 | prost256_linear_ = ptr->prost256_linear_; 210 | } 211 | 212 | 213 | 214 | #endif // PROST256_H_ 215 | -------------------------------------------------------------------------------- /examples/prost256_5_rounds_typeI.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /tool/configparser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | 28 | #include "configparser.h" 29 | 30 | Configparser::Configparser() 31 | : credits_(1000), 32 | print_active_(false) { 33 | settings_.clear(); 34 | } 35 | 36 | bool Configparser::parseFile(std::string filename) { 37 | settings_.clear(); 38 | tinyxml2::XMLDocument doc; 39 | doc.LoadFile(filename.data()); 40 | 41 | if (doc.ErrorID() != 0) { 42 | doc.PrintError(); 43 | return Error( { "Problem with ", filename.data(), ". "}); 44 | } 45 | 46 | doc.Print(); 47 | 48 | tinyxml2::XMLElement* root = 49 | doc.FirstChildElement("config") ? 50 | doc.FirstChildElement("config") : nullptr; 51 | if (root == nullptr) 52 | return Error( { "has to start with " }); 53 | 54 | int rounds = 3; 55 | 56 | 57 | 58 | if (root->FirstChildElement("parameters") != nullptr) { 59 | tinyxml2::XMLElement* parameters = root->FirstChildElement("parameters"); 60 | if (parameters->FirstChildElement("rounds") != nullptr) 61 | rounds = parameters->FirstChildElement("rounds")->IntAttribute("value"); 62 | else 63 | rounds = 1; 64 | 65 | std::string instance { parameters->FirstChildElement("permutation") 66 | ->Attribute("value") }; 67 | 68 | perm_.reset(permutation_list(instance, rounds)); 69 | } 70 | 71 | if (root->FirstChildElement("char") != nullptr) { 72 | std::string characteristic { root->FirstChildElement("char")->Attribute( 73 | "value") }; 74 | BitMask bm; 75 | unsigned int bit_pos = 0; 76 | for (auto& val : characteristic) { 77 | switch (val) { 78 | case '?': 79 | bm = BM_DUNNO; 80 | break; 81 | case '0': 82 | bm = BM_0; 83 | break; 84 | case '1': 85 | bm = BM_1; 86 | break; 87 | default: 88 | bm = BM_CONTRA; 89 | break; 90 | } 91 | if (bm != BM_CONTRA) { 92 | if (perm_->setBit(bm, bit_pos) == false) 93 | break; 94 | ++bit_pos; 95 | } 96 | } 97 | } 98 | if (root->FirstChildElement("active") != nullptr) { 99 | std::string characteristic { root->FirstChildElement("active")->Attribute( 100 | "value") }; 101 | bool active; 102 | int bit_pos = -1; 103 | for (auto& val : characteristic) { 104 | switch (val) { 105 | case '0': 106 | active = false; 107 | ++bit_pos; 108 | break; 109 | case '1': 110 | active = true; 111 | ++bit_pos; 112 | break; 113 | default: 114 | active = false; 115 | break; 116 | } 117 | if (active == true) { 118 | if (perm_->setBox(active, bit_pos) == false) 119 | break; 120 | } 121 | } 122 | // perm_->print(std::cout); 123 | // std::cout << characteristic << std::endl; 124 | } 125 | std::vector active, inactive; 126 | perm_->SboxStatus(active, inactive); 127 | // for (auto& box : active) { 128 | // std::cout << "(" << (int) box.layer_ << ", " << (int) box.pos_ << ") "; 129 | // } 130 | // std::cout << std::endl; 131 | 132 | if (root->FirstChildElement("search")->FirstChildElement("phase") 133 | != nullptr) { 134 | 135 | credits_ = 136 | root->FirstChildElement("search")->UnsignedAttribute("credits") ? 137 | root->FirstChildElement("search")->UnsignedAttribute("credits") : 138 | 1000; 139 | 140 | // std::cout << "Credits:" << credits_ << std::endl; 141 | 142 | print_active_ = 143 | root->FirstChildElement("search")->BoolAttribute("print_active") ? 144 | root->FirstChildElement("search")->BoolAttribute("print_active") : 145 | false; 146 | // std::cout << "print_active:" << print_active_ << std::endl; 147 | 148 | tinyxml2::XMLElement* phase = root->FirstChildElement("search") 149 | ->FirstChildElement("phase"); 150 | tinyxml2::XMLElement* setting = phase->FirstChildElement("setting"); 151 | while (setting != nullptr) { 152 | Setting set; 153 | set.guess_weights_.resize(rounds); 154 | for (auto& entry : set.guess_weights_) 155 | entry[0] = entry[1] = 0; 156 | 157 | set.push_stack_probability_ = 158 | setting->FloatAttribute("push_stack") ? 159 | setting->FloatAttribute("push_stack") : 0.05; 160 | // std::cout << "Setting pushstack prob: " << set.push_stack_probability_ 161 | // << std::endl; 162 | 163 | set.alternative_sbox_guesses_ = 164 | setting->UnsignedAttribute("alternative_sbox_guesses") ? 165 | setting->UnsignedAttribute("alternative_sbox_guesses") : 3; 166 | // std::cout << "Setting alternative sboxguesses: " 167 | // << set.alternative_sbox_guesses_ << std::endl; 168 | 169 | set.sbox_weight_hamming_ = 170 | setting->UnsignedAttribute("sbox_weight_hamming") ? 171 | setting->UnsignedAttribute("sbox_weight_hamming") : 1; 172 | // std::cout 173 | // << "Setting weight for sbox selection considering hammingweight: " 174 | // << set.sbox_weight_hamming_ << std::endl; 175 | 176 | set.sbox_weight_probability_ = 177 | setting->UnsignedAttribute("sbox_weight_probability") ? 178 | setting->UnsignedAttribute("sbox_weight_probability") : 2; 179 | // std::cout << "Setting weight for sbox selection considering ldt entries: " 180 | // << set.sbox_weight_probability_ << std::endl; 181 | 182 | tinyxml2::XMLElement* guess = setting->FirstChildElement("guess"); 183 | 184 | while (guess != nullptr) { 185 | assert(guess->IntAttribute("sbox_layer") < rounds); 186 | set.guess_weights_[guess->IntAttribute("sbox_layer")][0] = guess 187 | ->FloatAttribute("inactive_weight"); 188 | set.guess_weights_[guess->IntAttribute("sbox_layer")][1] = guess 189 | ->FloatAttribute("active_weight"); 190 | guess = guess->NextSiblingElement("guess"); 191 | } 192 | settings_.push_back(set); 193 | setting = setting->NextSiblingElement("setting"); 194 | } 195 | } 196 | 197 | // for (auto& set : settings_) { 198 | // for (auto& entry : set.guess_weights_) { 199 | // std::cout << "(" << entry[0] << ", " << entry[1] << "), "; 200 | // } 201 | // std::cout << std::endl; 202 | // } 203 | 204 | return true; 205 | } 206 | std::unique_ptr Configparser::getPermutation() { 207 | assert(perm_.get() != nullptr); 208 | return perm_->clone(); 209 | } 210 | Settings Configparser::getSettings() { 211 | return settings_; 212 | } 213 | 214 | unsigned int Configparser::getCredits() { 215 | return credits_; 216 | } 217 | 218 | bool Configparser::Error(std::initializer_list msg) { 219 | std::cerr << "Config Error: "; 220 | for (const auto& m : msg) 221 | std::cerr << m; 222 | std::cerr << std::endl; 223 | return false; 224 | } 225 | 226 | bool Configparser::Warning(std::initializer_list msg) { 227 | std::cerr << "Config Warning: "; 228 | for (const auto& m : msg) 229 | std::cerr << m; 230 | std::cerr << std::endl; 231 | return false; 232 | } 233 | 234 | bool Configparser::printActive() { 235 | return print_active_; 236 | } 237 | -------------------------------------------------------------------------------- /examples/keccak_2_rounds_typeI.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 138 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /tool/layer.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | 28 | #ifndef LAYER_H_ 29 | #define LAYER_H_ 30 | 31 | #include "mask.h" 32 | #include "statemask.h" 33 | #include "step_nonlinear.h" 34 | 35 | struct SboxPos { 36 | SboxPos(uint16_t layer, uint16_t pos); 37 | 38 | uint16_t layer_; uint16_t pos_; 39 | }; 40 | 41 | struct Layer { 42 | Layer() = default; 43 | virtual ~Layer(){}; 44 | Layer(StateMaskBase *in, StateMaskBase *out); 45 | void SetMasks(StateMaskBase *inmask, StateMaskBase *outmask); 46 | virtual bool Update() = 0; 47 | virtual bool updateStep(unsigned int step_pos) = 0; 48 | virtual Layer* clone() = 0; 49 | virtual unsigned int GetNumSteps() = 0; 50 | StateMaskBase *in; 51 | StateMaskBase *out; 52 | }; 53 | 54 | struct LinearLayer: public Layer { 55 | LinearLayer() = default; 56 | LinearLayer(StateMaskBase *in, StateMaskBase *out); 57 | virtual bool Update(); 58 | virtual LinearLayer* clone() = 0; 59 | virtual bool updateStep(unsigned int step_pos) = 0; 60 | virtual unsigned int GetNumSteps() = 0; 61 | virtual void copyValues(LinearLayer* other) = 0; 62 | }; 63 | 64 | struct SboxLayerBase: public Layer { 65 | SboxLayerBase() = default; 66 | SboxLayerBase(StateMaskBase *in, StateMaskBase *out); 67 | virtual bool Update() = 0; 68 | virtual bool updateStep(unsigned int step_pos) = 0; 69 | virtual void InitSboxes(std::function fun) = 0; 70 | virtual void GuessBox(unsigned int step_pos, std::function rating)= 0; 71 | virtual void GuessBoxRandom(unsigned int step_pos, std::function rating) = 0; 72 | virtual int GuessBox(unsigned int step_pos, std::function rating, int mask_pos)= 0; 73 | virtual bool SboxActive(unsigned int step_pos)= 0; 74 | virtual bool SboxGuessable(unsigned int step_pos)= 0; 75 | virtual SboxLayerBase* clone() = 0; 76 | virtual double GetProbability()= 0; 77 | virtual unsigned int GetNumSteps() = 0; 78 | virtual void SetSboxActive(unsigned int step_pos, bool active) = 0; 79 | virtual Mask GetVerticalMask(unsigned int b, const StateMaskBase& s) const = 0; 80 | virtual void SetVerticalMask(unsigned int b, StateMaskBase& s, const Mask& mask) = 0; 81 | virtual void copyValues(SboxLayerBase* other) = 0; 82 | }; 83 | 84 | template 85 | struct SboxLayer: public SboxLayerBase { 86 | SboxLayer() = default; 87 | SboxLayer(StateMaskBase *in, StateMaskBase *out); 88 | virtual bool Update(); 89 | virtual bool updateStep(unsigned int step_pos); 90 | virtual void InitSboxes(std::function fun); 91 | virtual void InitSboxes(std::shared_ptr> ldt); 92 | virtual void GuessBox(unsigned int step_pos, std::function rating); 93 | virtual void GuessBoxRandom(unsigned int step_pos, std::function rating); 94 | virtual int GuessBox(unsigned int step_pos, std::function rating, int mask_pos); 95 | virtual bool SboxActive(unsigned int step_pos); 96 | virtual bool SboxGuessable(unsigned int step_pos); 97 | virtual SboxLayer* clone() = 0; 98 | virtual double GetProbability(); 99 | virtual unsigned int GetNumSteps(); 100 | virtual void SetSboxActive(unsigned int step_pos, bool active); 101 | virtual Mask GetVerticalMask(unsigned int b, const StateMaskBase& s) const = 0; 102 | virtual void SetVerticalMask(unsigned int b, StateMaskBase& s, const Mask& mask) = 0; 103 | virtual void copyValues(SboxLayerBase* other); 104 | std::array, boxes> sboxes; 105 | }; 106 | 107 | //----------------------------------------------------------------------------- 108 | template 109 | SboxLayer::SboxLayer(StateMaskBase *in, StateMaskBase *out) : SboxLayerBase(in, out) { 110 | } 111 | 112 | template 113 | double SboxLayer::GetProbability(){ 114 | double prob = {0.0}; 115 | 116 | for (unsigned int i = 0; i < boxes; ++i){ 117 | Mask copyin(GetVerticalMask(i, *in)); 118 | Mask copyout(GetVerticalMask(i, *out)); 119 | double temp_prob = sboxes[i].GetProbability(copyin, copyout); 120 | prob += temp_prob; 121 | } 122 | 123 | prob += boxes-1; 124 | 125 | return prob; 126 | } 127 | 128 | template 129 | unsigned int SboxLayer::GetNumSteps(){ 130 | return boxes; 131 | } 132 | 133 | template 134 | bool SboxLayer::updateStep(unsigned int step_pos) { 135 | assert(step_pos < boxes); 136 | Mask copyin(GetVerticalMask(step_pos, *in)); 137 | Mask copyout(GetVerticalMask(step_pos, *out)); 138 | if (!sboxes[step_pos].Update(copyin, copyout)) 139 | return false; 140 | SetVerticalMask(step_pos, *in, copyin); 141 | SetVerticalMask(step_pos, *out, copyout); 142 | return true; 143 | } 144 | 145 | template 146 | bool SboxLayer::Update(){ 147 | bool ret_val = true; 148 | 149 | for(unsigned int i = 0; i < boxes; ++i) 150 | ret_val &= updateStep(i); 151 | 152 | in->resetChangesSbox(); 153 | out->resetChangesSbox(); 154 | return ret_val; 155 | } 156 | 157 | template 158 | bool SboxLayer::SboxActive(unsigned int step_pos){ 159 | assert(step_pos < boxes); 160 | return sboxes[step_pos].is_active_ | sboxes[step_pos].has_to_be_active_; 161 | } 162 | 163 | template 164 | void SboxLayer::SetSboxActive(unsigned int step_pos, bool active){ 165 | assert(step_pos < boxes); 166 | sboxes[step_pos].has_to_be_active_ = active; 167 | } 168 | 169 | template 170 | bool SboxLayer::SboxGuessable(unsigned int step_pos){ 171 | assert(step_pos < boxes); 172 | return sboxes[step_pos].is_guessable_; 173 | } 174 | 175 | template 176 | void SboxLayer::GuessBox(unsigned int step_pos, std::function rating) { 177 | assert(step_pos < boxes); 178 | Mask copyin(GetVerticalMask(step_pos, *in)); 179 | Mask copyout(GetVerticalMask(step_pos, *out)); 180 | 181 | sboxes[step_pos].TakeBestBox(copyin, copyout, rating); 182 | 183 | SetVerticalMask(step_pos, *in, copyin); 184 | SetVerticalMask(step_pos, *out, copyout); 185 | 186 | } 187 | 188 | template 189 | void SboxLayer::GuessBoxRandom(unsigned int step_pos, std::function rating) { 190 | assert(step_pos < boxes); 191 | Mask copyin(GetVerticalMask(step_pos, *in)); 192 | Mask copyout(GetVerticalMask(step_pos, *out)); 193 | 194 | sboxes[step_pos].TakeBestBoxRandom(copyin, copyout, rating); 195 | 196 | SetVerticalMask(step_pos, *in, copyin); 197 | SetVerticalMask(step_pos, *out, copyout); 198 | 199 | } 200 | 201 | template 202 | int SboxLayer::GuessBox(unsigned int step_pos, std::function rating, int mask_pos) { 203 | int choises; 204 | assert(step_pos < boxes); 205 | Mask copyin(GetVerticalMask(step_pos, *in)); 206 | Mask copyout(GetVerticalMask(step_pos, *out)); 207 | 208 | choises = sboxes[step_pos].TakeBestBox(copyin, copyout, rating, mask_pos); 209 | 210 | SetVerticalMask(step_pos, *in, copyin); 211 | SetVerticalMask(step_pos, *out, copyout); 212 | return choises; 213 | } 214 | 215 | template 216 | void SboxLayer::InitSboxes(std::function fun){ 217 | std::shared_ptr> ldt(new LinearDistributionTable(fun)); 218 | for (size_t i = 0; i < boxes; i++) 219 | sboxes[i].Initialize(ldt); 220 | } 221 | 222 | template 223 | void SboxLayer::InitSboxes(std::shared_ptr> ldt){ 224 | 225 | for (size_t i = 0; i < boxes; i++) 226 | sboxes[i].Initialize(ldt); 227 | } 228 | 229 | template 230 | void SboxLayer::copyValues(SboxLayerBase* other){ 231 | SboxLayer* ptr = dynamic_cast*> (other); 232 | 233 | sboxes = ptr->sboxes; 234 | } 235 | 236 | #endif // LAYER_H_ 237 | -------------------------------------------------------------------------------- /tool/search.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include "search.h" 28 | 29 | 30 | Search::Search(Permutation &perm) 31 | : perm_(&perm) { 32 | 33 | } 34 | 35 | 36 | void Search::StackSearch1(Commandlineparser& cl_param, 37 | Configparser& config_param) { 38 | 39 | std::unique_ptr working_copy; 40 | std::stack> char_stack; 41 | 42 | double best_prob = -DBL_MAX; 43 | GuessMask guesses; 44 | SboxPos guessed_box(0, 0); 45 | SboxPos backtrack_box(0, 0); 46 | bool backtrack; 47 | bool active; 48 | 49 | working_copy = config_param.getPermutation(); 50 | if (working_copy->checkchar() == false) { 51 | std::cout << "Initial checkchar failed" << std::endl; 52 | return; 53 | } 54 | Settings settings = config_param.getSettings(); 55 | 56 | auto start_count = std::chrono::system_clock::now(); 57 | std::mt19937 generator( 58 | std::chrono::high_resolution_clock::now().time_since_epoch().count()); 59 | std::uniform_real_distribution push_stack_rand(0.0, 1.0); 60 | 61 | unsigned int interations = (unsigned int) cl_param.getIntParameter("-iter"); 62 | int total_iterations = 0; 63 | int print_char = cl_param.getIntParameter("-S"); 64 | for (unsigned int i = 0; i < interations; ++i) { 65 | char_stack.emplace(working_copy->clone()); 66 | char_stack.emplace(working_copy->clone()); 67 | backtrack = false; 68 | guesses.createMask(char_stack.top().get(), settings); 69 | unsigned int curr_credit = config_param.getCredits(); 70 | while (guesses.getRandPos(guessed_box, active)) { 71 | total_iterations++; 72 | auto duration = std::chrono::duration_cast( 73 | std::chrono::system_clock::now() - start_count); 74 | if (cl_param.getIntParameter("-I") > 0 75 | && duration.count() > cl_param.getIntParameter("-I")) { 76 | std::cout << "PRINT-INFO: total iterations: " << total_iterations 77 | << ", stack size: " << char_stack.size() << ", credits: " 78 | << curr_credit << ", restarts: " << i << std::endl; 79 | print_char--; 80 | if (print_char == 0) { 81 | char_stack.top()->print(std::cout); 82 | print_char = cl_param.getIntParameter("-S"); 83 | } 84 | start_count = std::chrono::system_clock::now(); 85 | } 86 | 87 | if (curr_credit == 0) 88 | break; 89 | 90 | if (backtrack) 91 | guessed_box = backtrack_box; 92 | 93 | unsigned int wbias = guesses.getSboxWeigthProb(); 94 | unsigned int whamming = guesses.getSboxWeightHamming(); 95 | //FIXME: get rid of the 10 96 | auto rating = [wbias, whamming] (int bias, int hw_in, int hw_out) { 97 | return wbias*std::abs(bias) +whamming*((10-hw_in)+(10-hw_out)); 98 | }; 99 | if (char_stack.top()->guessbestsboxrandom( 100 | guessed_box, rating, guesses.getAlternativeSboxGuesses())) { 101 | // std::cout << "worked " << char_stack.size() << std::endl; 102 | // char_stack.top()->print(std::cout); 103 | backtrack = false; 104 | if (push_stack_rand(generator) <= guesses.getPushStackProb()) 105 | char_stack.emplace(char_stack.top()->clone()); 106 | } else { 107 | // std::cout << "failed" << std::endl; 108 | // char_stack.top()->print(std::cout); 109 | char_stack.pop(); 110 | curr_credit--; 111 | backtrack = true; 112 | backtrack_box = guessed_box; 113 | if (char_stack.size() == 1) 114 | char_stack.emplace(working_copy->clone()); 115 | } 116 | guesses.createMask(char_stack.top().get(), settings); 117 | } 118 | double current_prob; 119 | if (config_param.printActive()) 120 | current_prob = -char_stack.top()->GetActiveSboxes(); 121 | else 122 | current_prob = char_stack.top()->GetProbability(); 123 | if (current_prob > best_prob && curr_credit > 0) { 124 | best_prob = current_prob; 125 | std::cout << "iteration: " << i << std::endl; 126 | char_stack.top()->PrintWithProbability(); 127 | } 128 | while (char_stack.size()) 129 | char_stack.pop(); 130 | } 131 | } 132 | 133 | void Search::StackSearchKeccak(Commandlineparser& cl_param, 134 | Configparser& config_param) { 135 | 136 | std::unique_ptr working_copy; 137 | std::stack> char_stack; 138 | 139 | double best_prob = -DBL_MAX; 140 | GuessMask guesses; 141 | SboxPos guessed_box(0, 0); 142 | SboxPos backtrack_box(0, 0); 143 | bool backtrack; 144 | bool active; 145 | 146 | working_copy = config_param.getPermutation(); 147 | if (working_copy->checkchar() == false) { 148 | std::cout << "Initial checkchar failed" << std::endl; 149 | return; 150 | } 151 | Settings settings = config_param.getSettings(); 152 | 153 | auto start_count = std::chrono::system_clock::now(); 154 | std::mt19937 generator( 155 | std::chrono::high_resolution_clock::now().time_since_epoch().count()); 156 | std::uniform_real_distribution push_stack_rand(0.0, 1.0); 157 | 158 | unsigned int interations = (unsigned int) cl_param.getIntParameter("-iter"); 159 | int total_iterations = 0; 160 | int print_char = cl_param.getIntParameter("-S"); 161 | for (unsigned int i = 0; i < interations; ++i) { 162 | char_stack.emplace(working_copy->clone()); 163 | char_stack.emplace(working_copy->clone()); 164 | backtrack = false; 165 | guesses.createMask(char_stack.top().get(), settings); 166 | unsigned int curr_credit = config_param.getCredits(); 167 | while (guesses.getRandPos(guessed_box, active)) { 168 | total_iterations++; 169 | auto duration = std::chrono::duration_cast( 170 | std::chrono::system_clock::now() - start_count); 171 | if (cl_param.getIntParameter("-I") > 0 172 | && duration.count() > cl_param.getIntParameter("-I")) { 173 | std::cout << "PRINT-INFO: total iterations: " << total_iterations 174 | << ", stack size: " << char_stack.size() << ", credits: " 175 | << curr_credit << ", restarts: " << i << std::endl; 176 | print_char--; 177 | if (print_char == 0) { 178 | char_stack.top()->print(std::cout); 179 | print_char = cl_param.getIntParameter("-S"); 180 | } 181 | start_count = std::chrono::system_clock::now(); 182 | } 183 | 184 | if (curr_credit == 0) 185 | break; 186 | 187 | if (backtrack) 188 | guessed_box = backtrack_box; 189 | 190 | unsigned int wbias = guesses.getSboxWeigthProb(); 191 | unsigned int whamming = guesses.getSboxWeightHamming(); 192 | //FIXME: get rid of the 10 193 | auto rating = [wbias, whamming] (int bias, int hw_in, int hw_out) { 194 | return wbias * std::abs(bias) + whamming * ((10 - hw_in) + (10 - hw_out)); 195 | }; 196 | if (char_stack.top()->guessbestsboxrandom(guessed_box, rating, guesses.getAlternativeSboxGuesses())) { 197 | // std::cout << "worked " << char_stack.size() << std::endl; 198 | // char_stack.top()->print(std::cout); 199 | backtrack = false; 200 | if (push_stack_rand(generator) <= guesses.getPushStackProb()) 201 | char_stack.emplace(char_stack.top()->clone()); 202 | } else { 203 | // std::cout << "failed" << std::endl; 204 | // char_stack.top()->print(std::cout); 205 | char_stack.pop(); 206 | curr_credit--; 207 | backtrack = true; 208 | backtrack_box = guessed_box; 209 | if (char_stack.size() == 1) 210 | char_stack.emplace(working_copy->clone()); 211 | } 212 | guesses.createMask(char_stack.top().get(), settings); 213 | } 214 | double current_prob; 215 | current_prob = KeccakProb(char_stack); 216 | if (current_prob > best_prob && curr_credit > 0) { 217 | best_prob = current_prob; 218 | std::cout << "iteration: " << i << std::endl; 219 | std::cout << "bias without last round: " << best_prob << std::endl; 220 | char_stack.top()->PrintWithProbability(); 221 | } 222 | while (char_stack.size()) 223 | char_stack.pop(); 224 | } 225 | } 226 | 227 | double Search::KeccakProb(std::stack>& char_stack) { 228 | double prob = 0.0; 229 | double temp_prob; 230 | 231 | for (unsigned i = 0; i < char_stack.top()->sbox_layers_.size() - 1; ++i) { 232 | temp_prob = char_stack.top()->sbox_layers_[i]->GetProbability(); 233 | prob += temp_prob; 234 | } 235 | 236 | prob += char_stack.top()->sbox_layers_.size() - 2; 237 | 238 | return prob; 239 | } 240 | 241 | -------------------------------------------------------------------------------- /examples/icepole_3_rounds_typeIII.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /target/ascon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | In jurisdictions that recognize copyright laws, the author or authors 10 | of this software dedicate any and all copyright interest in the 11 | software to the public domain. We make this dedication for the benefit 12 | of the public at large and to the detriment of our heirs and 13 | successors. We intend this dedication to be an overt act of 14 | relinquishment in perpetuity of all present and future rights to this 15 | software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | For more information, please refer to 26 | */ 27 | #include "ascon.h" 28 | 29 | //#define HEXOUTPUT 30 | //#define LATEX 31 | //#define TRUNCATED 32 | 33 | AsconState::AsconState() 34 | : StateMask() { 35 | } 36 | 37 | AsconState* AsconState::clone() { 38 | AsconState* obj = new AsconState(); 39 | for (size_t j = 0; j < words_.size(); ++j) { 40 | obj->words_[j] = words_[j]; 41 | obj->changes_for_linear_layer_[j] = changes_for_linear_layer_[j]; 42 | obj->changes_for_sbox_layer_[j] = changes_for_sbox_layer_[j]; 43 | } 44 | return obj; 45 | } 46 | 47 | void AsconState::print(std::ostream& stream) { 48 | stream << *this; 49 | } 50 | 51 | 52 | #ifdef HEXOUTPUT 53 | #ifdef LATEX 54 | std::ostream& operator<<(std::ostream& stream, const AsconState& statemask) { 55 | 56 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 57 | unsigned long long outword = 0; 58 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 59 | outword <<= 1; 60 | if (*it % 4 == 1) 61 | outword |=1; 62 | } 63 | stream << " & \\texttt{" << std::hex << std::setfill('0') << std::setw(16) << outword << "} " << std::dec; 64 | } 65 | stream << std::endl; 66 | return stream; 67 | } 68 | #else 69 | #ifdef TRUNCATED 70 | std::ostream& operator<<(std::ostream& stream, const AsconState& statemask) { 71 | 72 | unsigned long long resultingword = 0; 73 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 74 | unsigned long long outword = 0; 75 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 76 | outword <<= 1; 77 | if (*it % 4 == 1) 78 | outword |=1; 79 | } 80 | resultingword |= outword; 81 | } 82 | stream << std::hex << std::setfill('0') << std::setw(16) << resultingword << std::dec << std::endl; 83 | return stream; 84 | } 85 | #else 86 | std::ostream& operator<<(std::ostream& stream, const AsconState& statemask) { 87 | 88 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 89 | unsigned long long outword = 0; 90 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 91 | outword <<= 1; 92 | if (*it % 4 == 1) 93 | outword |=1; 94 | } 95 | stream << std::hex << std::setfill('0') << std::setw(16) << outword << std::dec << std::endl; 96 | } 97 | return stream; 98 | } 99 | #endif 100 | #endif 101 | #else 102 | std::ostream& operator<<(std::ostream& stream, const AsconState& statemask) { 103 | #ifndef TERMINALCOLORS 104 | char symbol[4] {'#', '1', '0', '?'}; 105 | #else 106 | std::string symbol[4] { "\033[1;35m#\033[0m", "\033[1;31m1\033[0m", "0", 107 | "\033[1;33m?\033[0m" }; 108 | #endif 109 | for (Mask word : statemask.words_) { 110 | for (auto it = word.bitmasks.rbegin(); it != word.bitmasks.rend(); ++it) { 111 | stream << symbol[*it % 4]; 112 | } 113 | stream << std::endl; 114 | } 115 | return stream; 116 | } 117 | #endif 118 | 119 | //----------------------------------------------------------------------------- 120 | 121 | AsconLinearLayer& AsconLinearLayer::operator=(const AsconLinearLayer& rhs) { 122 | sigmas = rhs.sigmas; 123 | return *this; 124 | } 125 | 126 | AsconLinearLayer::AsconLinearLayer() { 127 | Init(); 128 | } 129 | 130 | unsigned int AsconLinearLayer::GetNumSteps() { 131 | return linear_steps_; 132 | } 133 | 134 | AsconLinearLayer* AsconLinearLayer::clone() { 135 | //TODO: write copy constructor 136 | AsconLinearLayer* obj = new AsconLinearLayer(in, out); 137 | obj->sigmas = this->sigmas; 138 | return obj; 139 | } 140 | 141 | AsconLinearLayer::AsconLinearLayer(StateMaskBase *in, StateMaskBase *out) 142 | : LinearLayer(in, out) { 143 | Init(); 144 | } 145 | 146 | void AsconLinearLayer::Init() { 147 | sigmas[0].Initialize(AsconSigma<0>); 148 | sigmas[1].Initialize(AsconSigma<1>); 149 | sigmas[2].Initialize(AsconSigma<2>); 150 | sigmas[3].Initialize(AsconSigma<3>); 151 | sigmas[4].Initialize(AsconSigma<4>); 152 | } 153 | 154 | //TODO: Test faster update 155 | //bool AsconLinearLayer::Update(){ 156 | // bool ret_val = true; 157 | // 158 | // unsigned long long words_to_update[linear_steps_]; 159 | // 160 | // for (unsigned int i = 0; i < linear_steps_; ++i) 161 | // words_to_update[i] = in->getWordLinear(i) | out->getWordLinear(i); 162 | // 163 | // for (unsigned int i = 0; i < linear_steps_; ++i) 164 | // for (unsigned int j = 0; j < word_size_; ++j) 165 | // words_to_update[i] |= words_to_update[i] >> j; 166 | // 167 | // for (unsigned int i = 0; i < linear_steps_; ++i) 168 | // if(words_to_update[i] & 1) 169 | // ret_val &= updateStep(i); 170 | // 171 | // in->resetChangesLinear(); 172 | // out->resetChangesLinear(); 173 | // return ret_val; 174 | //} 175 | 176 | bool AsconLinearLayer::updateStep(unsigned int step_pos) { 177 | 178 | bool ret_val = sigmas[step_pos].Update( { &((*in)[step_pos]) }, 179 | { &((*out)[step_pos]) }); 180 | 181 | // TODO: Test faster update 182 | // in->getWordSbox(step_pos) |= (*in)[step_pos].changes_; 183 | // out->getWordSbox(step_pos) |= (*out)[step_pos].changes_; 184 | 185 | return ret_val; 186 | } 187 | 188 | void AsconLinearLayer::copyValues(LinearLayer* other){ 189 | AsconLinearLayer* ptr = dynamic_cast (other); 190 | sigmas = ptr->sigmas; 191 | } 192 | 193 | //----------------------------------------------------------------------------- 194 | 195 | BitVector AsconSbox(BitVector in) { 196 | // with x0 as MSB 197 | static const BitVector sbox[32] = { 198 | 4, 11, 31, 20, 26, 21, 9, 2, 27, 5, 8, 18, 29, 3, 6, 28, 199 | 30, 19, 7, 14, 0, 13, 17, 24, 16, 12, 1, 25, 22, 10, 15, 23, 200 | }; 201 | return sbox[in % 32] & 0x1f; 202 | } 203 | 204 | std::unique_ptr> AsconSboxLayer::cache_; 205 | std::shared_ptr> AsconSboxLayer::ldt_; 206 | 207 | AsconSboxLayer& AsconSboxLayer::operator=(const AsconSboxLayer& rhs) { 208 | sboxes = rhs.sboxes; 209 | return *this; 210 | } 211 | 212 | AsconSboxLayer::AsconSboxLayer() { 213 | if(ldt_ == nullptr) 214 | ldt_.reset(new LinearDistributionTable<5>(AsconSbox)); 215 | InitSboxes(ldt_); 216 | if (this->cache_.get() == nullptr) 217 | this->cache_.reset( 218 | new LRU_Cache( 219 | cache_size_)); 220 | } 221 | 222 | AsconSboxLayer::AsconSboxLayer(StateMaskBase *in, StateMaskBase *out) 223 | : SboxLayer(in, out) { 224 | if(ldt_ == nullptr) 225 | ldt_.reset(new LinearDistributionTable<5>(AsconSbox)); 226 | InitSboxes(ldt_); 227 | if (this->cache_.get() == nullptr) 228 | this->cache_.reset( 229 | new LRU_Cache( 230 | cache_size_)); 231 | } 232 | 233 | AsconSboxLayer* AsconSboxLayer::clone() { 234 | //TODO: write copy constructor 235 | AsconSboxLayer* obj = new AsconSboxLayer(in, out); 236 | obj->sboxes = this->sboxes; 237 | return obj; 238 | } 239 | 240 | //TODO: Test faster update 241 | //bool AsconSboxLayer::Update() { 242 | // bool ret_val = true; 243 | // 244 | // unsigned long long boxes_to_update = 0; 245 | // 246 | // for (unsigned int i = 0; i < in->getnumwords(); ++i) 247 | // boxes_to_update |= in->getWordSbox(i) | out->getWordSbox(i); 248 | // 249 | // for (unsigned int i = 0; i < GetNumSteps(); ++i) { 250 | // if (boxes_to_update & 1){ 251 | // ret_val &= updateStep(i); 252 | // } 253 | // boxes_to_update >>= 1; 254 | // } 255 | // 256 | // in->resetChangesSbox(); 257 | // out->resetChangesSbox(); 258 | // return ret_val; 259 | //} 260 | 261 | bool AsconSboxLayer::updateStep(unsigned int step_pos) { 262 | assert(step_pos < sboxes.size()); 263 | bool ret_val; 264 | Mask copyin(GetVerticalMask(step_pos, *in)); 265 | Mask copyout(GetVerticalMask(step_pos, *out)); 266 | ret_val = sboxes[step_pos].Update(copyin, copyout, cache_.get()); 267 | SetVerticalMask(step_pos, *in, copyin); 268 | SetVerticalMask(step_pos, *out, copyout); 269 | return ret_val; 270 | } 271 | 272 | Mask AsconSboxLayer::GetVerticalMask(unsigned int b, 273 | const StateMaskBase& s) const { 274 | return Mask( 275 | { s[4].bitmasks[b], s[3].bitmasks[b], s[2].bitmasks[b], s[1].bitmasks[b], 276 | s[0].bitmasks[b] }); 277 | } 278 | 279 | void AsconSboxLayer::SetVerticalMask(unsigned int b, StateMaskBase& s, 280 | const Mask& mask) { 281 | 282 | //TODO: Test faster update 283 | // for(int i = 0; i < 5; ++i) 284 | // s.getWordLinear(i) |= ((mask.changes_>>(4-i))&1) << b; 285 | 286 | s[0].bitmasks[b] = mask.bitmasks[4]; 287 | s[1].bitmasks[b] = mask.bitmasks[3]; 288 | s[2].bitmasks[b] = mask.bitmasks[2]; 289 | s[3].bitmasks[b] = mask.bitmasks[1]; 290 | s[4].bitmasks[b] = mask.bitmasks[0]; 291 | BitVector m = ~(1ULL << b); 292 | s[0].caremask.canbe1 = (s[0].caremask.canbe1 & m) 293 | | (((mask.caremask.canbe1 >> 4) & 1) << b); 294 | s[1].caremask.canbe1 = (s[1].caremask.canbe1 & m) 295 | | (((mask.caremask.canbe1 >> 3) & 1) << b); 296 | s[2].caremask.canbe1 = (s[2].caremask.canbe1 & m) 297 | | (((mask.caremask.canbe1 >> 2) & 1) << b); 298 | s[3].caremask.canbe1 = (s[3].caremask.canbe1 & m) 299 | | (((mask.caremask.canbe1 >> 1) & 1) << b); 300 | s[4].caremask.canbe1 = (s[4].caremask.canbe1 & m) 301 | | (((mask.caremask.canbe1 >> 0) & 1) << b); 302 | 303 | s[0].caremask.care = (s[0].caremask.care & m) 304 | | (((mask.caremask.care >> 4) & 1) << b); 305 | s[1].caremask.care = (s[1].caremask.care & m) 306 | | (((mask.caremask.care >> 3) & 1) << b); 307 | s[2].caremask.care = (s[2].caremask.care & m) 308 | | (((mask.caremask.care >> 2) & 1) << b); 309 | s[3].caremask.care = (s[3].caremask.care & m) 310 | | (((mask.caremask.care >> 1) & 1) << b); 311 | s[4].caremask.care = (s[4].caremask.care & m) 312 | | (((mask.caremask.care >> 0) & 1) << b); 313 | } 314 | 315 | -------------------------------------------------------------------------------- /target/keccak1600.cpp: -------------------------------------------------------------------------------- 1 | #include "keccak1600.h" 2 | 3 | //#define HEXOUTPUT 4 | //#define LATEX 5 | 6 | Keccak1600State::Keccak1600State() 7 | : StateMask() { 8 | } 9 | 10 | Keccak1600State* Keccak1600State::clone() { 11 | Keccak1600State* obj = new Keccak1600State(); 12 | for (size_t j = 0; j < words_.size(); ++j) { 13 | obj->words_[j] = words_[j]; 14 | obj->changes_for_linear_layer_[j] = changes_for_linear_layer_[j]; 15 | obj->changes_for_sbox_layer_[j] = changes_for_sbox_layer_[j]; 16 | } 17 | return obj; 18 | } 19 | 20 | void Keccak1600State::print(std::ostream& stream) { 21 | stream << *this; 22 | } 23 | 24 | #ifdef HEXOUTPUT 25 | #ifdef LATEX 26 | std::ostream& operator<<(std::ostream& stream, const Keccak1600State& statemask) { 27 | 28 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 29 | unsigned long long outword = 0; 30 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 31 | outword <<= 1; 32 | if (*it % 4 == 1) 33 | outword |=1; 34 | } 35 | stream << " & \\texttt{" << std::hex << std::setfill('0') << std::setw(16) << outword << std::dec << "}"; 36 | if(i%5 == 4) 37 | stream << " \\\\ "<< std::endl; 38 | } 39 | stream << " \\\\ "<< std::endl; 40 | return stream; 41 | } 42 | #else 43 | std::ostream& operator<<(std::ostream& stream, const Keccak1600State& statemask) { 44 | 45 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 46 | unsigned long long outword = 0; 47 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 48 | outword <<= 1; 49 | if (*it % 4 == 1) 50 | outword |=1; 51 | } 52 | stream << std::hex << std::setfill('0') << std::setw(16) << outword << std::dec << "\t"; 53 | if(i%5 == 4) 54 | stream << std::endl; 55 | } 56 | return stream; 57 | } 58 | #endif 59 | #else 60 | std::ostream& operator<<(std::ostream& stream, const Keccak1600State& statemask) { 61 | #ifndef TERMINALCOLORS 62 | char symbol[4] {'#', '1', '0', '?'}; 63 | #else 64 | std::string symbol[4] { "\033[1;35m#\033[0m", "\033[1;31m1\033[0m", "0", 65 | "\033[1;33m?\033[0m" }; 66 | #endif 67 | for (Mask word : statemask.words_) { 68 | for (auto it = word.bitmasks.rbegin(); it != word.bitmasks.rend(); ++it) { 69 | stream << symbol[*it % 4]; 70 | } 71 | stream << std::endl; 72 | } 73 | return stream; 74 | } 75 | #endif 76 | 77 | //----------------------------------------------------------------------------- 78 | 79 | std::array Keccak1600Linear(std::array in) { 80 | BitVector t[25]; 81 | BitVector p[5]; 82 | static constexpr int R[5][5] = { 83 | { 0, 36, 3, 41, 18 }, 84 | { 1, 44, 10, 45, 2 }, 85 | { 62, 6, 43, 15, 61 }, 86 | { 28, 55, 25, 21, 56 }, 87 | { 27, 20, 39, 8, 14 } }; 88 | // parity of each lane 89 | p[0] = in[0] ^ in[5] ^ in[10] ^ in[15] ^ in[20]; 90 | p[1] = in[1] ^ in[6] ^ in[11] ^ in[16] ^ in[21]; 91 | p[2] = in[2] ^ in[7] ^ in[12] ^ in[17] ^ in[22]; 92 | p[3] = in[3] ^ in[8] ^ in[13] ^ in[18] ^ in[23]; 93 | p[4] = in[4] ^ in[9] ^ in[14] ^ in[19] ^ in[24]; 94 | // theta w/o parity 95 | t[0] = in[0] ^ p[4] ^ ROTL(p[1], 1); 96 | t[1] = in[1] ^ p[0] ^ ROTL(p[2], 1); 97 | t[2] = in[2] ^ p[1] ^ ROTL(p[3], 1); 98 | t[3] = in[3] ^ p[2] ^ ROTL(p[4], 1); 99 | t[4] = in[4] ^ p[3] ^ ROTL(p[0], 1); 100 | t[5] = in[5] ^ p[4] ^ ROTL(p[1], 1); 101 | t[6] = in[6] ^ p[0] ^ ROTL(p[2], 1); 102 | t[7] = in[7] ^ p[1] ^ ROTL(p[3], 1); 103 | t[8] = in[8] ^ p[2] ^ ROTL(p[4], 1); 104 | t[9] = in[9] ^ p[3] ^ ROTL(p[0], 1); 105 | t[10] = in[10] ^ p[4] ^ ROTL(p[1], 1); 106 | t[11] = in[11] ^ p[0] ^ ROTL(p[2], 1); 107 | t[12] = in[12] ^ p[1] ^ ROTL(p[3], 1); 108 | t[13] = in[13] ^ p[2] ^ ROTL(p[4], 1); 109 | t[14] = in[14] ^ p[3] ^ ROTL(p[0], 1); 110 | t[15] = in[15] ^ p[4] ^ ROTL(p[1], 1); 111 | t[16] = in[16] ^ p[0] ^ ROTL(p[2], 1); 112 | t[17] = in[17] ^ p[1] ^ ROTL(p[3], 1); 113 | t[18] = in[18] ^ p[2] ^ ROTL(p[4], 1); 114 | t[19] = in[19] ^ p[3] ^ ROTL(p[0], 1); 115 | t[20] = in[20] ^ p[4] ^ ROTL(p[1], 1); 116 | t[21] = in[21] ^ p[0] ^ ROTL(p[2], 1); 117 | t[22] = in[22] ^ p[1] ^ ROTL(p[3], 1); 118 | t[23] = in[23] ^ p[2] ^ ROTL(p[4], 1); 119 | t[24] = in[24] ^ p[3] ^ ROTL(p[0], 1); 120 | // rho, pi 121 | for (int y = 0; y < 5; y++) 122 | for (int x = 0; x < 5; x++) 123 | in[5 * (((2 * x + 3 * y) % 5)) + y] = ROTR(t[x + 5 * y], (64 - R[x][y]) % 64); 124 | 125 | return in; 126 | } 127 | 128 | Keccak1600LinearLayer& Keccak1600LinearLayer::operator=(const Keccak1600LinearLayer& rhs) { 129 | keccak_linear_ = rhs.keccak_linear_; 130 | return *this; 131 | } 132 | 133 | Keccak1600LinearLayer::Keccak1600LinearLayer() { 134 | Init(); 135 | } 136 | 137 | unsigned int Keccak1600LinearLayer::GetNumSteps() { 138 | return linear_steps_; 139 | } 140 | 141 | Keccak1600LinearLayer* Keccak1600LinearLayer::clone() { 142 | //TODO: write copy constructor 143 | Keccak1600LinearLayer* obj = new Keccak1600LinearLayer(in, out); 144 | obj->keccak_linear_ = this->keccak_linear_; 145 | return obj; 146 | } 147 | 148 | Keccak1600LinearLayer::Keccak1600LinearLayer(StateMaskBase *in, StateMaskBase *out) 149 | : LinearLayer(in, out) { 150 | Init(); 151 | } 152 | 153 | void Keccak1600LinearLayer::Init() { 154 | keccak_linear_[0].Initialize(Keccak1600Linear); 155 | 156 | } 157 | 158 | bool Keccak1600LinearLayer::updateStep(unsigned int step_pos) { 159 | assert(step_pos <= linear_steps_); 160 | bool ret_val; 161 | ret_val = keccak_linear_[step_pos].Update( { 162 | &((*in)[0]), &((*in)[1]), &((*in)[2]), &((*in)[3]), &((*in)[4]), 163 | &((*in)[5]), &((*in)[6]), &((*in)[7]), &((*in)[8]), &((*in)[9]), 164 | &((*in)[10]), &((*in)[11]), &((*in)[12]), &((*in)[13]), &((*in)[14]), 165 | &((*in)[15]), &((*in)[16]), &((*in)[17]), &((*in)[18]), &((*in)[19]), 166 | &((*in)[20]), &((*in)[21]), &((*in)[22]), &((*in)[23]), &((*in)[24])}, 167 | {&((*out)[0]), &((*out)[1]), &((*out)[2]), &((*out)[3]), &((*out)[4]), 168 | &((*out)[5]), &((*out)[6]), &((*out)[7]), &((*out)[8]), &((*out)[9]), 169 | &((*out)[10]), &((*out)[11]), &((*out)[12]), &((*out)[13]), &((*out)[14]), 170 | &((*out)[15]), &((*out)[16]), &((*out)[17]), &((*out)[18]), &((*out)[19]), 171 | &((*out)[20]), &((*out)[21]), &((*out)[22]), &((*out)[23]), &((*out)[24])}); 172 | 173 | // TODO: Test faster update 174 | //for(int i = 0; i < 25; ++i){ 175 | // in->getWordSbox(i) |= (*in)[i].changes_; 176 | // out->getWordSbox(i) |= (*out)[i].changes_; 177 | //} 178 | return ret_val; 179 | } 180 | 181 | void Keccak1600LinearLayer::copyValues(LinearLayer* other){ 182 | Keccak1600LinearLayer* ptr = dynamic_cast (other); 183 | keccak_linear_ = ptr->keccak_linear_; 184 | } 185 | 186 | //----------------------------------------------------------------------------- 187 | 188 | BitVector Keccak1600Sbox(BitVector in) { 189 | static const BitVector sbox[32] = { 190 | 0, 5, 10, 11, 20, 17, 22, 23, 9, 12, 3, 2, 13, 8, 15, 14, 18, 21, 191 | 24, 27, 6, 1, 4, 7, 26, 29, 16, 19, 30, 25, 28, 31}; 192 | return sbox[in % 32] & 0x1f; 193 | } 194 | 195 | std::unique_ptr> Keccak1600SboxLayer::cache_; 196 | std::shared_ptr> Keccak1600SboxLayer::ldt_; 197 | 198 | Keccak1600SboxLayer& Keccak1600SboxLayer::operator=(const Keccak1600SboxLayer& rhs) { 199 | sboxes = rhs.sboxes; 200 | return *this; 201 | } 202 | 203 | Keccak1600SboxLayer::Keccak1600SboxLayer() { 204 | if(ldt_ == nullptr) 205 | ldt_.reset(new LinearDistributionTable<5>(Keccak1600Sbox)); 206 | InitSboxes(ldt_); 207 | if (this->cache_.get() == nullptr) 208 | this->cache_.reset( 209 | new LRU_Cache( 210 | cache_size_)); 211 | } 212 | 213 | Keccak1600SboxLayer::Keccak1600SboxLayer(StateMaskBase *in, StateMaskBase *out) 214 | : SboxLayer(in, out) { 215 | if(ldt_ == nullptr) 216 | ldt_.reset(new LinearDistributionTable<5>(Keccak1600Sbox)); 217 | InitSboxes(ldt_); 218 | if (this->cache_.get() == nullptr) 219 | this->cache_.reset( 220 | new LRU_Cache( 221 | cache_size_)); 222 | } 223 | 224 | Keccak1600SboxLayer* Keccak1600SboxLayer::clone() { 225 | //TODO: write copy constructor 226 | Keccak1600SboxLayer* obj = new Keccak1600SboxLayer(in, out); 227 | obj->sboxes = this->sboxes; 228 | return obj; 229 | } 230 | 231 | bool Keccak1600SboxLayer::updateStep(unsigned int step_pos) { 232 | assert(step_pos < sboxes.size()); 233 | bool ret_val; 234 | Mask copyin(GetVerticalMask(step_pos, *in)); 235 | Mask copyout(GetVerticalMask(step_pos, *out)); 236 | ret_val = sboxes[step_pos].Update(copyin, copyout, cache_.get()); 237 | SetVerticalMask(step_pos, *in, copyin); 238 | SetVerticalMask(step_pos, *out, copyout); 239 | return ret_val; 240 | } 241 | 242 | Mask Keccak1600SboxLayer::GetVerticalMask(unsigned int b, 243 | const StateMaskBase& s) const { 244 | return Mask( 245 | { s[((b/64)*5)+4].bitmasks[b%64], s[((b/64)*5)+3].bitmasks[b%64], s[((b/64)*5)+2].bitmasks[b%64], s[((b/64)*5)+1].bitmasks[b%64], 246 | s[((b/64)*5)+0].bitmasks[b%64] }); 247 | } 248 | 249 | void Keccak1600SboxLayer::SetVerticalMask(unsigned int b, StateMaskBase& s, 250 | const Mask& mask) { 251 | 252 | // TODO: Test faster update 253 | // s.getWordLinear(((b/64)*5)+0) |= ((mask.changes_>>(4))&1) << b%64; 254 | // s.getWordLinear(((b/64)*5)+1) |= ((mask.changes_>>(3))&1) << b%64; 255 | // s.getWordLinear(((b/64)*5)+2) |= ((mask.changes_>>(2))&1) << b%64; 256 | // s.getWordLinear(((b/64)*5)+3) |= ((mask.changes_>>(1))&1) << b%64; 257 | // s.getWordLinear(((b/64)*5)+4) |= ((mask.changes_>>(0))&1) << b%64; 258 | 259 | s[((b/64)*5)+0].bitmasks[b%64] = mask.bitmasks[4]; 260 | s[((b/64)*5)+1].bitmasks[b%64] = mask.bitmasks[3]; 261 | s[((b/64)*5)+2].bitmasks[b%64] = mask.bitmasks[2]; 262 | s[((b/64)*5)+3].bitmasks[b%64] = mask.bitmasks[1]; 263 | s[((b/64)*5)+4].bitmasks[b%64] = mask.bitmasks[0]; 264 | BitVector m = ~(1ULL << b); 265 | s[((b/64)*5)+0].caremask.canbe1 = (s[((b/64)*5)+0].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 4) & 1) << (b%64)); 266 | s[((b/64)*5)+1].caremask.canbe1 = (s[((b/64)*5)+1].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 3) & 1) << (b%64)); 267 | s[((b/64)*5)+2].caremask.canbe1 = (s[((b/64)*5)+2].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 2) & 1) << (b%64)); 268 | s[((b/64)*5)+3].caremask.canbe1 = (s[((b/64)*5)+3].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 1) & 1) << (b%64)); 269 | s[((b/64)*5)+4].caremask.canbe1 = (s[((b/64)*5)+4].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 0) & 1) << (b%64)); 270 | 271 | s[((b/64)*5)+0].caremask.care = (s[((b/64)*5)+0].caremask.care & m) | (((mask.caremask.care >> 4) & 1) << (b%64)); 272 | s[((b/64)*5)+1].caremask.care = (s[((b/64)*5)+1].caremask.care & m) | (((mask.caremask.care >> 3) & 1) << (b%64)); 273 | s[((b/64)*5)+2].caremask.care = (s[((b/64)*5)+2].caremask.care & m) | (((mask.caremask.care >> 2) & 1) << (b%64)); 274 | s[((b/64)*5)+3].caremask.care = (s[((b/64)*5)+3].caremask.care & m) | (((mask.caremask.care >> 1) & 1) << (b%64)); 275 | s[((b/64)*5)+4].caremask.care = (s[((b/64)*5)+4].caremask.care & m) | (((mask.caremask.care >> 0) & 1) << (b%64)); 276 | } 277 | 278 | -------------------------------------------------------------------------------- /target/icepole.cpp: -------------------------------------------------------------------------------- 1 | #include "icepole.h" 2 | 3 | //#define HEXOUTPUT 4 | //#define LATEX 5 | 6 | IcepoleState::IcepoleState() 7 | : StateMask() { 8 | } 9 | 10 | IcepoleState* IcepoleState::clone() { 11 | IcepoleState* obj = new IcepoleState(); 12 | for (size_t j = 0; j < words_.size(); ++j) { 13 | obj->words_[j] = words_[j]; 14 | obj->changes_for_linear_layer_[j] = changes_for_linear_layer_[j]; 15 | obj->changes_for_sbox_layer_[j] = changes_for_sbox_layer_[j]; 16 | } 17 | return obj; 18 | } 19 | 20 | void IcepoleState::print(std::ostream& stream) { 21 | stream << *this; 22 | } 23 | 24 | #ifdef HEXOUTPUT 25 | #ifdef LATEX 26 | std::ostream& operator<<(std::ostream& stream, const IcepoleState& statemask) { 27 | 28 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 29 | unsigned long long outword = 0; 30 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 31 | outword <<= 1; 32 | if (*it % 4 == 1) 33 | outword |=1; 34 | } 35 | stream << " & \\texttt{" << std::hex << std::setfill('0') << std::setw(16) << outword << std::dec << "}"; 36 | if(i%5 == 4) 37 | stream << " \\\\ "<< std::endl; 38 | } 39 | // stream << " \\\\ "<< std::endl; 40 | return stream; 41 | } 42 | #else 43 | std::ostream& operator<<(std::ostream& stream, const IcepoleState& statemask) { 44 | 45 | for (size_t i = 0; i < statemask.words_.size(); ++i) { 46 | unsigned long long outword = 0; 47 | for (auto it = statemask.words_[i].bitmasks.rbegin(); it != statemask.words_[i].bitmasks.rend(); ++it) { 48 | outword <<= 1; 49 | if (*it % 4 == 1) 50 | outword |=1; 51 | } 52 | stream << std::hex << std::setfill('0') << std::setw(16) << outword << std::dec << "\t"; 53 | if(i%5 == 4) 54 | stream << std::endl; 55 | } 56 | return stream; 57 | } 58 | #endif 59 | #else 60 | std::ostream& operator<<(std::ostream& stream, const IcepoleState& statemask) { 61 | #ifndef TERMINALCOLORS 62 | char symbol[4] {'#', '1', '0', '?'}; 63 | #else 64 | std::string symbol[4] { "\033[1;35m#\033[0m", "\033[1;31m1\033[0m", "0", 65 | "\033[1;33m?\033[0m" }; 66 | #endif 67 | for (Mask word : statemask.words_) { 68 | for (auto it = word.bitmasks.rbegin(); it != word.bitmasks.rend(); ++it) { 69 | stream << symbol[*it % 4]; 70 | } 71 | stream << std::endl; 72 | } 73 | return stream; 74 | } 75 | #endif 76 | 77 | //----------------------------------------------------------------------------- 78 | 79 | std::array IcepoleLinear(std::array in) { 80 | BitVector tmp[20]; 81 | 82 | //the code used in this function is taken and modified from the reference version of ICEPOLE available at 83 | //http://bench.cr.yp.to/ebash.html 84 | 85 | tmp[0*5+0] = in[0*5+4] ^ in[1*5+0] ^ in[2*5+0] ^ in[3*5+0]; 86 | tmp[0*5+1] = in[0*5+0] ^ in[1*5+1] ^ in[2*5+1] ^ in[3*5+1]; 87 | tmp[0*5+2] = in[0*5+4] ^ in[0*5+1] ^ in[1*5+2] ^ in[2*5+2] ^ in[3*5+2]; 88 | tmp[0*5+3] = in[0*5+2] ^ in[1*5+3] ^ in[2*5+3] ^ in[3*5+3]; 89 | tmp[0*5+4] = in[0*5+3] ^ in[1*5+4] ^ in[2*5+4] ^ in[3*5+4]; 90 | 91 | tmp[1*5+0] = in[0*5+0] ^ in[1*5+0] ^ in[2*5+1] ^ in[3*5+4]; 92 | tmp[1*5+1] = in[0*5+1] ^ in[1*5+1] ^ in[2*5+2] ^ in[2*5+0] ^ in[3*5+0]; 93 | tmp[1*5+2] = in[0*5+2] ^ in[1*5+2] ^ in[2*5+3] ^ in[3*5+4] ^ in[3*5+1]; 94 | tmp[1*5+3] = in[0*5+3] ^ in[1*5+3] ^ in[2*5+4] ^ in[3*5+2]; 95 | tmp[1*5+4] = in[0*5+4] ^ in[1*5+4] ^ in[2*5+0] ^ in[3*5+3]; 96 | 97 | tmp[2*5+0] = in[0*5+0] ^ in[1*5+4] ^ in[2*5+0] ^ in[3*5+1]; 98 | tmp[2*5+1] = in[0*5+1] ^ in[1*5+0] ^ in[2*5+1] ^ in[3*5+2] ^ in[3*5+0]; 99 | tmp[2*5+2] = in[0*5+2] ^ in[1*5+4] ^ in[1*5+1] ^ in[2*5+2] ^ in[3*5+3]; 100 | tmp[2*5+3] = in[0*5+3] ^ in[1*5+2] ^ in[2*5+3] ^ in[3*5+4]; 101 | tmp[2*5+4] = in[0*5+4] ^ in[1*5+3] ^ in[2*5+4] ^ in[3*5+0]; 102 | 103 | tmp[3*5+0] = in[0*5+0] ^ in[1*5+1] ^ in[2*5+4] ^ in[3*5+0]; 104 | tmp[3*5+1] = in[0*5+1] ^ in[1*5+2] ^ in[1*5+0] ^ in[2*5+0] ^ in[3*5+1]; 105 | tmp[3*5+2] = in[0*5+2] ^ in[1*5+3] ^ in[2*5+4] ^ in[2*5+1] ^ in[3*5+2]; 106 | tmp[3*5+3] = in[0*5+3] ^ in[1*5+4] ^ in[2*5+2] ^ in[3*5+3]; 107 | tmp[3*5+4] = in[0*5+4] ^ in[1*5+0] ^ in[2*5+3] ^ in[3*5+4]; 108 | 109 | tmp[0*5+1] = ROTL(tmp[0*5+1], 36); 110 | tmp[0*5+2] = ROTL(tmp[0*5+2], 3); 111 | tmp[0*5+3] = ROTL(tmp[0*5+3], 41); 112 | tmp[0*5+4] = ROTL(tmp[0*5+4], 18); 113 | 114 | tmp[1*5+0] = ROTL(tmp[1*5+0], 1); 115 | tmp[1*5+1] = ROTL(tmp[1*5+1], 44); 116 | tmp[1*5+2] = ROTL(tmp[1*5+2], 10); 117 | tmp[1*5+3] = ROTL(tmp[1*5+3], 45); 118 | tmp[1*5+4] = ROTL(tmp[1*5+4], 2); 119 | 120 | tmp[2*5+0] = ROTL(tmp[2*5+0], 62); 121 | tmp[2*5+1] = ROTL(tmp[2*5+1], 6); 122 | tmp[2*5+2] = ROTL(tmp[2*5+2], 43); 123 | tmp[2*5+3] = ROTL(tmp[2*5+3], 15); 124 | tmp[2*5+4] = ROTL(tmp[2*5+4], 61); 125 | 126 | tmp[3*5+0] = ROTL(tmp[3*5+0], 28); 127 | tmp[3*5+1] = ROTL(tmp[3*5+1], 55); 128 | tmp[3*5+2] = ROTL(tmp[3*5+2], 25); 129 | tmp[3*5+3] = ROTL(tmp[3*5+3], 21); 130 | tmp[3*5+4] = ROTL(tmp[3*5+4], 56); 131 | 132 | unsigned int x,y; 133 | for(x = 0; x < 4; ++x) { 134 | for (y = 0; y < 5; ++y) { 135 | unsigned int xx = (x + y) % 4; 136 | unsigned int yy = (xx + y + 1) % 5; 137 | in[xx*5+yy] = tmp[x*5+y]; 138 | } 139 | } 140 | 141 | return in; 142 | } 143 | 144 | IcepoleLinearLayer& IcepoleLinearLayer::operator=(const IcepoleLinearLayer& rhs) { 145 | icepole_linear_ = rhs.icepole_linear_; 146 | return *this; 147 | } 148 | 149 | IcepoleLinearLayer::IcepoleLinearLayer() { 150 | Init(); 151 | } 152 | 153 | unsigned int IcepoleLinearLayer::GetNumSteps() { 154 | return linear_steps_; 155 | } 156 | 157 | IcepoleLinearLayer* IcepoleLinearLayer::clone() { 158 | //TODO: write copy constructor 159 | IcepoleLinearLayer* obj = new IcepoleLinearLayer(in, out); 160 | obj->icepole_linear_ = this->icepole_linear_; 161 | return obj; 162 | } 163 | 164 | IcepoleLinearLayer::IcepoleLinearLayer(StateMaskBase *in, StateMaskBase *out) 165 | : LinearLayer(in, out) { 166 | Init(); 167 | } 168 | 169 | void IcepoleLinearLayer::Init() { 170 | icepole_linear_[0].Initialize(IcepoleLinear); 171 | 172 | } 173 | 174 | bool IcepoleLinearLayer::updateStep(unsigned int step_pos) { 175 | assert(step_pos <= linear_steps_); 176 | bool ret_val; 177 | ret_val = icepole_linear_[step_pos].Update( { 178 | &((*in)[0]), &((*in)[1]), &((*in)[2]), &((*in)[3]), &((*in)[4]), 179 | &((*in)[5]), &((*in)[6]), &((*in)[7]), &((*in)[8]), &((*in)[9]), 180 | &((*in)[10]), &((*in)[11]), &((*in)[12]), &((*in)[13]), &((*in)[14]), 181 | &((*in)[15]), &((*in)[16]), &((*in)[17]), &((*in)[18]), &((*in)[19])}, 182 | {&((*out)[0]), &((*out)[1]), &((*out)[2]), &((*out)[3]), &((*out)[4]), 183 | &((*out)[5]), &((*out)[6]), &((*out)[7]), &((*out)[8]), &((*out)[9]), 184 | &((*out)[10]), &((*out)[11]), &((*out)[12]), &((*out)[13]), &((*out)[14]), 185 | &((*out)[15]), &((*out)[16]), &((*out)[17]), &((*out)[18]), &((*out)[19])}); 186 | 187 | for(int i = 0; i < 20; ++i){ 188 | in->getWordSbox(i) |= (*in)[i].changes_; 189 | out->getWordSbox(i) |= (*out)[i].changes_; 190 | } 191 | return ret_val; 192 | } 193 | 194 | void IcepoleLinearLayer::copyValues(LinearLayer* other){ 195 | IcepoleLinearLayer* ptr = dynamic_cast (other); 196 | icepole_linear_ = ptr->icepole_linear_; 197 | } 198 | 199 | //----------------------------------------------------------------------------- 200 | 201 | BitVector IcepoleSbox(BitVector in) { 202 | static const BitVector sbox[32] = { 203 | 31, 5, 10, 11, 20, 17, 22, 23, 9, 12, 3, 2, 13, 8, 15, 14, 18, 21, 204 | 24, 27, 6, 1, 4, 7, 26, 29, 16, 19, 30, 25, 28, 0}; 205 | return sbox[in % 32] & 0x1f; 206 | } 207 | 208 | std::unique_ptr> IcepoleSboxLayer::cache_; 209 | std::shared_ptr> IcepoleSboxLayer::ldt_; 210 | 211 | IcepoleSboxLayer& IcepoleSboxLayer::operator=(const IcepoleSboxLayer& rhs) { 212 | sboxes = rhs.sboxes; 213 | return *this; 214 | } 215 | 216 | IcepoleSboxLayer::IcepoleSboxLayer() { 217 | if(ldt_ == nullptr) 218 | ldt_.reset(new LinearDistributionTable<5>(IcepoleSbox)); 219 | InitSboxes(ldt_); 220 | if (this->cache_.get() == nullptr) 221 | this->cache_.reset( 222 | new LRU_Cache( 223 | cache_size_)); 224 | } 225 | 226 | IcepoleSboxLayer::IcepoleSboxLayer(StateMaskBase *in, StateMaskBase *out) 227 | : SboxLayer(in, out) { 228 | if(ldt_ == nullptr) 229 | ldt_.reset(new LinearDistributionTable<5>(IcepoleSbox)); 230 | InitSboxes(ldt_); 231 | if (this->cache_.get() == nullptr) 232 | this->cache_.reset( 233 | new LRU_Cache( 234 | cache_size_)); 235 | } 236 | 237 | IcepoleSboxLayer* IcepoleSboxLayer::clone() { 238 | //TODO: write copy constructor 239 | IcepoleSboxLayer* obj = new IcepoleSboxLayer(in, out); 240 | obj->sboxes = this->sboxes; 241 | return obj; 242 | } 243 | 244 | bool IcepoleSboxLayer::updateStep(unsigned int step_pos) { 245 | assert(step_pos < sboxes.size()); 246 | bool ret_val; 247 | Mask copyin(GetVerticalMask(step_pos, *in)); 248 | Mask copyout(GetVerticalMask(step_pos, *out)); 249 | ret_val = sboxes[step_pos].Update(copyin, copyout, cache_.get()); 250 | SetVerticalMask(step_pos, *in, copyin); 251 | SetVerticalMask(step_pos, *out, copyout); 252 | return ret_val; 253 | } 254 | 255 | Mask IcepoleSboxLayer::GetVerticalMask(unsigned int b, 256 | const StateMaskBase& s) const { 257 | return Mask( 258 | { s[((b/64)*5)+4].bitmasks[b%64], s[((b/64)*5)+3].bitmasks[b%64], s[((b/64)*5)+2].bitmasks[b%64], s[((b/64)*5)+1].bitmasks[b%64], 259 | s[((b/64)*5)+0].bitmasks[b%64] }); 260 | } 261 | 262 | void IcepoleSboxLayer::SetVerticalMask(unsigned int b, StateMaskBase& s, 263 | const Mask& mask) { 264 | 265 | s.getWordLinear(((b/64)*5)+0) |= ((mask.changes_>>(4))&1) << b%64; 266 | s.getWordLinear(((b/64)*5)+1) |= ((mask.changes_>>(3))&1) << b%64; 267 | s.getWordLinear(((b/64)*5)+2) |= ((mask.changes_>>(2))&1) << b%64; 268 | s.getWordLinear(((b/64)*5)+3) |= ((mask.changes_>>(1))&1) << b%64; 269 | s.getWordLinear(((b/64)*5)+4) |= ((mask.changes_>>(0))&1) << b%64; 270 | 271 | s[((b/64)*5)+0].bitmasks[b%64] = mask.bitmasks[4]; 272 | s[((b/64)*5)+1].bitmasks[b%64] = mask.bitmasks[3]; 273 | s[((b/64)*5)+2].bitmasks[b%64] = mask.bitmasks[2]; 274 | s[((b/64)*5)+3].bitmasks[b%64] = mask.bitmasks[1]; 275 | s[((b/64)*5)+4].bitmasks[b%64] = mask.bitmasks[0]; 276 | BitVector m = ~(1ULL << b); 277 | s[((b/64)*5)+0].caremask.canbe1 = (s[((b/64)*5)+0].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 4) & 1) << (b%64)); 278 | s[((b/64)*5)+1].caremask.canbe1 = (s[((b/64)*5)+1].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 3) & 1) << (b%64)); 279 | s[((b/64)*5)+2].caremask.canbe1 = (s[((b/64)*5)+2].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 2) & 1) << (b%64)); 280 | s[((b/64)*5)+3].caremask.canbe1 = (s[((b/64)*5)+3].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 1) & 1) << (b%64)); 281 | s[((b/64)*5)+4].caremask.canbe1 = (s[((b/64)*5)+4].caremask.canbe1 & m) | (((mask.caremask.canbe1 >> 0) & 1) << (b%64)); 282 | 283 | s[((b/64)*5)+0].caremask.care = (s[((b/64)*5)+0].caremask.care & m) | (((mask.caremask.care >> 4) & 1) << (b%64)); 284 | s[((b/64)*5)+1].caremask.care = (s[((b/64)*5)+1].caremask.care & m) | (((mask.caremask.care >> 3) & 1) << (b%64)); 285 | s[((b/64)*5)+2].caremask.care = (s[((b/64)*5)+2].caremask.care & m) | (((mask.caremask.care >> 2) & 1) << (b%64)); 286 | s[((b/64)*5)+3].caremask.care = (s[((b/64)*5)+3].caremask.care & m) | (((mask.caremask.care >> 1) & 1) << (b%64)); 287 | s[((b/64)*5)+4].caremask.care = (s[((b/64)*5)+4].caremask.care & m) | (((mask.caremask.care >> 0) & 1) << (b%64)); 288 | } 289 | 290 | --------------------------------------------------------------------------------