def _CoreAggregateVerify(cls, PKs: Sequence[BLSPubkey], messages: Sequence[bytes], signature: BLSSignature, DST: bytes) -> bool: try: if len(PKs) != len(messages): raise ValidationError( 'len(PKs) != len(messages): got len(PKs)=%s, len(messages)=%s' % (len(PKs), len(messages))) if len(PKs) < 1: raise ValidationError( 'Insufficient number of PKs: should be greater than' ' or equal to 1, got %d' % len(PKs)) signature_point = signature_to_G2(signature) aggregate = FQ12.one() for pk, message in zip(PKs, messages): pubkey_point = pubkey_to_G1(pk) message_point = hash_to_G2(message, DST, cls.xmd_hash_function) aggregate *= pairing(message_point, pubkey_point, final_exponentiate=False) aggregate *= pairing(signature_point, neg(G1), final_exponentiate=False) return final_exponentiate(aggregate) == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def _CoreAggregateVerify(cls, PKs: Sequence[BLSPubkey], messages: Sequence[bytes], signature: BLSSignature, DST: bytes) -> bool: try: # Inputs validation for pk in PKs: assert cls._is_valid_pubkey(pk) for message in messages: assert cls._is_valid_message(message) assert len(PKs) == len(messages) assert cls._is_valid_signature(signature) # Preconditions assert len(PKs) >= 1 # Procedure signature_point = signature_to_G2(signature) if not subgroup_check(signature_point): return False aggregate = FQ12.one() for pk, message in zip(PKs, messages): assert cls.KeyValidate(pk) pubkey_point = pubkey_to_G1(pk) message_point = hash_to_G2(message, DST, cls.xmd_hash_function) aggregate *= pairing(message_point, pubkey_point, final_exponentiate=False) aggregate *= pairing(signature_point, neg(G1), final_exponentiate=False) return final_exponentiate(aggregate) == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def execute(cls, stack: 'MichelsonStack', stdout: List[str], context: AbstractContext): points = cast(ListType, stack.pop1()) points.assert_type_equal( ListType.create_type(args=[ PairType.create_type(args=[BLS12_381_G1Type, BLS12_381_G2Type]) ])) prod = FQ12.one() for pair in points: g1, g2 = tuple( iter(pair)) # type: BLS12_381_G1Type, BLS12_381_G2Type prod = prod * bls12_381.pairing(g2.to_point(), g1.to_point()) res = BoolType.from_value(FQ12.one() == prod) stack.push(res) stdout.append(format_stdout(cls.prim, [points], [res])) return cls()
def _CoreVerify(cls, PK: BLSPubkey, message: bytes, signature: BLSSignature, DST: bytes) -> bool: try: # Inputs validation assert cls._is_valid_pubkey(PK) assert cls._is_valid_message(message) assert cls._is_valid_signature(signature) # Procedure assert cls.KeyValidate(PK) signature_point = signature_to_G2(signature) if not subgroup_check(signature_point): return False final_exponentiation = final_exponentiate( pairing( signature_point, G1, final_exponentiate=False, ) * pairing( hash_to_G2(message, DST, cls.xmd_hash_function), neg(pubkey_to_G1(PK)), final_exponentiate=False, )) return final_exponentiation == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def verify_multiple(pubkeys: Sequence[BLSPubkey], message_hashes: Sequence[Hash32], signature: BLSSignature, domain: int) -> bool: len_msgs = len(message_hashes) if len(pubkeys) != len_msgs: raise ValidationError( "len(pubkeys) (%s) should be equal to len(message_hashes) (%s)" % (len(pubkeys), len_msgs)) try: o = FQ12([1] + [0] * 11) for m_pubs in set(message_hashes): # aggregate the pubs group_pub = Z1 for i in range(len_msgs): if message_hashes[i] == m_pubs: group_pub = add(group_pub, pubkey_to_G1(pubkeys[i])) o *= pairing(hash_to_G2(m_pubs, domain), group_pub, final_exponentiate=False) o *= pairing(signature_to_G2(signature), neg(G1), final_exponentiate=False) final_exponentiation = final_exponentiate(o) return final_exponentiation == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def pairing(Q, P, final_exponentiate=True): assert is_on_curve(Q, b2) assert is_on_curve(P, b) if P[-1] == P[-1].__class__.zero() or Q[-1] == Q[-1].__class__.zero(): return FQ12.one() return miller_loop(twist(Q), cast_point_to_fq12(P), final_exponentiate=final_exponentiate)
def _CoreAggregateVerify(pairs: Sequence[Tuple[BLSPubkey, bytes]], signature: BLSSignature, DST: bytes) -> bool: try: signature_point = signature_to_G2(signature) accumulator = FQ12.one() for pk, message in pairs: pubkey_point = pubkey_to_G1(pk) message_point = hash_to_G2(message, DST) accumulator *= pairing(message_point, pubkey_point, final_exponentiate=False) accumulator *= pairing(signature_point, neg(G1), final_exponentiate=False) return final_exponentiate(accumulator) == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def pairing(Q: Optimized_Point3D[FQ2], P: Optimized_Point3D[FQ], final_exponentiate: bool = True) -> FQ12: assert is_on_curve(Q, b2) assert is_on_curve(P, b) if P[-1] == (P[-1].zero()) or Q[-1] == (Q[-1].zero()): return FQ12.one() return miller_loop(twist(Q), cast_point_to_fq12(P), final_exponentiate=final_exponentiate)
def miller_loop(Q: Optimized_Point3D[FQ12], P: Optimized_Point3D[FQ12], final_exponentiate: bool = True) -> FQ12: if Q is None or P is None: return FQ12.one() R = Q # type: Optimized_Point3D[FQ12] f_num, f_den = FQ12.one(), FQ12.one() # for i in range(log_ate_loop_count, -1, -1): for v in pseudo_binary_encoding[62::-1]: _n, _d = linefunc(R, R, P) f_num = f_num * f_num * _n f_den = f_den * f_den * _d R = double(R) if v == 1: _n, _d = linefunc(R, Q, P) f_num = f_num * _n f_den = f_den * _d R = add(R, Q) elif v == -1: nQ = neg(Q) _n, _d = linefunc(R, nQ, P) f_num = f_num * _n f_den = f_den * _d R = add(R, nQ) # assert R == multiply(Q, ate_loop_count) # Q1 = (Q[0] ** field_modulus, Q[1] ** field_modulus, Q[2] ** field_modulus) # assert is_on_curve(Q1, b12) # nQ2 = (Q1[0] ** field_modulus, -Q1[1] ** field_modulus, Q1[2] ** field_modulus) # assert is_on_curve(nQ2, b12) # _n1, _d1 = linefunc(R, Q1, P) # R = add(R, Q1) # _n2, _d2 = linefunc(R, nQ2, P) # f = f_num * _n1 * _n2 / (f_den * _d1 * _d2) f = f_num / f_den # R = add(R, nQ2) This line is in many specifications but it technically does nothing if final_exponentiate: return f**((field_modulus**12 - 1) // curve_order) else: return f
def verify(message_hash: Hash32, pubkey: BLSPubkey, signature: BLSSignature, domain: int) -> bool: try: final_exponentiation = final_exponentiate( pairing( signature_to_G2(signature), G1, final_exponentiate=False, ) * pairing( hash_to_G2(message_hash, domain), neg(pubkey_to_G1(pubkey)), final_exponentiate=False, )) return final_exponentiation == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def _CoreVerify(PK: BLSPubkey, message: bytes, signature: BLSSignature, DST: bytes) -> bool: try: signature_point = signature_to_G2(signature) final_exponentiation = final_exponentiate( pairing( signature_point, G1, final_exponentiate=False, ) * pairing( hash_to_G2(message, DST), neg(pubkey_to_G1(PK)), final_exponentiate=False, )) return final_exponentiation == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def _CoreVerify(cls, PK: BLSPubkey, message: bytes, signature: BLSSignature, DST: bytes) -> bool: try: assert BaseG2Ciphersuite.KeyValidate(PK) signature_point = signature_to_G2(signature) final_exponentiation = final_exponentiate( pairing( signature_point, G1, final_exponentiate=False, ) * pairing( hash_to_G2(message, DST, cls.xmd_hash_function), neg(pubkey_to_G1(PK)), final_exponentiate=False, )) return final_exponentiation == FQ12.one() except (ValidationError, ValueError, AssertionError): return False
def singlechecker(agg_pk, agg_sig, msg): final_exp = final_exponentiate( pairing(agg_sig, G1, final_exponentiate=False) * pairing( multiply(G2, hasher(msg)), neg(agg_pk), final_exponentiate=False)) isok = (final_exp == FQ12.one()) return isok
def pairing_check(points: Iterable[Tuple[G1Point, G2Point]]) -> bool: prod = FQ12.one() for g1_point, g2_point in points: prod = prod * bls12_381.pairing(g2_point, g1_point) return FQ12.one() == prod