-rw-r--r-- 4014 cryptattacktester-20230614/bit.h raw
#ifndef bit_h #define bit_h #include "bigint.h" #include "bit_cost.h" #include <cassert> #include <bitset> #include <vector> #define bit_slicing 64 enum bit_ops_selector { bit_ops_cost, bit_ops_not, bit_ops_xor, bit_ops_and, bit_ops_or, bit_ops_xnor, bit_ops_andn, bit_ops_nand, bit_ops_orn, bit_ops_nor, bit_ops_mux, bit_ops_cswap, } ; const std::vector<bit_ops_selector> bit_ops_selectors = { bit_ops_cost, bit_ops_not, bit_ops_xor, bit_ops_and, bit_ops_or, bit_ops_xnor, bit_ops_andn, bit_ops_nand, bit_ops_orn, bit_ops_nor, bit_ops_mux, bit_ops_cswap, } ; class bit { static bigint cost; static bigint numnot; static bigint numxor; static bigint numand; static bigint numor; static bigint numxnor; static bigint numandn; static bigint numnand; static bigint numorn; static bigint numnor; static bigint nummux; static bigint numcswap; std::bitset<bit_slicing> b; public: static bigint ops(void) { return cost; } static bigint ops(bit_ops_selector t) { switch(t) { case bit_ops_not: return numnot; case bit_ops_xor: return numxor; case bit_ops_and: return numand; case bit_ops_or: return numor; case bit_ops_xnor: return numxnor; case bit_ops_andn: return numandn; case bit_ops_nand: return numnand; case bit_ops_orn: return numorn; case bit_ops_nor: return numnor; case bit_ops_mux: return nummux; case bit_ops_cswap: return numcswap; default: return cost; } } static const char *opsname(bit_ops_selector t) { switch(t) { case bit_ops_not: return "not"; case bit_ops_xor: return "xor"; case bit_ops_and: return "and"; case bit_ops_or: return "or"; case bit_ops_xnor: return "xnor"; case bit_ops_andn: return "andn"; case bit_ops_nand: return "nand"; case bit_ops_orn: return "orn"; case bit_ops_nor: return "nor"; case bit_ops_mux: return "mux"; case bit_ops_cswap: return "cswap"; default: return "ops"; } } static void clear_all() { cost = 0; numnot = 0; numxor = 0; numand = 0; numor = 0; numxnor = 0; numandn = 0; numnand = 0; numorn = 0; numnor = 0; nummux = 0; numcswap = 0; } std::bitset<bit_slicing> value_vector(void) const { return b; } bool value(void) const { return b[0]; } void value_assert_eq(const bit &c) { assert(b == c.b); } bit(unsigned long i = 0) : b(-(i & 1)) { } bit(std::bitset<bit_slicing> x) : b(x) { } bit operator~() const { cost += bit_not_cost; ++numnot; return bit(b ^ std::bitset<bit_slicing>(-(unsigned long long) 1)); } bit operator^(const bit &c) const { cost += bit_xor_cost; ++numxor; return bit(b ^ c.b); } bit operator&(const bit &c) const { cost += bit_and_cost; ++numand; return bit(b & c.b); } bit operator|(const bit &c) const { cost += bit_or_cost; ++numor; return bit(b | c.b); } bit xnor(const bit &c) const { cost += bit_xnor_cost; ++numxnor; return bit(~(b ^ c.b)); } bit andn(const bit &c) const { cost += bit_andn_cost; ++numandn; return bit(b & ~c.b); } bit nand(const bit &c) const { cost += bit_nand_cost; ++numnand; return bit(~(b & c.b)); } bit orn(const bit &c) const { cost += bit_orn_cost; ++numorn; return bit(b | ~c.b); } bit nor(const bit &c) const { cost += bit_nor_cost; ++numnor; return bit(~(b | c.b)); } bit mux(const bit &c0,const bit &c1) const { cost += bit_mux_cost; ++nummux; return bit(c0.b ^ (b & (c0.b ^ c1.b))); } void cswap(bit &c0,bit &c1) const { cost += bit_cswap_cost; ++numcswap; bit flip = bit(b & (c0.b ^ c1.b)); bit t0 = bit(c0.b ^ flip.b); // i.e., this->mux(b0,b1) bit t1 = bit(c1.b ^ flip.b); // i.e., this->mux(b1,b0) c0 = t0; c1 = t1; } bit operator^=(const bit &c) { *this = *this ^ c; return *this; } bit operator&=(const bit &c) { *this = *this & c; return *this; } bit operator|=(const bit &c) { *this = *this | c; return *this; } } ; #endif