Exemplo n.º 1
0
    def from_bytes(cls, data, curve: ec.EllipticCurve = None):
        """
        Returns a Point object from the given byte data on the curve provided.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        compressed_size = cls.expected_bytes_length(curve)
        # Check if compressed
        if data[0] in [2, 3]:
            if len(data) != compressed_size:
                raise ValueError("X coordinate too large for curve.")

            affine_x = CurveBN.from_bytes(data[1:], curve)
            type_y = data[0] - 2

            ec_point = openssl._get_new_EC_POINT(ec_group=affine_x.group)
            with backend._tmp_bn_ctx() as bn_ctx:
                res = backend._lib.EC_POINT_set_compressed_coordinates_GFp(
                    affine_x.group, ec_point, affine_x.bignum, type_y, bn_ctx)
                backend.openssl_assert(res == 1)
            return cls(ec_point, curve_nid, affine_x.group)

        # Handle uncompressed point
        elif data[0] == 4:
            coord_size = compressed_size - 1
            uncompressed_size = 1 + 2 * coord_size
            if len(data) != uncompressed_size:
                raise ValueError(
                    "uncompressed point does not have right size.")
            affine_x = int.from_bytes(data[1:coord_size + 1], 'big')
            affine_y = int.from_bytes(data[1 + coord_size:], 'big')

            return cls.from_affine((affine_x, affine_y), curve)
        else:
            raise ValueError("Invalid point serialization.")
Exemplo n.º 2
0
    def from_bytes(cls,
                   key_bytes: bytes,
                   params: UmbralParameters = None,
                   password: bytes = None,
                   _scrypt_cost: int = 20,
                   decoder: Callable = None):
        """
        Loads an Umbral private key from bytes.
        Optionally, allows a decoder function to be passed as a param to decode
        the data provided before converting to an Umbral key.
        Optionally, if a password is provided it will decrypt the key using
        nacl's Salsa20-Poly1305 and Scrypt key derivation.

        WARNING: RFC7914 recommends that you use a 2^20 cost value for sensitive
        files. Unless you changed this when you called `to_bytes`, you should
        not change it here. It is NOT recommended to change the `_scrypt_cost`
        value unless you know what you're doing.
        """
        if params is None:
            params = default_params()

        if decoder:
            key_bytes = decoder(key_bytes)

        if password:
            salt = key_bytes[-16:]
            key_bytes = key_bytes[:-16]

            key = Scrypt(salt=salt,
                         length=SecretBox.KEY_SIZE,
                         n=2**_scrypt_cost,
                         r=8,
                         p=1,
                         backend=default_backend()).derive(password)

            key_bytes = SecretBox(key).decrypt(key_bytes)

        bn_key = CurveBN.from_bytes(key_bytes, params.curve)
        return cls(bn_key, params)
Exemplo n.º 3
0
def test_point_operations():

    vector_file = os.path.join('vectors', 'vectors_point_operations.json')
    try:
        with open(vector_file) as f:
            vector_suite = json.load(f)
    except OSError:
        raise

    point1 = Point.from_bytes(
        bytes.fromhex(vector_suite['first Point operand']))
    point2 = Point.from_bytes(
        bytes.fromhex(vector_suite['second Point operand']))
    bn1 = CurveBN.from_bytes(bytes.fromhex(vector_suite['CurveBN operand']))

    expected = dict()
    for op_result in vector_suite['vectors']:
        expected[op_result['operation']] = bytes.fromhex(op_result['result'])

    test = [
        ('Addition', point1 + point2),
        ('Subtraction', point1 - point2),
        ('Multiplication', bn1 * point1),
        ('Inversion', -point1),
    ]

    for (operation, result) in test:
        assert result == Point.from_bytes(
            expected[operation]), 'Error in {}'.format(operation)

    test = [
        ('To_affine.X', point1.to_affine()[0]),
        ('To_affine.Y', point1.to_affine()[1]),
    ]

    for (operation, result) in test:
        assert result == int.from_bytes(expected[operation],
                                        'big'), 'Error in {}'.format(operation)
def test_point_curve_multiplication_regression():
    k256_point_bytes = b'\x03\xe0{\x1bQ\xbf@\x1f\x95\x8d\xe1\x17\xa7\xbe\x9e-G`T\xbf\xd7\x9e\xa7\x10\xc8uA\xc0z$\xc0\x92\x8a'
    k256_bn_bytes = b'4u\xd70-\xa0h\xdeG\xf0\x143\x06!\x91\x05{\xe4jC\n\xf1h\xed7a\xf8\x9d\xec^\x19\x8c'

    k256_point = Point.from_bytes(k256_point_bytes)
    k256_bn = CurveBN.from_bytes(k256_bn_bytes)

    product_with_star_operator = k256_point * k256_bn

    # Make sure we have instantiated a new, unequal point in the same curve and group
    assert isinstance(product_with_star_operator,
                      Point), "Point.__mul__ did not return a point instance"
    assert k256_point != product_with_star_operator
    assert k256_point.curve == product_with_star_operator.curve

    product_bytes = b'\x03\xc9\xda\xa2\x88\xe2\xa0+\xb1N\xb6\xe6\x1c\xa5(\xe6\xe0p\xf6\xf4\xa9\xfc\xb1\xfaUV\xd3\xb3\x0e4\x94\xbe\x12'
    product_point = Point.from_bytes(product_bytes)
    assert product_with_star_operator.to_bytes() == product_bytes
    assert product_point == product_with_star_operator

    # Repeating the operation, should return the same result.
    product_with_star_operator_again = k256_point * k256_bn
    assert product_with_star_operator == product_with_star_operator_again
Exemplo n.º 5
0
    def from_bytes(cls, data: bytes, curve: Optional[Curve] = None) -> 'Point':
        """
        Returns a Point object from the given byte data on the curve provided.
        """
        curve = curve if curve is not None else default_curve()

        compressed_size = cls.expected_bytes_length(curve)
        # Check if compressed
        if data[0] in [2, 3]:
            if len(data) != compressed_size:
                raise ValueError("X coordinate too large for curve.")

            affine_x = CurveBN.from_bytes(data[1:], curve)
            type_y = data[0] - 2

            ec_point = openssl._get_new_EC_POINT(curve)
            with backend._tmp_bn_ctx() as bn_ctx:
                res = backend._lib.EC_POINT_set_compressed_coordinates_GFp(
                    curve.ec_group, ec_point, affine_x.bignum, type_y, bn_ctx)
                backend.openssl_assert(res == 1)
            return cls(ec_point, curve)

        # Handle uncompressed point
        # TODO: Give better error messages
        elif data[0] == 4:
            coord_size = compressed_size - 1
            uncompressed_size = 1 + (2 * coord_size)
            if len(data) != uncompressed_size:
                raise ValueError(
                    "Uncompressed point does not have right size.")
            affine_x = int.from_bytes(data[1:coord_size + 1], 'big')
            affine_y = int.from_bytes(data[1 + coord_size:], 'big')

            return cls.from_affine((affine_x, affine_y), curve)
        else:
            raise ValueError("Invalid point serialization.")
Exemplo n.º 6
0
def test_bn_roundtrip(bn):
    assert(bn == CurveBN.from_bytes(bn.to_bytes()))