class cbits(bits): max_length = 64 reg_type = 'cb' is_clear = True load_inst = (None, inst.ldmc) store_inst = (None, inst.stmc) bitdec = inst.bitdecc conv_regint = staticmethod(lambda n, x, y: inst.convcint(x, y)) types = {} def load_int(self, value): self.load_other(regint(value)) def store_in_dynamic_mem(self, address): inst.stmsdci(self, cbits.conv(address)) def clear_op(self, other, c_inst, ci_inst, op): if isinstance(other, cbits): res = cbits(n=max(self.n, other.n)) c_inst(res, self, other) return res else: if util.is_constant(other): if other >= 2**31 or other < -2**31: return op(self, cbits(other)) res = cbits(n=max(self.n, len(bin(other)) - 2)) ci_inst(res, self, other) return res else: return op(self, cbits(other)) __add__ = lambda self, other: \ self.clear_op(other, inst.addc, inst.addci, operator.add) __xor__ = lambda self, other: \ self.clear_op(other, inst.xorc, inst.xorci, operator.xor) __radd__ = __add__ __rxor__ = __xor__ def __mul__(self, other): if isinstance(other, cbits): return NotImplemented else: try: res = cbits(n=min(self.max_length, self.n + util.int_len(other))) inst.mulci(res, self, other) return res except TypeError: return NotImplemented def __rshift__(self, other): res = cbits(n=self.n - other) inst.shrci(res, self, other) return res def __lshift__(self, other): res = cbits(n=self.n + other) inst.shlci(res, self, other) return res def print_reg(self, desc=''): inst.print_reg(self, desc) def print_reg_plain(self): inst.print_reg_signed(self.n, self) output = print_reg_plain def print_if(self, string): inst.cond_print_str(self, string) def reveal(self): return self
class cbits(bits): max_length = 64 reg_type = 'cb' is_clear = True load_inst = (None, inst.ldmcb) store_inst = (None, inst.stmcb) bitdec = inst.bitdecc conv_regint = staticmethod(lambda n, x, y: inst.convcint(x, y)) conv_cint_vec = inst.convcintvec @classmethod def conv_regint_by_bit(cls, n, res, other): assert n == res.n assert n == other.size cls.conv_cint_vec(cint(other, size=other.size), res) types = {} def load_int(self, value): self.load_other(regint(value)) def store_in_dynamic_mem(self, address): inst.stmsdci(self, cbits.conv(address)) def clear_op(self, other, c_inst, ci_inst, op): if isinstance(other, cbits): res = cbits(n=max(self.n, other.n)) c_inst(res, self, other) return res else: if util.is_constant(other): if other >= 2**31 or other < -2**31: return op(self, cbits(other)) res = cbits(n=max(self.n, len(bin(other)) - 2)) ci_inst(res, self, other) return res else: return op(self, cbits(other)) __add__ = lambda self, other: \ self.clear_op(other, inst.addcb, inst.addcbi, operator.add) __sub__ = lambda self, other: \ self.clear_op(-other, inst.addcb, inst.addcbi, operator.add) __xor__ = lambda self, other: \ self.clear_op(other, inst.xorcb, inst.xorcbi, operator.xor) __radd__ = __add__ __rxor__ = __xor__ def __mul__(self, other): if isinstance(other, cbits): return NotImplemented else: try: res = cbits(n=min(self.max_length, self.n+util.int_len(other))) inst.mulcbi(res, self, other) return res except TypeError: return NotImplemented def __rshift__(self, other): res = cbits(n=self.n-other) inst.shrcbi(res, self, other) return res def __lshift__(self, other): res = cbits(n=self.n+other) inst.shlcbi(res, self, other) return res def print_reg(self, desc=''): inst.print_regb(self, desc) def print_reg_plain(self): inst.print_reg_signed(self.n, self) output = print_reg_plain def print_if(self, string): inst.cond_print_strb(self, string) def reveal(self): return self def to_regint(self, dest=None): if dest is None: dest = regint() if self.n > 64: raise CompilerError('too many bits') inst.convcbit(dest, self) return dest def to_regint_by_bit(self): if self.n != None: res = regint(size=self.n) else: res = regint() inst.convcbitvec(self.n, res, self) return res
class cbits(bits): """ Clear bits register. Helper type with limited functionality. """ max_length = 64 reg_type = 'cb' is_clear = True load_inst = (inst.ldmcbi, inst.ldmcb) store_inst = (inst.stmcbi, inst.stmcb) bitdec = inst.bitdecc conv_regint = staticmethod(lambda n, x, y: inst.convcint(x, y)) conv_cint_vec = inst.convcintvec @classmethod def bit_compose(cls, bits): return sum(bit << i for i, bit in enumerate(bits)) @classmethod def conv_regint_by_bit(cls, n, res, other): assert n == res.n assert n == other.size cls.conv_cint_vec(cint(other, size=other.size), res) @classmethod def conv(cls, other): if isinstance(other, cbits) and cls.n != None and \ cls.n // cls.unit == other.n // cls.unit: return other else: return super(cbits, cls).conv(other) types = {} def load_int(self, value): n_limbs = math.ceil(self.n / self.unit) tmp = regint(size=n_limbs) for i in range(n_limbs): tmp[i].load_int(value % 2 ** self.unit) value >>= self.unit self.load_other(tmp) def store_in_dynamic_mem(self, address): inst.stmsdci(self, cbits.conv(address)) def clear_op(self, other, c_inst, ci_inst, op): if isinstance(other, cbits): res = cbits.get_type(max(self.n, other.n))() c_inst(res, self, other) return res elif isinstance(other, sbits): return NotImplemented else: if util.is_constant(other): if other >= 2**31 or other < -2**31: return op(self, cbits.new(other)) res = cbits.get_type(max(self.n, len(bin(other)) - 2))() ci_inst(res, self, other) return res else: return op(self, cbits(other)) __add__ = lambda self, other: \ self.clear_op(other, inst.addcb, inst.addcbi, operator.add) __sub__ = lambda self, other: \ self.clear_op(-other, inst.addcb, inst.addcbi, operator.add) def _xor(self, other): if isinstance(other, (sbits, sbitvec)): return NotImplemented elif isinstance(other, cbits): res = self.res_type(other)() assert res.size == self.size assert res.size == other.size inst.xorcb(res.n, res, self, other) return res else: return self.clear_op(other, None, inst.xorcbi, operator.xor) def _and(self, other): return NotImplemented __radd__ = __add__ def __mul__(self, other): if isinstance(other, cbits): return NotImplemented else: try: res = cbits.get_type(min(self.max_length, self.n+util.int_len(other)))() inst.mulcbi(res, self, other) return res except TypeError: return NotImplemented def __rshift__(self, other): res = cbits.new(n=self.n-other) inst.shrcbi(res, self, other) return res def __lshift__(self, other): res = cbits.get_type(self.n+other)() inst.shlcbi(res, self, other) return res def __invert__(self): res = type(self)() inst.notcb(self.n, res, self) return res def __eq__(self, other): raise CompilerError('equality not implemented') def print_reg(self, desc=''): inst.print_regb(self, desc) def print_reg_plain(self): inst.print_reg_signed(self.n, self) output = print_reg_plain def print_if(self, string): inst.cond_print_strb(self, string) def output_if(self, cond): if Program.prog.options.binary: raise CompilerError('conditional output not supported') cint(self).output_if(cond) def reveal(self): return self def to_regint(self, dest=None): if dest is None: dest = regint() if self.n > 64: raise CompilerError('too many bits') inst.convcbit(dest, self) return dest def to_regint_by_bit(self): if self.n != None: res = regint(size=self.n) else: res = regint() inst.convcbitvec(self.n, res, self) return res