def __call__(self, com, g, h, a, b, x, r): """ Get a conjunction of two range-power-of-two proofs. Args: com: Value of the Pedersen commitment, :math:`C = x G + r H` g: First commitment base point :math:`G` h: Second commitment base point :math:`H` a: Lower limit :math:`a` b: Upper limit :math:`b` x: Value for which we construct a range proof r: Randomizer of the commitment :math:`r` """ a = ensure_bn(a) b = ensure_bn(b) num_bits = (b - a - 1).num_bits() offset = Bn(2)**num_bits - (b - a) com_shifted1 = com - a * g com_shifted2 = com_shifted1 + offset * g x1 = Secret() x2 = Secret() if x.value is not None: x1.value = x.value - a x2.value = x.value - a + offset # Ensure secret is in range if x.value < a or x.value >= b: warnings.warn("Secret outside of given range [{}, {})".format( a, b)) com_stmt = DLRep(com, x * g + r * h) p1 = PowerTwoRangeStmt( com=com_shifted1, g=g, h=h, num_bits=num_bits, x=x1, randomizer=r, ) p2 = PowerTwoRangeStmt( com=com_shifted2, g=g, h=h, num_bits=num_bits, x=x2, randomizer=r, ) return com_stmt & p1 & p2
def __call__(self, a, b, x=None): """ Get a conjunction of two range-power-of-two proofs. Args: a: Lower limit :math:`a` b: Upper limit :math:`b` x: Value for which we construct a range proof """ group = EcGroup() g = group.hash_to_point(b"g") h = group.hash_to_point(b"h") r = Secret(value=group.order().random()) com = (x * g + r * h).eval() a = ensure_bn(a) b = ensure_bn(b) num_bits = (b - a - 1).num_bits() offset = Bn(2)**num_bits - (b - a) com_shifted1 = com - a * g com_shifted2 = com_shifted1 + offset * g x1 = Secret() x2 = Secret() if x is not None: x1.value = x.value - a x2.value = x.value - a + offset com_stmt = DLRep(com, x * g + r * h) p1 = PowerTwoRangeStmt( com=com_shifted1, g=g, h=h, num_bits=num_bits, x=x1, randomizer=r, ) p2 = PowerTwoRangeStmt( com=com_shifted2, g=g, h=h, num_bits=num_bits, x=x2, randomizer=r, ) return com_stmt & p1 & p2