コード例 #1
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
コード例 #2
0
def split_rekey(priv_a: Union[UmbralPrivateKey, BigNum],
                pub_b: 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(pub_b, UmbralPublicKey):
        pub_b = pub_b.point_key

    g = params.g
    pub_a = priv_a * g

    x = BigNum.gen_rand(params.curve)
    xcomp = x * g
    d = hash_to_bn([xcomp, pub_b, pub_b * x], params)

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

    u = params.u

    g_ab = priv_a * pub_b

    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()

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

        share_x = hash_to_bn([id_kfrag, hashed_dh_tuple], params)

        rk = poly_eval(coeffs, share_x)

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

        z1 = hash_to_bn([y * g, id_kfrag, pub_a, pub_b, u1, xcomp], params)
        z2 = y - priv_a * z1

        kfrag = KFrag(id_=id_kfrag, key=rk, x=xcomp, u1=u1, z1=z1, z2=z2)
        kfrags.append(kfrag)

    return kfrags
コード例 #3
0
def split_rekey(
        priv_a: Union[UmbralPrivateKey, BigNum],
        pub_b: Union[UmbralPublicKey, Point],
        threshold: int,
        N: int,
        params: UmbralParameters = None) -> Tuple[List[KFrag], List[Point]]:
    """
    Creates a re-encryption key and splits it using Shamir's Secret Sharing.
    Requires a threshold number of fragments out of N to rebuild rekey.

    Returns rekeys and the vKeys.
    """
    params = params if params is not None else default_params()

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

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

    g = params.g
    pub_a = priv_a * g

    x = BigNum.gen_rand(params.curve)
    xcomp = x * g
    d = hash_to_bn([xcomp, pub_b, pub_b * x], params)

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

    h = params.h
    u = params.u

    v_keys = [coeff * h for coeff in coeffs]

    rk_shares = []
    for _ in range(N):
        id_kfrag = BigNum.gen_rand(params.curve)
        rk = poly_eval(coeffs, id_kfrag)

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

        z1 = hash_to_bn([y * g, id_kfrag, pub_a, pub_b, u1, xcomp], params)
        z2 = y - priv_a * z1

        kFrag = KFrag(id_=id_kfrag, key=rk, x=xcomp, u1=u1, z1=z1, z2=z2)
        rk_shares.append(kFrag)

    return rk_shares, v_keys
コード例 #4
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
コード例 #5
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
コード例 #6
0
def share_secret(secret, threshold, n):
    coeff = [secret] + [CurveBN.gen_rand() for _ in range(threshold - 1)]
    xs = [CurveBN.gen_rand() for _ in range(n)]
    points = [(x, utils.poly_eval(coeff, x)) for x in xs]
    return points
コード例 #7
0
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

    # Secret value 'd' allows to make Umbral non-interactive
    d = hash_to_curvebn(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 = hash_to_curvebn(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
コード例 #8
0
import random
from umbral.utils import poly_eval, lambda_coeff

prime = 2**127 - 1
n_voters = 100
n_authorities = 10

choices = [1, -1]
votes = random.sample(choibces, n_voters)
polynoms = [[random.randint(prime) for _ in range(n_authorities - 1)]
            for _ in range(n_voters)]
for i in range(n_voters):
    polynoms[i] = [votes[i]] + polynoms[i]

autorities_keys = [random.randint(prime)]

vote_parts = [[poly_eval(polynom, key) for polynom in polynoms]
              for key in authority_keys]