Exemplo n.º 1
0
    def from_bytes(cls, data: bytes, curve: ec.EllipticCurve = None):
        """
        Instantiate CorrectnessProof from serialized data.
        """
        curve = curve if curve is not None else default_curve()
        key_size = get_curve_keysize_bytes(curve)
        data = BytesIO(data)

        # CurveBNs are the keysize in bytes, Points are compressed and the
        # keysize + 1 bytes long.
        e2 = Point.from_bytes(data.read(key_size + 1), curve)
        v2 = Point.from_bytes(data.read(key_size + 1), curve)
        kfrag_commitment = Point.from_bytes(data.read(key_size + 1), curve)
        kfrag_pok = Point.from_bytes(data.read(key_size + 1), curve)
        kfrag_sig1 = CurveBN.from_bytes(data.read(key_size), curve)
        kfrag_sig2 = CurveBN.from_bytes(data.read(key_size), curve)
        sig = CurveBN.from_bytes(data.read(key_size), curve)

        metadata = data.read() or None

        return cls(e2,
                   v2,
                   kfrag_commitment,
                   kfrag_pok,
                   kfrag_sig1,
                   kfrag_sig2,
                   sig,
                   metadata=metadata)
Exemplo n.º 2
0
 def expected_bytes_length(cls, curve: Optional[Curve] = None) -> int:
     """
     Returns the size (in bytes) of a compressed Point given a curve.
     If no curve is provided, it uses the default curve.
     """
     curve = curve if curve is not None else default_curve()
     return get_field_order_size_in_bytes(curve) + 1
Exemplo n.º 3
0
    def from_affine(cls, coords, curve: ec.EllipticCurve = None):
        """
        Returns a Point object from the given affine coordinates in a tuple in
        the format of (x, y) and a given curve.
        """
        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

        affine_x, affine_y = coords
        if type(affine_x) == int:
            affine_x = openssl._int_to_bn(affine_x)

        if type(affine_y) == int:
            affine_y = openssl._int_to_bn(affine_y)

        group = openssl._get_ec_group_by_curve_nid(curve_nid)
        ec_point = openssl._get_EC_POINT_via_affine(affine_x,
                                                    affine_y,
                                                    ec_group=group)

        return cls(ec_point, curve_nid, group)
Exemplo n.º 4
0
 def get_generator_from_curve(cls,
                              curve: Optional[Curve] = None) -> 'Point':
     """
     Returns the generator Point from the given curve as a Point object.
     """
     curve = curve if curve is not None else default_curve()
     return cls(curve.generator, curve)
Exemplo n.º 5
0
 def expected_bytes_length(cls, curve: ec.EllipticCurve = None):
     """
     Returns the size (in bytes) of a CurveBN given the curve.
     If no curve is provided, it uses the default.
     """
     curve = curve if curve is not None else default_curve()
     return get_curve_keysize_bytes(curve)
Exemplo n.º 6
0
 def get_size(cls, curve: ec.EllipticCurve=None):
     """
     Returns the size (in bytes) of a compressed Point given a curve.
     If no curve is provided, it uses the default curve.
     """
     curve = curve if curve is not None else default_curve()
     return get_curve_keysize_bytes(curve) + 1
Exemplo n.º 7
0
def test_simple_api(N, M, curve=default_curve()):
    """Manually injects umbralparameters for multi-curve testing."""

    params = UmbralParameters(curve=curve)

    priv_key_alice = keys.UmbralPrivateKey.gen_key(params=params)
    pub_key_alice = priv_key_alice.get_pubkey()

    priv_key_bob = keys.UmbralPrivateKey.gen_key(params=params)
    pub_key_bob = priv_key_bob.get_pubkey()

    plain_data = b'peace at dawn'
    ciphertext, capsule = pre.encrypt(pub_key_alice, plain_data, params=params)

    cleartext = pre.decrypt(ciphertext, capsule, priv_key_alice, params=params)
    assert cleartext == plain_data

    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N, params=params)
    for kfrag in kfrags:
        cfrag = pre.reencrypt(kfrag, capsule, params=params)
        capsule.attach_cfrag(cfrag)

    reenc_cleartext = pre.decrypt(ciphertext,
                                  capsule,
                                  priv_key_bob,
                                  pub_key_alice,
                                  params=params)
    assert reenc_cleartext == plain_data
Exemplo n.º 8
0
    def gen_rand(cls, curve: ec.EllipticCurve = None):
        """
        Returns a BigNum object with a cryptographically secure BigNum based
        on the given curve.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        order = backend._lib.BN_new()
        backend.openssl_assert(order != backend._ffi.NULL)
        order = backend._ffi.gc(order, backend._lib.BN_clear_free)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
            backend.openssl_assert(res == 1)

        new_rand_bn = backend._lib.BN_new()
        backend.openssl_assert(new_rand_bn != backend._ffi.NULL)
        new_rand_bn = backend._ffi.gc(new_rand_bn, backend._lib.BN_clear_free)

        rand_res = backend._lib.BN_rand_range(new_rand_bn, order)
        backend.openssl_assert(rand_res == 1)

        return cls(new_rand_bn, curve_nid, group, order)
Exemplo n.º 9
0
    def gen_rand(cls, curve: ec.EllipticCurve = None):
        """
        Returns a Point object with a cryptographically secure EC_POINT based
        on the provided curve.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        generator = backend._lib.EC_GROUP_get0_generator(group)
        backend.openssl_assert(generator != backend._ffi.NULL)

        rand_point = backend._lib.EC_POINT_new(group)
        backend.openssl_assert(rand_point != backend._ffi.NULL)
        rand_point = backend._ffi.gc(rand_point,
                                     backend._lib.EC_POINT_clear_free)

        rand_bn = BigNum.gen_rand(curve).bignum

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_POINT_mul(group, rand_point,
                                            backend._ffi.NULL, generator,
                                            rand_bn, bn_ctx)
            backend.openssl_assert(res == 1)

        return Point(rand_point, curve_nid, group)
Exemplo n.º 10
0
    def gen_rand(cls, curve: ec.EllipticCurve = None):
        """
        Returns a BigNum object with a cryptographically secure BigNum based
        on the given curve.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        order = backend._lib.BN_new()
        backend.openssl_assert(order != backend._ffi.NULL)
        order = backend._ffi.gc(order, backend._lib.BN_free)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
            backend.openssl_assert(res == 1)

        order_int = backend._bn_to_int(order)

        # Generate random number on curve
        key_size = get_curve_keysize_bytes(curve)
        rand_num = int.from_bytes(os.urandom(key_size), 'big')
        while rand_num >= order_int or rand_num <= 0:
            rand_num = int.from_bytes(os.urandom(key_size), 'big')

        new_rand_bn = backend._int_to_bn(rand_num)
        new_rand_bn = backend._ffi.gc(new_rand_bn, backend._lib.BN_free)

        return cls(new_rand_bn, curve_nid, group, order)
Exemplo n.º 11
0
def test_cfrag_serialization_no_proof_no_metadata(alices_keys, bobs_keys):
    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()

    _receiving_privkey, receiving_pubkey = bobs_keys
    signer_alice = Signer(signing_privkey)

    _unused_key, capsule = pre._encapsulate(delegating_pubkey.point_key)
    kfrags = pre.split_rekey(delegating_privkey, signer_alice,
                             receiving_pubkey, 1, 2)

    cfrag = pre.reencrypt(kfrags[0], capsule, provide_proof=False)
    cfrag_bytes = cfrag.to_bytes()

    proof = cfrag.proof
    assert proof is None

    curve = default_curve()
    assert len(cfrag_bytes) == CapsuleFrag.expected_bytes_length(curve)

    new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
    assert new_cfrag._point_e1 == cfrag._point_e1
    assert new_cfrag._point_v1 == cfrag._point_v1
    assert new_cfrag._kfrag_id == cfrag._kfrag_id
    assert new_cfrag._point_noninteractive == cfrag._point_noninteractive

    new_proof = new_cfrag.proof
    assert new_proof is None
Exemplo n.º 12
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])
Exemplo n.º 13
0
def test_simple_api(N, M, curve=default_curve()):
    """Manually injects umbralparameters for multi-curve testing."""
    params = UmbralParameters(curve=curve)

    delegating_privkey = UmbralPrivateKey.gen_key(params=params)
    delegating_pubkey = delegating_privkey.get_pubkey()

    signing_privkey = UmbralPrivateKey.gen_key(params=params)
    signing_pubkey = signing_privkey.get_pubkey()
    signer = Signer(signing_privkey)

    receiving_privkey = UmbralPrivateKey.gen_key(params=params)
    receiving_pubkey = receiving_privkey.get_pubkey()

    plain_data = b'peace at dawn'
    ciphertext, capsule = pre.encrypt(delegating_pubkey, plain_data)

    cleartext = pre.decrypt(ciphertext, capsule, delegating_privkey)
    assert cleartext == plain_data

    capsule.set_correctness_keys(delegating=delegating_pubkey,
                                 receiving=receiving_pubkey,
                                 verifying=signing_pubkey)

    kfrags = pre.split_rekey(delegating_privkey, signer, receiving_pubkey, M, N)

    for kfrag in kfrags:
        cfrag = pre.reencrypt(kfrag, capsule)
        capsule.attach_cfrag(cfrag)

    reenc_cleartext = pre.decrypt(ciphertext, capsule, receiving_privkey)
    assert reenc_cleartext == plain_data
Exemplo n.º 14
0
    def from_int(cls, num, curve: ec.EllipticCurve = None):
        """
        Returns a BigNum object from a given integer on a curve.
        """
        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

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        order = backend._lib.BN_new()
        backend.openssl_assert(order != backend._ffi.NULL)
        order = backend._ffi.gc(order, backend._lib.BN_clear_free)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
            backend.openssl_assert(res == 1)

        order_int = backend._bn_to_int(order)
        if num <= 0 or num >= order_int:
            # TODO: Handle this better maybe? Ask David.
            raise ValueError("Integer provided is not on the given curve.")

        bignum = backend._int_to_bn(num)
        bignum = backend._ffi.gc(bignum, backend._lib.BN_clear_free)

        return cls(bignum, curve_nid, group, order)
Exemplo n.º 15
0
    def from_affine(cls, coords, curve: ec.EllipticCurve = None):
        """
        Returns a Point object from the given affine coordinates in a tuple in
        the format of (x, y) and a given curve.
        """
        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

        affine_x, affine_y = coords
        if type(affine_x) == int:
            affine_x = backend._int_to_bn(affine_x)
            affine_x = backend._ffi.gc(affine_x, backend._lib.BN_clear_free)

        if type(affine_y) == int:
            affine_y = backend._int_to_bn(affine_y)
            affine_y = backend._ffi.gc(affine_y, backend._lib.BN_clear_free)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        ec_point = backend._lib.EC_POINT_new(group)
        backend.openssl_assert(ec_point != backend._ffi.NULL)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_POINT_set_affine_coordinates_GFp(
                group, ec_point, affine_x, affine_y, bn_ctx)
            backend.openssl_assert(res == 1)

        return Point(ec_point, curve_nid, group)
Exemplo n.º 16
0
 def expected_bytes_length(cls, curve: Optional[Curve] = None) -> int:
     """
     Returns the size (in bytes) of a CurveBN given the curve.
     If no curve is provided, it uses the default.
     """
     curve = curve if curve is not None else default_curve()
     return curve.field_order_size_in_bytes
Exemplo n.º 17
0
    def from_bytes(cls, capsule_bytes: bytes, curve: ec.EllipticCurve = None):
        """
        Instantiates a Capsule object from the serialized data.
        """
        curve = curve if curve is not None else default_curve()
        key_size = get_curve_keysize_bytes(curve)
        capsule_buff = BytesIO(capsule_bytes)

        # CurveBNs are the keysize in bytes, Points are compressed and the
        # keysize + 1 bytes long.
        if len(capsule_bytes) == 197:
            e = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
            v = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
            sig = CurveBN.from_bytes(capsule_buff.read(key_size), curve)
            e_prime = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
            v_prime = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
            ni = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
        else:
            e = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
            v = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
            sig = CurveBN.from_bytes(capsule_buff.read(key_size), curve)
            e_prime = v_prime = ni = None

        return cls(point_e=e, point_v=v, bn_sig=sig,
                   point_e_prime=e_prime, point_v_prime=v_prime, 
                   point_noninteractive=ni)
Exemplo n.º 18
0
    def from_bytes(cls, capsule_bytes: bytes, curve: ec.EllipticCurve = None):
        """
        Instantiates a Capsule 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)

        if len(capsule_bytes) == cls.expected_bytes_length(curve,
                                                           activated=True):
            splitter = BytestringSplitter(
                (Point, point_size),  # point_e
                (Point, point_size),  # point_v
                (CurveBN, bn_size),  # bn_sig
                (Point, point_size),  # point_e_prime
                (Point, point_size),  # point_v_prime
                (Point, point_size)  # point_noninteractive
            )
        else:
            splitter = BytestringSplitter(
                (Point, point_size),  # point_e
                (Point, point_size),  # point_v
                (CurveBN, bn_size)  # bn_sig
            )

        components = splitter(capsule_bytes)
        return cls(*components)
Exemplo n.º 19
0
    def from_bytes(cls,
                   data: bytes,
                   curve: Optional[Curve] = None) -> 'CapsuleFrag':
        """
        Instantiates a CapsuleFrag 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)
        arguments = {'curve': curve}

        splitter = BytestringSplitter(
            (Point, point_size, arguments),  # point_e1
            (Point, point_size, arguments),  # point_v1
            bn_size,  # kfrag_id
            (Point, point_size, arguments),  # point_precursor
        )
        components = splitter(data, return_remainder=True)

        proof = components.pop() or None
        components.append(
            CorrectnessProof.from_bytes(proof, curve) if proof else None)

        return cls(*components)
Exemplo n.º 20
0
 def expected_bytes_length(cls, curve: Optional[Curve] = None) -> int:
     """
     Returns the size (in bytes) of a CurveBN given the curve,
     which comes from the size of the order of the generated group.
     If no curve is provided, it uses the default.
     """
     curve = curve if curve is not None else default_curve()
     return curve.group_order_size_in_bytes
Exemplo n.º 21
0
    def from_bytes(cls, data, curve: ec.EllipticCurve = None):
        """
        Returns a BigNum object from the given byte data that's within the size
        of the provided curve's order.
        """
        curve = curve if curve is not None else default_curve()
        num = int.from_bytes(data, 'big')

        return BigNum.from_int(num, curve)
Exemplo n.º 22
0
 def from_int(cls, num: int, curve: Optional[Curve] = None) -> 'CurveBN':
     """
     Returns a CurveBN object from a given integer on a curve.
     By default, the underlying OpenSSL BIGNUM has BN_FLG_CONSTTIME set for
     constant time operations.
     """
     curve = curve if curve is not None else default_curve()
     conv_bn = openssl._int_to_bn(num, curve)
     return cls(conv_bn, curve)
Exemplo n.º 23
0
    def get_size(cls, curve: ec.EllipticCurve = None):
        """
        Returns the size (in bytes) of a KFrag given the curve.
        If no curve is provided, it will use the default curve.
        """
        curve = curve if curve is not None else default_curve()
        bn_size = CurveBN.get_size(curve)
        point_size = Point.get_size(curve)

        return (bn_size * 4) + (point_size * 2)
Exemplo n.º 24
0
    def expected_bytes_length(cls, curve: Optional[Curve] = None) -> int:
        """
        Returns the size (in bytes) of a Capsule given the curve.
        If no curve is provided, it will use the default curve.
        """
        curve = curve if curve is not None else default_curve()
        bn_size = CurveBN.expected_bytes_length(curve)
        point_size = Point.expected_bytes_length(curve)

        return (bn_size * 1) + (point_size * 2)
Exemplo n.º 25
0
    def get_size(cls, curve: ec.EllipticCurve = None):
        """
        Returns the size (in bytes) of a CorrectnessProof without the metadata.
        If no curve is given, it will use the default curve.
        """
        curve = curve if curve is not None else default_curve()
        bn_size = CurveBN.get_size(curve=curve)
        point_size = Point.get_size(curve=curve)

        return (bn_size * 3) + (point_size * 4)
Exemplo n.º 26
0
 def from_bytes(cls, data: bytes, curve: Curve = None) -> 'CurveBN':
     """
     Returns a CurveBN object from the given byte data that's within the size
     of the provided curve's order.
     By default, the underlying OpenSSL BIGNUM has BN_FLG_CONSTTIME set for
     constant time operations.
     """
     curve = curve if curve is not None else default_curve()
     num = int.from_bytes(data, 'big')
     return cls.from_int(num, curve)
Exemplo n.º 27
0
    def expected_bytes_length(cls, curve: Optional[Curve] = None):
        """
        Returns the size (in bytes) of a CorrectnessProof without the metadata.
        If no curve is given, it will use the default curve.
        """
        curve = curve if curve is not None else default_curve()
        bn_size = CurveBN.expected_bytes_length(curve=curve)
        point_size = Point.expected_bytes_length(curve=curve)

        return (bn_size * 3) + (point_size * 4)
Exemplo n.º 28
0
    def get_size(cls, curve: ec.EllipticCurve = None):
        """
        Returns the size (in bytes) of a CapsuleFrag given the curve without
        the CorrectnessProof.
        If no curve is provided, it will use the default curve.
        """
        curve = curve if curve is not None else default_curve()
        bn_size = CurveBN.get_size(curve)
        point_size = Point.get_size(curve)

        return (bn_size * 1) + (point_size * 3)
Exemplo n.º 29
0
    def expected_bytes_length(cls,
                              curve: Optional[EllipticCurve] = None) -> int:
        """
        Returns the size (in bytes) of a CapsuleFrag given the curve without
        the CorrectnessProof.
        If no curve is provided, it will use the default curve.
        """
        curve = curve if curve is not None else default_curve()
        bn_size = CurveBN.expected_bytes_length(curve)
        point_size = Point.expected_bytes_length(curve)

        return (bn_size * 1) + (point_size * 4)
Exemplo n.º 30
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()

        point = openssl._get_new_EC_POINT(curve)
        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_POINT_oct2point(curve.ec_group, point, data,
                                                  len(data), bn_ctx)
            backend.openssl_assert(res == 1)

        return cls(point, curve)