Example #1
0
    def verify(self):
        """
        This implementation of verify has several steps. First, it
        reorganizes the pubkeys and messages into groups, where
        each group corresponds to a message. Then, it checks if the
        siganture has info on how it was aggregated. If so, we
        exponentiate each pk based on the exponent in the AggregationInfo.
        If not, we find public keys that share messages with others,
        and aggregate all of these securely (with exponents.).
        Finally, since each public key now corresponds to a unique
        message (since we grouped them), we can verify using the
        distinct verification procedure.
        """
        message_hashes = self.aggregation_info.message_hashes
        public_keys = self.aggregation_info.public_keys
        assert (len(message_hashes) == len(public_keys))

        hash_to_public_keys = {}
        for i in range(len(message_hashes)):
            if message_hashes[i] in hash_to_public_keys:
                hash_to_public_keys[message_hashes[i]].append(public_keys[i])
            else:
                hash_to_public_keys[message_hashes[i]] = [public_keys[i]]

        final_message_hashes = []
        final_public_keys = []
        ec = public_keys[0].value.ec
        for message_hash, mapped_keys in hash_to_public_keys.items():
            dedup = list(set(mapped_keys))
            public_key_sum = JacobianPoint(Fq.one(ec.q), Fq.one(ec.q),
                                           Fq.zero(ec.q), True, ec)
            for public_key in dedup:
                try:
                    exponent = self.aggregation_info.tree[(message_hash,
                                                           public_key)]
                    public_key_sum += (public_key.value * exponent)
                except KeyError:
                    return False
            final_message_hashes.append(message_hash)
            final_public_keys.append(public_key_sum.to_affine())

        mapped_hashes = [
            hash_to_point_prehashed_Fq2(mh) for mh in final_message_hashes
        ]

        g1 = Fq(default_ec.n, -1) * generator_Fq()
        Ps = [g1] + final_public_keys
        Qs = [self.value.to_affine()] + mapped_hashes
        res = ate_pairing_multi(Ps, Qs, default_ec)
        return res == Fq12.one(default_ec.q)
Example #2
0
    def verify(self, message_hashes, public_keys):
        """
        Verifies messages using the prepend method. It prepends public keys
        to message hashes before verifying.
        """
        assert (len(message_hashes) == len(public_keys))
        mapped_hashes = [
            hash_to_point_prehashed_Fq2(
                hash256(public_keys[i].serialize() + message_hashes[i]))
            for i in range(len(message_hashes))
        ]
        keys = [pk.value.to_affine() for pk in public_keys]

        g1 = Fq(default_ec.n, -1) * generator_Fq()
        Ps = [g1] + keys
        Qs = [self.value.to_affine()] + mapped_hashes
        res = ate_pairing_multi(Ps, Qs, default_ec)
        return res == Fq12.one(default_ec.q)
Example #3
0
 def sign_prehashed(self, h):
     r = hash_to_point_prehashed_Fq2(h).to_jacobian()
     aggregation_info = AggregationInfo.from_msg_hash(
         self.get_public_key(), h)
     return Signature.from_g2(self.value * r, aggregation_info)
Example #4
0
 def sign_prepend_prehashed(self, h):
     final_message = hash256(self.get_public_key().serialize() + h)
     r = hash_to_point_prehashed_Fq2(final_message).to_jacobian()
     return PrependSignature(self.value * r)