def get_epoch_signature(state: BeaconState, block: BeaconBlock, privkey: int) -> BLSSignature: domain = get_domain(state, DOMAIN_RANDAO, compute_epoch_at_slot(block.slot)) signing_root = compute_signing_root(compute_epoch_at_slot(block.slot), domain) return bls.Sign(privkey, signing_root)
def case01_sign(): # Valid cases for privkey in PRIVKEYS: for message in MESSAGES: sig = bls.Sign(privkey, message) assert sig == milagro_bls.Sign( to_bytes(privkey), message) # double-check with milagro identifier = f'{int_to_hex(privkey)}_{encode_hex(message)}' yield f'sign_case_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'privkey': int_to_hex(privkey), 'message': encode_hex(message), }, 'output': encode_hex(sig) } # Edge case: privkey == 0 expect_exception(bls.Sign, ZERO_PRIVKEY, message) expect_exception(milagro_bls.Sign, ZERO_PRIVKEY_BYTES, message) yield f'sign_case_zero_privkey', { 'input': { 'privkey': encode_hex(ZERO_PRIVKEY_BYTES), 'message': encode_hex(message), }, 'output': None }
def get_attestation_signature(state: BeaconState, attestation_data: AttestationData, privkey: int) -> BLSSignature: domain = get_domain(state, DOMAIN_BEACON_ATTESTER, attestation_data.target.epoch) signing_root = compute_signing_root(attestation_data, domain) return bls.Sign(privkey, signing_root)
def test_verify_multiple_aggregate_signatures(SKs, messages): signature_set = [(bls.Aggregate([bls.Sign(sk, msg) for sk in SKs]), bls._AggregatePKs([bls.SkToPk(sk) for sk in SKs]), msg) for msg in messages] assert bls.VerifyMultipleAggregateSignatures(signature_set) bad_signature_set = [(aggsig, aggkey, msg + b'\xbadd') for aggsig, aggkey, msg in signature_set] assert not bls.VerifyMultipleAggregateSignatures(bad_signature_set)
def test_weird_cases(): Z1_PUBKEY = b'\xc0' + b'\x00' * 47 Z2_SIGNATURE = b'\xc0' + b'\x00' * 95 assert not bls.AggregateVerify([], [], Z2_SIGNATURE) assert bls.Aggregate([]) == Z2_SIGNATURE with pytest.raises(ValueError): bls.Sign(to_bytes(0), b'abcd') assert not bls.Verify(Z1_PUBKEY, b'abcd', Z2_SIGNATURE) assert not bls.FastAggregateVerify([Z1_PUBKEY], b'abcd', Z2_SIGNATURE)
def test_single_verify(benchmark, pubkeys, privkeys, messages): sig = bls.Sign(privkeys[0], messages[0]) args = (sig, pubkeys, messages) result = benchmark.pedantic(verify_single_sig, args=args, rounds=100, iterations=10) assert result == True
def test_verifying_aggregation_of_128_signatures_with_two_distinct_messages( benchmark, privkeys, pubkeys, messages): sigs = [bls.Sign(key, messages[i % 2]) for i, key in enumerate(privkeys)] agg_sig = bls.Aggregate(sigs) args = (agg_sig, pubkeys, messages) result = benchmark.pedantic(verifying_two_distinct_messages, args=args, rounds=10, iterations=10) assert result == True
def test_verifying_aggregate_of_128_signatures(benchmark, privkeys, pubkeys, messages): message = messages[0] sigs = [bls.Sign(key, message) for key in privkeys] agg_sig = bls.Aggregate(sigs) args = (agg_sig, pubkeys, message) result = benchmark.pedantic(verifying_one_message, args=args, rounds=10, iterations=10) assert result == True
def case02_verify(): for i, privkey in enumerate(PRIVKEYS): for message in MESSAGES: # Valid signature signature = bls.Sign(privkey, message) pubkey = bls.SkToPk(privkey) assert milagro_bls.SkToPk(to_bytes(privkey)) == pubkey assert milagro_bls.Sign(to_bytes(privkey), message) == signature identifier = f'{encode_hex(pubkey)}_{encode_hex(message)}' assert bls.Verify(pubkey, message, signature) assert milagro_bls.Verify(pubkey, message, signature) yield f'verify_valid_case_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'pubkey': encode_hex(pubkey), 'message': encode_hex(message), 'signature': encode_hex(signature), }, 'output': True, } # Invalid signatures -- wrong pubkey wrong_pubkey = bls.SkToPk(PRIVKEYS[(i + 1) % len(PRIVKEYS)]) identifier = f'{encode_hex(wrong_pubkey)}_{encode_hex(message)}' assert not bls.Verify(wrong_pubkey, message, signature) assert not milagro_bls.Verify(wrong_pubkey, message, signature) yield f'verify_wrong_pubkey_case_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'pubkey': encode_hex(wrong_pubkey), 'message': encode_hex(message), 'signature': encode_hex(signature), }, 'output': False, } # Invalid signature -- tampered with signature tampered_signature = signature[:-4] + b'\xFF\xFF\xFF\xFF' identifier = f'{encode_hex(pubkey)}_{encode_hex(message)}' assert not bls.Verify(pubkey, message, tampered_signature) assert not milagro_bls.Verify(pubkey, message, tampered_signature) yield f'verify_tampered_signature_case_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'pubkey': encode_hex(pubkey), 'message': encode_hex(message), 'signature': encode_hex(tampered_signature), }, 'output': False, } # Invalid pubkey and signature with the point at infinity assert not bls.Verify(Z1_PUBKEY, SAMPLE_MESSAGE, Z2_SIGNATURE) assert not milagro_bls.Verify(Z1_PUBKEY, SAMPLE_MESSAGE, Z2_SIGNATURE) yield f'verify_infinity_pubkey_and_infinity_signature', { 'input': { 'pubkey': encode_hex(Z1_PUBKEY), 'message': encode_hex(SAMPLE_MESSAGE), 'signature': encode_hex(Z2_SIGNATURE), }, 'output': False, }
def get_block_signature(state: BeaconState, block: BeaconBlock, privkey: int) -> BLSSignature: domain = get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_at_slot(block.slot)) signing_root = compute_signing_root(block, domain) return bls.Sign(privkey, signing_root)
def test_fast_aggregate_verify(SKs, message): PKs = [bls.SkToPk(sk) for sk in SKs] signatures = [bls.Sign(sk, message) for sk in SKs] aggregate_signature = bls.Aggregate(signatures) assert bls.FastAggregateVerify(PKs, message, aggregate_signature)
def test_sign_verify(privkey_int): privkey = to_bytes(privkey_int) msg = str(privkey).encode('utf-8') pub = bls.SkToPk(privkey) sig = bls.Sign(privkey, msg) assert bls.Verify(pub, msg, sig)
def test_aggregate_verify(SKs, messages, success): PKs = [bls.SkToPk(SK) for SK in SKs] messages = [msg.to_bytes(32, "big") for msg in messages] signatures = [bls.Sign(SK, msg) for SK, msg in zip(SKs, messages)] aggregate_signature = bls.Aggregate(signatures) assert bls.AggregateVerify(PKs, messages, aggregate_signature) == success