コード例 #1
0
def _decapsulate_reencrypted(receiving_privkey: UmbralPrivateKey,
                             capsule: Capsule,
                             key_length: int = DEM_KEYSIZE) -> bytes:
    """Derive the same symmetric key"""
    params = capsule._umbral_params

    pub_key = receiving_privkey.get_pubkey().point_key
    priv_key = receiving_privkey.bn_key

    ni = capsule._point_noninteractive
    d = CurveBN.hash(ni, pub_key, priv_key * ni, params=params)

    e_prime = capsule._point_e_prime
    v_prime = capsule._point_v_prime

    shared_key = d * (e_prime + v_prime)

    key = kdf(shared_key, key_length)

    e = capsule._point_e
    v = capsule._point_v
    s = capsule._bn_sig
    h = CurveBN.hash(e, v, params=params)
    inv_d = ~d
    orig_pub_key = capsule.get_correctness_keys()['delegating'].point_key

    if not (s * inv_d) * orig_pub_key == (h * e_prime) + v_prime:
        raise GenericUmbralError()
    return key
コード例 #2
0
def split_rekey(priv_a: Union[UmbralPrivateKey, CurveBN],
                pubkey_b_point: Union[UmbralPublicKey, Point],
                threshold: int, N: int,
                params: UmbralParameters=None) -> List[KFrag]:
    """
    Creates a re-encryption key from Alice to Bob and splits it in KFrags,
    using Shamir's Secret Sharing. Requires a threshold number of KFrags 
    out of N to guarantee correctness of re-encryption.

    Returns a list of KFrags.
    """
    params = params if params is not None else default_params()

    if isinstance(priv_a, UmbralPrivateKey):
        priv_a = priv_a.bn_key

    if isinstance(pubkey_b_point, UmbralPublicKey):
        pubkey_b_point = pubkey_b_point.point_key

    g = params.g
    pubkey_a_point = priv_a * g

    x = CurveBN.gen_rand(params.curve)
    xcomp = x * g
    d = CurveBN.hash(xcomp, pubkey_b_point, pubkey_b_point * x, params=params)

    coeffs = [priv_a * (~d)]
    coeffs += [CurveBN.gen_rand(params.curve) for _ in range(threshold - 1)]

    u = params.u

    g_ab = priv_a * pubkey_b_point

    blake2b = hashes.Hash(hashes.BLAKE2b(64), backend=backend)
    blake2b.update(pubkey_a_point.to_bytes())
    blake2b.update(pubkey_b_point.to_bytes())
    blake2b.update(g_ab.to_bytes())
    hashed_dh_tuple = blake2b.finalize()

    kfrags = []
    for _ in range(N):
        id_kfrag = CurveBN.gen_rand(params.curve)

        share_x = CurveBN.hash(id_kfrag, hashed_dh_tuple, params=params)

        rk = poly_eval(coeffs, share_x)

        u1 = rk * u
        y = CurveBN.gen_rand(params.curve)

        signature_input = [y * g, id_kfrag, pubkey_a_point, pubkey_b_point, u1, xcomp]
        z1 = CurveBN.hash(*signature_input, params=params)
        z2 = y - priv_a * z1

        kfrag = KFrag(bn_id=id_kfrag, bn_key=rk, 
                      point_noninteractive=xcomp, point_commitment=u1, 
                      bn_sig1=z1, bn_sig2=z2)
        kfrags.append(kfrag)

    return kfrags
コード例 #3
0
def _decapsulate_reencrypted(pub_key: Point,
                             priv_key: CurveBN,
                             orig_pub_key: Point,
                             capsule: Capsule,
                             key_length=32,
                             params: UmbralParameters = None) -> bytes:
    """Derive the same symmetric key"""
    params = params if params is not None else default_params()

    ni = capsule._point_noninteractive
    d = CurveBN.hash(ni, pub_key, priv_key * ni, params=params)

    e_prime = capsule._point_e_prime
    v_prime = capsule._point_v_prime

    shared_key = d * (e_prime + v_prime)

    key = kdf(shared_key, key_length)

    e = capsule._point_e
    v = capsule._point_v
    s = capsule._bn_sig
    h = CurveBN.hash(e, v, params=params)
    inv_d = ~d

    if not (s * inv_d) * orig_pub_key == (h * e_prime) + v_prime:
        raise GenericUmbralError()
    return key
コード例 #4
0
ファイル: pre.py プロジェクト: renovate-tests/pyUmbral
def _decapsulate_reencrypted(receiving_privkey: UmbralPrivateKey,
                             capsule: Capsule,
                             key_length: int = DEM_KEYSIZE) -> bytes:
    """Derive the same symmetric encapsulated_key"""

    params = capsule.params

    pub_key = receiving_privkey.get_pubkey().point_key
    priv_key = receiving_privkey.bn_key

    precursor = capsule._attached_cfrags[0]._point_precursor
    dh_point = priv_key * precursor

    from constant_sorrow import constants

    # Combination of CFrags via Shamir's Secret Sharing reconstruction
    if len(capsule._attached_cfrags) > 1:
        xs = [
            CurveBN.hash(precursor,
                         pub_key,
                         dh_point,
                         bytes(constants.X_COORDINATE),
                         cfrag._kfrag_id,
                         params=params) for cfrag in capsule._attached_cfrags
        ]

        e_summands, v_summands = list(), list()
        for cfrag, x in zip(capsule._attached_cfrags, xs):
            if precursor != cfrag._point_precursor:
                raise ValueError("Attached CFrags are not pairwise consistent")

            lambda_i = lambda_coeff(x, xs)
            e_summands.append(lambda_i * cfrag._point_e1)
            v_summands.append(lambda_i * cfrag._point_v1)

        e_prime = sum(e_summands[1:], e_summands[0])
        v_prime = sum(v_summands[1:], v_summands[0])
    else:
        e_prime = capsule._attached_cfrags[0]._point_e1
        v_prime = capsule._attached_cfrags[0]._point_v1

    # Secret value 'd' allows to make Umbral non-interactive
    d = CurveBN.hash(precursor,
                     pub_key,
                     dh_point,
                     bytes(constants.NON_INTERACTIVE),
                     params=params)

    e, v, s = capsule.components()
    h = CurveBN.hash(e, v, params=params)

    orig_pub_key = capsule.get_correctness_keys(
    )['delegating'].point_key  # type: ignore

    if not (s / d) * orig_pub_key == (h * e_prime) + v_prime:
        raise GenericUmbralError()

    shared_key = d * (e_prime + v_prime)
    encapsulated_key = kdf(shared_key, key_length)
    return encapsulated_key
コード例 #5
0
    def _reconstruct_shamirs_secret(
            self, priv_b: Union[UmbralPrivateKey, CurveBN]) -> None:
        g = self._umbral_params.g

        if isinstance(priv_b, UmbralPrivateKey):
            pub_b = priv_b.get_pubkey()
            priv_b = priv_b.bn_key
        else:
            pub_b = priv_b * g

        cfrag_0 = self._attached_cfrags[0]
        id_0 = cfrag_0._kfrag_id
        ni = cfrag_0._point_noninteractive
        xcoord = cfrag_0._point_xcoord

        dh_xcoord = priv_b * xcoord

        blake2b = hashes.Hash(hashes.BLAKE2b(64), backend=backend)
        blake2b.update(xcoord.to_bytes())
        blake2b.update(pub_b.to_bytes())
        blake2b.update(dh_xcoord.to_bytes())
        hashed_dh_tuple = blake2b.finalize()

        if len(self._attached_cfrags) > 1:
            xs = [
                CurveBN.hash(cfrag._kfrag_id,
                             hashed_dh_tuple,
                             params=self._umbral_params)
                for cfrag in self._attached_cfrags
            ]
            x_0 = CurveBN.hash(id_0,
                               hashed_dh_tuple,
                               params=self._umbral_params)
            lambda_0 = lambda_coeff(x_0, xs)
            e = lambda_0 * cfrag_0._point_e1
            v = lambda_0 * cfrag_0._point_v1

            for cfrag in self._attached_cfrags[1:]:
                if (ni, xcoord) != (cfrag._point_noninteractive,
                                    cfrag._point_xcoord):
                    raise ValueError(
                        "Attached CFrags are not pairwise consistent")

                x_i = CurveBN.hash(cfrag._kfrag_id,
                                   hashed_dh_tuple,
                                   params=self._umbral_params)
                lambda_i = lambda_coeff(x_i, xs)
                e = e + (lambda_i * cfrag._point_e1)
                v = v + (lambda_i * cfrag._point_v1)
        else:
            e = cfrag_0._point_e1
            v = cfrag_0._point_v1

        self._point_e_prime = e
        self._point_v_prime = v
        self._point_noninteractive = ni
コード例 #6
0
ファイル: _pre.py プロジェクト: macienrique/MaciasCypher
def assess_cfrag_correctness(cfrag,
                             capsule: "Capsule",
                             pubkey_a_point,
                             pubkey_b_point,
                             params: UmbralParameters = None):
    params = params if params is not None else default_params()

    ####
    ## Here are the formulaic constituents shared with `prove_cfrag_correctness`.
    ####
    e = capsule._point_e
    v = capsule._point_v

    e1 = cfrag._point_e1
    v1 = cfrag._point_v1

    u = params.u
    u1 = cfrag.proof._point_kfrag_commitment

    e2 = cfrag.proof._point_e2
    v2 = cfrag.proof._point_v2
    u2 = cfrag.proof._point_kfrag_pok

    hash_input = (e, e1, e2, v, v1, v2, u, u1, u2)
    if cfrag.proof.metadata is not None:
        hash_input += (cfrag.proof.metadata, )
    h = CurveBN.hash(*hash_input, params=params)

    z1 = cfrag.proof._bn_kfrag_sig1
    z2 = cfrag.proof._bn_kfrag_sig2
    z3 = cfrag.proof._bn_sig
    ########

    ni = cfrag._point_noninteractive
    xcoord = cfrag._point_xcoord
    kfrag_id = cfrag._kfrag_id

    g = params.g

    # TODO: change this Schnorr signature for Ed25519 or ECDSA (#97)
    g_y = (z2 * g) + (z1 * pubkey_a_point)
    signature_input = (g_y, kfrag_id, pubkey_a_point, pubkey_b_point, u1, ni,
                       xcoord)
    kfrag_signature1 = CurveBN.hash(*signature_input, params=params)
    valid_kfrag_signature = z1 == kfrag_signature1

    correct_reencryption_of_e = z3 * e == e2 + (h * e1)

    correct_reencryption_of_v = z3 * v == v2 + (h * v1)

    correct_rk_commitment = z3 * u == u2 + (h * u1)

    return valid_kfrag_signature \
           & correct_reencryption_of_e \
           & correct_reencryption_of_v \
           & correct_rk_commitment
コード例 #7
0
ファイル: _pre.py プロジェクト: macienrique/MaciasCypher
def verify_kfrag(kfrag,
                 pubkey_a_point,
                 pubkey_b_point,
                 params: UmbralParameters = None):

    params = params if params is not None else default_params()

    u = params.u

    id = kfrag._id
    key = kfrag._bn_key
    u1 = kfrag._point_commitment
    z1 = kfrag._bn_sig1
    z2 = kfrag._bn_sig2
    ni = kfrag._point_noninteractive
    xcoord = kfrag._point_xcoord

    #  We check that the commitment u1 is well-formed
    correct_commitment = u1 == key * u

    # We check the Schnorr signature over the kfrag components
    g_y = (z2 * params.g) + (z1 * pubkey_a_point)

    signature_input = (g_y, id, pubkey_a_point, pubkey_b_point, u1, ni, xcoord)
    valid_kfrag_signature = z1 == CurveBN.hash(*signature_input, params=params)

    return correct_commitment & valid_kfrag_signature
コード例 #8
0
def verify_kfrag(kfrag,
                 pubkey_a_point,
                 pubkey_b_point,
                 params: UmbralParameters = None):

    params = params if params is not None else default_params()

    u = params.u

    u1 = kfrag._point_commitment
    z1 = kfrag._bn_sig1
    z2 = kfrag._bn_sig2
    x = kfrag._point_noninteractive
    key = kfrag._bn_key

    #  We check that the commitment u1 is well-formed
    correct_commitment = u1 == key * u

    # We check the Schnorr signature over the kfrag components
    g_y = (z2 * params.g) + (z1 * pubkey_a_point)

    kfrag_components = [
        g_y, kfrag._bn_id, pubkey_a_point, pubkey_b_point, u1, x
    ]
    valid_kfrag_signature = z1 == CurveBN.hash(*kfrag_components,
                                               params=params)

    return correct_commitment & valid_kfrag_signature
コード例 #9
0
    def _reconstruct_shamirs_secret(self, 
                                    pub_a: Union[UmbralPublicKey, Point], 
                                    priv_b: Union[UmbralPrivateKey, CurveBN],
                                    params: UmbralParameters=None) -> None:

        params = params if params is not None else default_params()

        if isinstance(priv_b, UmbralPrivateKey):
            priv_b = priv_b.bn_key

        if isinstance(pub_a, UmbralPublicKey):
            pub_a = pub_a.point_key

        g = params.g
        pub_b = priv_b * g
        g_ab = priv_b * pub_a

        blake2b = hashes.Hash(hashes.BLAKE2b(64), backend=backend)
        blake2b.update(pub_a.to_bytes())
        blake2b.update(pub_b.to_bytes())
        blake2b.update(g_ab.to_bytes())
        hashed_dh_tuple = blake2b.finalize()

        cfrag_0 = self._attached_cfrags[0]
        id_0 = cfrag_0._bn_kfrag_id
        x_0 = CurveBN.hash(id_0, hashed_dh_tuple, params=params)
        if len(self._attached_cfrags) > 1:
            xs = [CurveBN.hash(cfrag._bn_kfrag_id, hashed_dh_tuple, params=params)
                    for cfrag in self._attached_cfrags]
            lambda_0 = lambda_coeff(x_0, xs)
            e = lambda_0 * cfrag_0._point_e1
            v = lambda_0 * cfrag_0._point_v1

            for cfrag in self._attached_cfrags[1:]:
                x_i = CurveBN.hash(cfrag._bn_kfrag_id, hashed_dh_tuple, params=params)
                lambda_i = lambda_coeff(x_i, xs)
                e = e + (lambda_i * cfrag._point_e1)
                v = v + (lambda_i * cfrag._point_v1)
        else:
            e = cfrag_0._point_e1
            v = cfrag_0._point_v1

        self._point_e_prime = e
        self._point_v_prime = v
        self._point_noninteractive = cfrag_0._point_noninteractive
コード例 #10
0
    def verify(self, params: UmbralParameters=None) -> bool:
        params = params if params is not None else default_params()

        e = self._point_e
        v = self._point_v
        s = self._bn_sig
        h = CurveBN.hash(e, v, params=params)

        return s * params.g == v + (h * e)
コード例 #11
0
def assess_cfrag_correctness(cfrag,
                             capsule: "Capsule",
                             delegating_point,
                             signing_pubkey,
                             receiving_point,
                             params: UmbralParameters = None):
    params = params if params is not None else default_params()

    ####
    ## Here are the formulaic constituents shared with `prove_cfrag_correctness`.
    ####
    e = capsule._point_e
    v = capsule._point_v

    e1 = cfrag._point_e1
    v1 = cfrag._point_v1

    u = params.u
    try:
        u1 = cfrag.proof._point_kfrag_commitment

        e2 = cfrag.proof._point_e2
        v2 = cfrag.proof._point_v2
        u2 = cfrag.proof._point_kfrag_pok
    except AttributeError:
        if cfrag.proof is None:
            raise cfrag.NoProofProvided
        else:
            raise

    hash_input = (e, e1, e2, v, v1, v2, u, u1, u2)
    if cfrag.proof.metadata is not None:
        hash_input += (cfrag.proof.metadata, )
    h = CurveBN.hash(*hash_input, params=params)
    ########

    ni = cfrag._point_noninteractive
    xcoord = cfrag._point_xcoord
    kfrag_id = cfrag._kfrag_id

    kfrag_validity_message = bytes().join(
        bytes(material) for material in (kfrag_id, delegating_point,
                                         receiving_point, u1, ni, xcoord))
    valid_kfrag_signature = cfrag.proof.kfrag_signature.verify(
        kfrag_validity_message, signing_pubkey)

    z3 = cfrag.proof.bn_sig
    correct_reencryption_of_e = z3 * e == e2 + (h * e1)

    correct_reencryption_of_v = z3 * v == v2 + (h * v1)

    correct_rk_commitment = z3 * u == u2 + (h * u1)

    return valid_kfrag_signature \
           & correct_reencryption_of_e \
           & correct_reencryption_of_v \
           & correct_rk_commitment
コード例 #12
0
ファイル: pre.py プロジェクト: renovate-tests/pyUmbral
    def verify(self) -> bool:

        g = self.params.g
        e, v, s = self.components()

        h = CurveBN.hash(e, v, params=self.params)

        result = s * g == v + (h * e)  # type: bool
        return result
コード例 #13
0
ファイル: pre.py プロジェクト: soros1321/pyUmbral
    def verify(self) -> bool:

        g = self._umbral_params.g
        e = self._point_e
        v = self._point_v
        s = self._bn_sig
        h = CurveBN.hash(e, v, params=self._umbral_params)

        return s * g == v + (h * e)
コード例 #14
0
def assess_cfrag_correctness(cfrag: 'CapsuleFrag', capsule: 'Capsule') -> bool:

    correctness_keys = capsule.get_correctness_keys()

    delegating_pubkey = correctness_keys['delegating']
    signing_pubkey = correctness_keys['verifying']
    receiving_pubkey = correctness_keys['receiving']

    params = capsule.params

    ####
    # Here are the formulaic constituents shared with `prove_cfrag_correctness`.
    ####
    e = capsule._point_e
    v = capsule._point_v

    e1 = cfrag._point_e1
    v1 = cfrag._point_v1

    u = params.u
    try:
        u1 = cfrag.proof._point_kfrag_commitment

        e2 = cfrag.proof._point_e2
        v2 = cfrag.proof._point_v2
        u2 = cfrag.proof._point_kfrag_pok
    except AttributeError:
        if cfrag.proof is None:
            raise cfrag.NoProofProvided
        else:
            raise

    hash_input = [e, e1, e2, v, v1, v2, u, u1, u2]
    if cfrag.proof.metadata is not None:
        hash_input.append(cfrag.proof.metadata)
    h = CurveBN.hash(*hash_input, params=params)
    ########

    precursor = cfrag._point_precursor
    kfrag_id = cfrag._kfrag_id

    validity_input = (kfrag_id, delegating_pubkey, receiving_pubkey, u1, precursor)

    kfrag_validity_message = bytes().join(bytes(item) for item in validity_input)
    valid_kfrag_signature = cfrag.proof.kfrag_signature.verify(kfrag_validity_message, signing_pubkey)

    z3 = cfrag.proof.bn_sig
    correct_reencryption_of_e = z3 * e == e2 + (h * e1)

    correct_reencryption_of_v = z3 * v == v2 + (h * v1)

    correct_rk_commitment = z3 * u == u2 + (h * u1)

    return valid_kfrag_signature \
           & correct_reencryption_of_e \
           & correct_reencryption_of_v \
           & correct_rk_commitment
コード例 #15
0
def test_curvebn_hash():

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

    params = default_params()

    for vector in vector_suite['vectors']:
        hash_input = [bytes.fromhex(item['bytes']) for item in vector['input']]
        expected = CurveBN.from_bytes(bytes.fromhex(vector['output']))
        assert CurveBN.hash(*hash_input, params=params) == expected
コード例 #16
0
def prove_cfrag_correctness(
        cfrag: "CapsuleFrag",
        kfrag: "KFrag",
        capsule: "Capsule",
        metadata: bytes = None,
        params: UmbralParameters = None) -> "CorrectnessProof":
    params = params if params is not None else default_params()

    rk = kfrag._bn_key
    t = CurveBN.gen_rand(params.curve)
    ####
    ## Here are the formulaic constituents shared with `assess_cfrag_correctness`.
    ####
    e = capsule._point_e
    v = capsule._point_v

    e1 = cfrag._point_e1
    v1 = cfrag._point_v1

    u = params.u
    u1 = kfrag._point_commitment

    e2 = t * e
    v2 = t * v
    u2 = t * u

    hash_input = (e, e1, e2, v, v1, v2, u, u1, u2)
    if metadata is not None:
        hash_input += (metadata, )
    h = CurveBN.hash(*hash_input, params=params)
    ########

    z3 = t + h * rk

    cfrag.attach_proof(e2,
                       v2,
                       u1,
                       u2,
                       metadata=metadata,
                       z3=z3,
                       kfrag_signature=kfrag.signature)

    # Check correctness of original ciphertext (check nº 2) at the end
    # to avoid timing oracles
    if not capsule.verify():
        raise capsule.NotValid("Capsule verification failed.")
コード例 #17
0
ファイル: keys.py プロジェクト: macienrique/MaciasCypher
    def derive_privkey_by_label(self, label: bytes, salt: bytes=None, 
                                params: UmbralParameters=None):
        """
        Derives an UmbralPrivateKey using a KDF from this instance of 
        UmbralKeyingMaterial, a label, and an optional salt.
        """
        params = params if params is not None else default_params()

        key_material = HKDF(
            algorithm=hashes.BLAKE2b(64),
            length=64,
            salt=salt,
            info=b"NuCypherKMS/KeyDerivation/"+label,
            backend=default_backend()
        ).derive(self.keying_material)

        bn_key = CurveBN.hash(key_material, params=params)
        return UmbralPrivateKey(bn_key, params)
コード例 #18
0
def _encapsulate(alice_pubkey: UmbralPublicKey,
                 key_length: int = DEM_KEYSIZE) -> Tuple[bytes, Capsule]:
    """Generates a symmetric key and its associated KEM ciphertext"""

    params = alice_pubkey.params
    g = params.g

    priv_r = CurveBN.gen_rand(params.curve)
    pub_r = priv_r * g

    priv_u = CurveBN.gen_rand(params.curve)
    pub_u = priv_u * g

    h = CurveBN.hash(pub_r, pub_u, params=params)
    s = priv_u + (priv_r * h)

    shared_key = (priv_r + priv_u) * alice_pubkey.point_key

    # Key to be used for symmetric encryption
    key = kdf(shared_key, key_length)

    return key, Capsule(point_e=pub_r, point_v=pub_u, bn_sig=s, params=params)
コード例 #19
0
def prove_cfrag_correctness(cfrag: 'CapsuleFrag',
                            kfrag: 'KFrag',
                            capsule: 'Capsule',
                            metadata: Optional[bytes] = None
                            ) -> None:

    params = capsule.params

    # Check correctness of original ciphertext
    if not capsule.verify():
        raise capsule.NotValid("Capsule verification failed.")

    rk = kfrag._bn_key
    t = CurveBN.gen_rand(params.curve)
    ####
    # Here are the formulaic constituents shared with `assess_cfrag_correctness`.
    ####
    e = capsule._point_e
    v = capsule._point_v

    e1 = cfrag._point_e1
    v1 = cfrag._point_v1

    u = params.u
    u1 = kfrag._point_commitment

    e2 = t * e
    v2 = t * v
    u2 = t * u

    hash_input = [e, e1, e2, v, v1, v2, u, u1, u2]
    if metadata is not None:
        hash_input.append(metadata)
    h = CurveBN.hash(*hash_input, params=params)
    ########

    z3 = t + h * rk

    cfrag.attach_proof(e2, v2, u1, u2, metadata=metadata, z3=z3, kfrag_signature=kfrag.signature_for_bob)
コード例 #20
0
def _encapsulate(alice_pub_key: Point, key_length=32,
                 params: UmbralParameters=None) -> Tuple[bytes, Capsule]:
    """Generates a symmetric key and its associated KEM ciphertext"""
    params = params if params is not None else default_params()

    g = params.g

    priv_r = CurveBN.gen_rand(params.curve)
    pub_r = priv_r * g

    priv_u = CurveBN.gen_rand(params.curve)
    pub_u = priv_u * g

    h = CurveBN.hash(pub_r, pub_u, params=params)
    s = priv_u + (priv_r * h)

    shared_key = (priv_r + priv_u) * alice_pub_key

    # Key to be used for symmetric encryption
    key = kdf(shared_key, key_length)

    return key, Capsule(point_e=pub_r, point_v=pub_u, bn_sig=s)
コード例 #21
0
def test_cant_hash_arbitrary_object_into_bignum():
    whatever = object()
    with pytest.raises(TypeError):
        CurveBN.hash(whatever)
コード例 #22
0
ファイル: _pre.py プロジェクト: eramitg/pyUmbral
def assess_cfrag_correctness(cfrag: 'CapsuleFrag', capsule: 'Capsule') -> bool:

    correctness_keys = capsule.get_correctness_keys()

    delegating_pubkey = correctness_keys['delegating']
    signing_pubkey = correctness_keys['verifying']
    receiving_pubkey = correctness_keys['receiving']

    if not all((delegating_pubkey, signing_pubkey, receiving_pubkey)):
        raise TypeError("Need all three keys to verify correctness.")

    delegating_point = delegating_pubkey.point_key
    receiving_point = receiving_pubkey.point_key

    params = capsule._umbral_params

    ####
    # Here are the formulaic constituents shared with `prove_cfrag_correctness`.
    ####
    e = capsule._point_e
    v = capsule._point_v

    e1 = cfrag._point_e1
    v1 = cfrag._point_v1

    u = params.u
    try:
        u1 = cfrag.proof._point_kfrag_commitment

        e2 = cfrag.proof._point_e2
        v2 = cfrag.proof._point_v2
        u2 = cfrag.proof._point_kfrag_pok
    except AttributeError:
        if cfrag.proof is None:
            raise cfrag.NoProofProvided
        else:
            raise

    hash_input = (e, e1, e2, v, v1, v2, u, u1, u2)
    if cfrag.proof.metadata is not None:
        hash_input += (cfrag.proof.metadata,)
    h = CurveBN.hash(*hash_input, params=params)
    ########

    ni = cfrag._point_noninteractive
    xcoord = cfrag._point_xcoord
    kfrag_id = cfrag._kfrag_id

    kfrag_validity_message = bytes().join(
        bytes(material) for material in (kfrag_id, delegating_point, receiving_point, u1, ni, xcoord))
    valid_kfrag_signature = cfrag.proof.kfrag_signature.verify(kfrag_validity_message, signing_pubkey)

    z3 = cfrag.proof.bn_sig
    correct_reencryption_of_e = z3 * e == e2 + (h * e1)

    correct_reencryption_of_v = z3 * v == v2 + (h * v1)

    correct_rk_commitment = z3 * u == u2 + (h * u1)

    return valid_kfrag_signature \
           & correct_reencryption_of_e \
           & correct_reencryption_of_v \
           & correct_rk_commitment
コード例 #23
0
def split_rekey(delegating_privkey: UmbralPrivateKey, signer: Signer,
                receiving_pubkey: UmbralPublicKey, threshold: int,
                N: int) -> List[KFrag]:
    """
    Creates a re-encryption key from Alice to Bob and splits it in KFrags,
    using Shamir's Secret Sharing. Requires a threshold number of KFrags
    out of N to guarantee correctness of re-encryption.

    Returns a list of KFrags.
    """

    if threshold <= 0 or threshold > N:
        raise ValueError(
            'Arguments threshold and N must satisfy 0 < threshold <= N')

    if delegating_privkey.params != receiving_pubkey.params:
        raise ValueError("Keys must have the same parameter set.")

    params = delegating_privkey.params

    g = params.g

    pubkey_a_point = delegating_privkey.get_pubkey().point_key
    privkey_a_bn = delegating_privkey.bn_key

    pubkey_b_point = receiving_pubkey.point_key

    # 'ni' stands for 'Non Interactive'.
    # This point is used as an ephemeral public key in a DH key exchange,
    # and the resulting shared secret 'd' allows to make Umbral non-interactive
    priv_ni = CurveBN.gen_rand(params.curve)
    ni = priv_ni * g
    d = CurveBN.hash(ni,
                     pubkey_b_point,
                     pubkey_b_point * priv_ni,
                     params=params)

    coeffs = [privkey_a_bn * (~d)]
    coeffs += [CurveBN.gen_rand(params.curve) for _ in range(threshold - 1)]

    u = params.u

    # 'xcoord' stands for 'X coordinate'.
    # This point is used as an ephemeral public key in a DH key exchange,
    # and the resulting shared secret 'dh_xcoord' contributes to prevent
    # reconstruction of the re-encryption key without Bob's intervention
    priv_xcoord = CurveBN.gen_rand(params.curve)
    xcoord = priv_xcoord * g

    dh_xcoord = priv_xcoord * pubkey_b_point

    blake2b = hashes.Hash(hashes.BLAKE2b(64), backend=backend)
    blake2b.update(xcoord.to_bytes())
    blake2b.update(pubkey_b_point.to_bytes())
    blake2b.update(dh_xcoord.to_bytes())
    hashed_dh_tuple = blake2b.finalize()

    bn_size = CurveBN.expected_bytes_length(params.curve)

    kfrags = []
    for _ in range(N):
        id = os.urandom(bn_size)

        share_x = CurveBN.hash(id, hashed_dh_tuple, params=params)

        rk = poly_eval(coeffs, share_x)

        u1 = rk * u

        kfrag_validity_message = bytes().join(
            bytes(material) for material in (id, pubkey_a_point,
                                             pubkey_b_point, u1, ni, xcoord))
        signature = signer(kfrag_validity_message)

        kfrag = KFrag(id=id,
                      bn_key=rk,
                      point_noninteractive=ni,
                      point_commitment=u1,
                      point_xcoord=xcoord,
                      signature=signature)

        kfrags.append(kfrag)

    return kfrags
コード例 #24
0
# CurveBN.hash() #
##################

# Test vectors for different kinds of inputs (bytes, Points, CurveBNs, etc.)
inputs = (
    [b''],
    [b'abc'],
    [capsule._point_e],
    [z],
    [capsule._point_e, z],
    points,
)

vectors = list()
for input_to_hash in inputs:
    bn_output = CurveBN.hash(*input_to_hash, params=params)
    json_input = [{
        'class': data.__class__.__name__,
        'bytes': hexlify(data),
    } for data in input_to_hash]

    json_input = {'input': json_input, 'output': hexlify(bn_output)}

    vectors.append(json_input)

vector_suite = {
    'name': 'Test vectors for umbral.curvebn.CurveBN.hash()',
    'params': 'default',
    'vectors': vectors
}
コード例 #25
0
def split_rekey(privkey_a_bn: Union[UmbralPrivateKey, CurveBN],
                signer_a: Signer,
                pubkey_b_point: Union[UmbralPublicKey, Point],
                threshold: int,
                N: int,
                params: UmbralParameters = None) -> List[KFrag]:
    """
    Creates a re-encryption key from Alice to Bob and splits it in KFrags,
    using Shamir's Secret Sharing. Requires a threshold number of KFrags
    out of N to guarantee correctness of re-encryption.

    Returns a list of KFrags.
    """
    params = params if params is not None else default_params()

    g = params.g

    if isinstance(privkey_a_bn, UmbralPrivateKey):
        pubkey_a_point = privkey_a_bn.get_pubkey().point_key
        privkey_a_bn = privkey_a_bn.bn_key
    else:
        pubkey_a_point = privkey_a_bn * g

    if isinstance(pubkey_b_point, UmbralPublicKey):
        pubkey_b_point = pubkey_b_point.point_key

    # 'ni' stands for 'Non Interactive'.
    # This point is used as an ephemeral public key in a DH key exchange,
    # and the resulting shared secret 'd' allows to make Umbral non-interactive
    priv_ni = CurveBN.gen_rand(params.curve)
    ni = priv_ni * g
    d = CurveBN.hash(ni,
                     pubkey_b_point,
                     pubkey_b_point * priv_ni,
                     params=params)

    coeffs = [privkey_a_bn * (~d)]
    coeffs += [CurveBN.gen_rand(params.curve) for _ in range(threshold - 1)]

    u = params.u

    # 'xcoord' stands for 'X coordinate'.
    # This point is used as an ephemeral public key in a DH key exchange,
    # and the resulting shared secret 'dh_xcoord' contributes to prevent
    # reconstruction of the re-encryption key without Bob's intervention
    priv_xcoord = CurveBN.gen_rand(params.curve)
    xcoord = priv_xcoord * g

    dh_xcoord = priv_xcoord * pubkey_b_point

    blake2b = hashes.Hash(hashes.BLAKE2b(64), backend=backend)
    blake2b.update(xcoord.to_bytes())
    blake2b.update(pubkey_b_point.to_bytes())
    blake2b.update(dh_xcoord.to_bytes())
    hashed_dh_tuple = blake2b.finalize()

    bn_size = CurveBN.expected_bytes_length(params.curve)

    kfrags = []
    for _ in range(N):
        id = os.urandom(bn_size)

        share_x = CurveBN.hash(id, hashed_dh_tuple, params=params)

        rk = poly_eval(coeffs, share_x)

        u1 = rk * u

        kfrag_validity_message = bytes().join(
            bytes(material) for material in (id, pubkey_a_point,
                                             pubkey_b_point, u1, ni, xcoord))
        signature = signer_a(kfrag_validity_message)

        kfrag = KFrag(id=id,
                      bn_key=rk,
                      point_noninteractive=ni,
                      point_commitment=u1,
                      point_xcoord=xcoord,
                      signature=signature)
        kfrags.append(kfrag)

    return kfrags
コード例 #26
0
ファイル: pre.py プロジェクト: renovate-tests/pyUmbral
def generate_kfrags(
    delegating_privkey: UmbralPrivateKey,
    receiving_pubkey: UmbralPublicKey,
    threshold: int,
    N: int,
    signer: Signer,
    sign_delegating_key: Optional[bool] = True,
    sign_receiving_key: Optional[bool] = True,
) -> List[KFrag]:
    """
    Creates a re-encryption key from Alice's delegating public key to Bob's
    receiving public key, and splits it in KFrags, using Shamir's Secret Sharing.
    Requires a threshold number of KFrags out of N.

    Returns a list of N KFrags
    """

    if threshold <= 0 or threshold > N:
        raise ValueError(
            'Arguments threshold and N must satisfy 0 < threshold <= N')

    if delegating_privkey.params != receiving_pubkey.params:
        raise ValueError("Keys must have the same parameter set.")

    params = delegating_privkey.params

    g = params.g

    delegating_pubkey = delegating_privkey.get_pubkey()

    bob_pubkey_point = receiving_pubkey.point_key

    # The precursor point is used as an ephemeral public key in a DH key exchange,
    # and the resulting shared secret 'dh_point' is used to derive other secret values
    private_precursor = CurveBN.gen_rand(params.curve)
    precursor = private_precursor * g  # type: Any

    dh_point = private_precursor * bob_pubkey_point

    from constant_sorrow import constants

    # Secret value 'd' allows to make Umbral non-interactive
    d = CurveBN.hash(precursor,
                     bob_pubkey_point,
                     dh_point,
                     bytes(constants.NON_INTERACTIVE),
                     params=params)

    # Coefficients of the generating polynomial
    coefficients = [delegating_privkey.bn_key * (~d)]
    coefficients += [
        CurveBN.gen_rand(params.curve) for _ in range(threshold - 1)
    ]

    bn_size = CurveBN.expected_bytes_length(params.curve)

    kfrags = list()
    for _ in range(N):
        kfrag_id = os.urandom(bn_size)

        # The index of the re-encryption key share (which in Shamir's Secret
        # Sharing corresponds to x in the tuple (x, f(x)), with f being the
        # generating polynomial), is used to prevent reconstruction of the
        # re-encryption key without Bob's intervention
        share_index = CurveBN.hash(precursor,
                                   bob_pubkey_point,
                                   dh_point,
                                   bytes(constants.X_COORDINATE),
                                   kfrag_id,
                                   params=params)

        # The re-encryption key share is the result of evaluating the generating
        # polynomial for the index value
        rk = poly_eval(coefficients, share_index)

        commitment = rk * params.u  # type: Any

        validity_message_for_bob = (
            kfrag_id,
            delegating_pubkey,
            receiving_pubkey,
            commitment,
            precursor,
        )  # type: Any
        validity_message_for_bob = bytes().join(
            bytes(item) for item in validity_message_for_bob)
        signature_for_bob = signer(validity_message_for_bob)

        if sign_delegating_key and sign_receiving_key:
            mode = DELEGATING_AND_RECEIVING
        elif sign_delegating_key:
            mode = DELEGATING_ONLY
        elif sign_receiving_key:
            mode = RECEIVING_ONLY
        else:
            mode = NO_KEY

        validity_message_for_proxy = [kfrag_id, commitment, precursor,
                                      mode]  # type: Any

        if sign_delegating_key:
            validity_message_for_proxy.append(delegating_pubkey)
        if sign_receiving_key:
            validity_message_for_proxy.append(receiving_pubkey)

        validity_message_for_proxy = bytes().join(
            bytes(item) for item in validity_message_for_proxy)
        signature_for_proxy = signer(validity_message_for_proxy)

        kfrag = KFrag(
            identifier=kfrag_id,
            bn_key=rk,
            point_commitment=commitment,
            point_precursor=precursor,
            signature_for_proxy=signature_for_proxy,
            signature_for_bob=signature_for_bob,
            keys_in_signature=mode,
        )

        kfrags.append(kfrag)

    return kfrags