Exemple #1
0
    def from_bytes(cls, data: bytes, curve: Optional[Curve] = None) -> 'KFrag':
        """
        Instantiate a KFrag object from the serialized data.
        """
        curve = curve if curve is not None else default_curve()

        bn_size = CurveBN.expected_bytes_length(curve)
        point_size = Point.expected_bytes_length(curve)
        signature_size = Signature.expected_bytes_length(curve)
        arguments = {'curve': curve}

        splitter = BytestringSplitter(
            bn_size,  # id
            (CurveBN, bn_size, arguments),  # bn_key
            (Point, point_size, arguments),  # point_commitment
            (Point, point_size, arguments),  # point_precursor
            1,  # keys_in_signature
            (Signature, signature_size, arguments),  # signature_for_proxy
            (Signature, signature_size, arguments),  # signature_for_bob
        )
        components = splitter(data)

        return cls(identifier=components[0],
                   bn_key=components[1],
                   point_commitment=components[2],
                   point_precursor=components[3],
                   keys_in_signature=components[4],
                   signature_for_proxy=components[5],
                   signature_for_bob=components[6])
Exemple #2
0
def get_signature_recovery_value(message: bytes,
                                 signature: Union[bytes, Signature],
                                 public_key: Union[bytes, UmbralPublicKey],
                                 is_prehashed: bool = False) -> bytes:
    """
    Obtains the recovery value of a standard ECDSA signature.

    :param message: Signed message
    :param signature: The signature from which the pubkey is recovered
    :param public_key: The public key for verifying the signature
    :param is_prehashed: True if the message is already pre-hashed. Default is False, and message will be hashed with SHA256
    :return: The compressed byte-serialized representation of the recovered public key
    """

    signature = bytes(signature)
    ecdsa_signature_size = Signature.expected_bytes_length()
    if len(signature) != ecdsa_signature_size:
        raise ValueError(
            f"The signature size should be {ecdsa_signature_size} B.")

    kwargs = dict(hasher=None) if is_prehashed else {}
    for v in (0, 1):
        v_byte = bytes([v])
        recovered_pubkey = PublicKey.from_signature_and_message(
            serialized_sig=signature + v_byte, message=message, **kwargs)
        if bytes(public_key) == recovered_pubkey.format(compressed=True):
            return v_byte
    else:
        raise ValueError(
            "Signature recovery failed. "
            "Either the message, the signature or the public key is not correct"
        )
Exemple #3
0
def recover_pubkey_from_signature(message: bytes,
                                  signature: Union[bytes, Signature],
                                  v_value_to_try: int,
                                  is_prehashed: bool = False) -> bytes:
    """
    Recovers a serialized, compressed public key from a signature.
    It allows to specify a potential v value, in which case it assumes the signature
    has the traditional (r,s) raw format. If a v value is not present, it assumes
    the signature has the recoverable format (r, s, v).

    :param message: Signed message
    :param signature: The signature from which the pubkey is recovered
    :param v_value_to_try: A potential v value to try
    :param is_prehashed: True if the message is already pre-hashed. Default is False, and message will be hashed with SHA256
    :return: The compressed byte-serialized representation of the recovered public key
    """

    signature = bytes(signature)
    expected_signature_size = Signature.expected_bytes_length()
    if not len(signature) == expected_signature_size:
        raise ValueError(
            f"The signature size should be {expected_signature_size} B.")

    if v_value_to_try in (0, 1, 27, 28):
        if v_value_to_try >= 27:
            v_value_to_try -= 27
        signature = signature + v_value_to_try.to_bytes(1, 'big')
    else:
        raise ValueError("Wrong v value. It should be 0, 1, 27 or 28.")

    kwargs = dict(hasher=None) if is_prehashed else {}
    pubkey = PublicKey.from_signature_and_message(serialized_sig=signature,
                                                  message=message,
                                                  **kwargs)
    return pubkey.format(compressed=True)
Exemple #4
0
def test_sign_and_verify(execution_number):
    privkey = UmbralPrivateKey.gen_key()
    pubkey = privkey.get_pubkey()
    signer = Signer(private_key=privkey)
    message = b"peace at dawn"
    signature = signer(message=message)

    # Basic signature verification
    assert signature.verify(message, pubkey)
    assert not signature.verify(b"another message", pubkey)
    another_pubkey = UmbralPrivateKey.gen_key().pubkey
    assert not signature.verify(message, another_pubkey)

    # Signature serialization
    sig_bytes = bytes(signature)
    assert len(sig_bytes) == Signature.expected_bytes_length()
    restored_signature = Signature.from_bytes(sig_bytes)
    assert restored_signature == signature
    assert restored_signature.verify(message, pubkey)
Exemple #5
0
    def from_bytes(cls, data: bytes, curve: ec.EllipticCurve = None):
        """
        Instantiate a KFrag object from the serialized data.
        """
        curve = curve if curve is not None else default_curve()

        bn_size = CurveBN.expected_bytes_length(curve)
        point_size = Point.expected_bytes_length(curve)

        splitter = BytestringSplitter(
            bn_size,  # id
            (CurveBN, bn_size),  # bn_key
            (Point, point_size),  # point_noninteractive
            (Point, point_size),  # point_commitment
            (Point, point_size),  # point_xcoord
            (Signature, Signature.expected_bytes_length(curve)))
        components = splitter(data)

        return cls(*components)
Exemple #6
0
    def from_bytes(cls, data: bytes, curve: Optional[Curve] = None) -> 'CorrectnessProof':
        """
        Instantiate CorrectnessProof from serialized data.
        """
        curve = curve if curve is not None else default_curve()
        bn_size = CurveBN.expected_bytes_length(curve)
        point_size = Point.expected_bytes_length(curve)
        arguments = {'curve': curve}
        splitter = BytestringSplitter(
            (Point, point_size, arguments),  # point_e2
            (Point, point_size, arguments),  # point_v2
            (Point, point_size, arguments),  # point_kfrag_commitment
            (Point, point_size, arguments),  # point_kfrag_pok
            (CurveBN, bn_size, arguments),  # bn_sig
            (Signature, Signature.expected_bytes_length(curve), arguments),  # kfrag_signature
        )
        components = splitter(data, return_remainder=True)
        components.append(components.pop() or None)

        return cls(*components)
Exemple #7
0
def recover_pubkey_from_signature(prehashed_message,
                                  signature,
                                  v_value_to_try=None) -> bytes:
    """
    Recovers a serialized, compressed public key from a signature.
    It allows to specify a potential v value, in which case it assumes the signature
    has the traditional (r,s) raw format. If a v value is not present, it assumes
    the signature has the recoverable format (r, s, v).

    :param prehashed_message: Prehashed message
    :param signature: The signature from which the pubkey is recovered
    :param v_value_to_try: A potential v value to try
    :return: The compressed byte-serialized representation of the recovered public key
    """

    signature = bytes(signature)
    ecdsa_signature_size = Signature.expected_bytes_length()

    if not v_value_to_try:
        expected_signature_size = ecdsa_signature_size + 1
        if not len(signature) == expected_signature_size:
            raise ValueError(
                f"When not passing a v value, "
                f"the signature size should be {expected_signature_size} B.")
    elif v_value_to_try in (0, 1, 27, 28):
        expected_signature_size = ecdsa_signature_size
        if not len(signature) == expected_signature_size:
            raise ValueError(
                f"When passing a v value, "
                f"the signature size should be {expected_signature_size} B.")
        if v_value_to_try >= 27:
            v_value_to_try -= 27
        signature = signature + v_value_to_try.to_bytes(1, 'big')
    else:
        raise ValueError("Wrong v value. It should be 0, 1, 27 or 28.")

    pubkey = PublicKey.from_signature_and_message(serialized_sig=signature,
                                                  message=prehashed_message,
                                                  hasher=None)
    return pubkey.format(compressed=True)