Пример #1
0
def GetNIZKPChallenges(n, y, kappa, secparams):
    """
    Algorithm 7.5: Computes n challenges c ∈ Z_q for a given of public value y. The domain
    Y of the input value is unspecified. The results in c = (c_1, ..., c_n) are identical to
    c_i = RecHash(y, i), but precomputing H makes the algorithm more efficient.

    Args:
        y (unspecified):                    Public value
        t (unspecified):                    Commitment
        kappa (int):                        Soundness strength 1 <= kappa <= 8L
        secparams (SecurityParams):         Collection of public security parameters

    Retuns:
        list of mpz:                        List containing n computed challenges (mpz)
    """

    AssertInt(n)
    AssertInt(kappa)
    assert kappa >= 1 and kappa <= 8 * secparams.L, "Constraint for kappa: 1 <= kappa <= 8L"
    AssertClass(secparams, SecurityParams)

    H = RecHash(y, secparams)
    c = []

    for i in range(1, n + 1):
        I = RecHash(i, secparams)
        c.append(mpz(ToInteger(secparams.hash(H + I)) % 2 ^ kappa))

    return c
Пример #2
0
def GenSecretVoterData(p_bold, secparams):
    """
    Algorithm 7.10: Generates the secret data for a single voter, which is sent to the voter prior to an election event via the printing authority.

    Args:
       p_bold (list):                      A list of n points = (p_1, ... , p_n) in Z_p'
       secparams (SecurityParams):         Collection of public security parameters

    Returns:
       tuple:                              Secret voter data (x,y,F,r)
    """

    AssertList(p_bold)
    AssertClass(secparams, SecurityParams)

    q_hat_apos_x = floor(secparams.q_hat_X // secparams.s)
    q_hat_apos_y = floor(secparams.q_hat_Y // secparams.s)
    x = randomMpz(q_hat_apos_x, secparams)
    y = randomMpz(q_hat_apos_y, secparams)

    F = Truncate(RecHash(p_bold, secparams),
                 secparams.L_F)  # Finalization code
    r_bold = []  # Return codes

    n = len(p_bold)
    for i in range(n):
        r_bold.append(Truncate(RecHash(p_bold[i], secparams), secparams.L_R))

    return SecretVoterData(x, y, F, r_bold)
Пример #3
0
def GetFinalization(v, P_bold, B, secparams):
    """
    Algorithm 7.36: Computes the finalization code F_v for voter v from the given points p_i
    and returns F_v together with the randomizations r_v used in the OT response.

    Args:
        v (int):                             Voter index
        p_bold (list of points):             Points
        B (list):                            Ballot list
        secparams (SecurityParams):          Collection of public security parameters

    Returns:
        tuple:                               delta (F_v, r_bold_v)
    """

    AssertInt(v)
    AssertList(P_bold)
    AssertList(B)
    AssertClass(secparams, SecurityParams)


    p_bold_v = P_bold[v]
    F = Truncate(RecHash(p_bold_v, secparams), secparams.L_F)

    for i in range(len(B)):
        if (B[i].voterId == v):
            z_i = B[i].randomizations

    delta = (F, z_i)
    return delta
Пример #4
0
def GetReturnCodes(s_bold, P_s_bold, secparams):
    """
    Algorithm 7.28: Computes the k return codes rcs = (RC_s_1, ... , RC_s_k) for the selected
    candidates by combining the hash values of the transferred points p_ij in P_s from different authorities.

    Args:
        s_bold (list of int):                Selections
        P_s_bold (list of Point):            Points
        secparams (SecurityParams):          Collection of public security parameters

    Returns:
        list                                 Points
    """

    AssertList(s_bold)
    AssertList(P_s_bold)
    AssertClass(secparams, SecurityParams)

    rc_s_bold = []

    k = len(s_bold)
    s = len(P_s_bold)

    for i in range(k):
        R_j = []

        for j in range(s):
            R_j.append(Truncate(RecHash(P_s_bold[j][i], secparams), secparams.L_R))

        R = MarkByteArray(XorByteArray(R_j), s_bold[i], secparams.n_max)
        rc_s_bold.append(ByteArrayToString(R, secparams.A_R))

    return rc_s_bold
Пример #5
0
 def testGetNIZKPChallenges(self):
     # The results in c should be identical to c_i = ToInteger(RecHash(y,i)):
     c = GetNIZKPChallenges(50, mpz(1234), secparams_l3.tau, secparams_l3)
     self.assertEqual(len(c), 50)
     for i in range(1, len(c) + 1):
         self.assertEqual(
             c[i - 1],
             ToInteger(RecHash([mpz(1234), i], secparams_l3)) % 2
             ^ secparams_l3.tau)
Пример #6
0
def GetPoints(beta, s_bold, r_bold, secparams):
    """
    Algorithm 7.26: Computes the k-by-s matrix P_s = (P_ij)k x s of the points obtained from
    the s authorities for the selection s. The points are derived from the messages included
    in the OT responses beta = (beta_1, ..., beta_s)

    Args:
        beta (Response):                     Oblivious Transfer Response
        s_bold (list of int):                Selections
        r_bold (list of mpz):                Randomizations
        secparams (SecurityParams):          Collection of public security parameters

    Returns:
        list                                 Points
    """

    AssertClass(beta, Response)
    AssertList(s_bold)
    AssertList(r_bold)
    AssertClass(secparams, SecurityParams)

    (b_bold, C_bold, d) = beta

    k = len(s_bold)

    l_M = ceil(secparams.L_M // secparams.L)

    p_bold = []

    for j in range(k):
        k_j = (b_bold[j] *
               gmpy2.powmod(d, -r_bold[j], secparams.p)) % secparams.p

        K_j = bytearray()
        for c in range(l_M):
            K_j += RecHash([k_j, c], secparams)

        K_j = Truncate(K_j, secparams.L_M)
        M_j = XorByteArray([C_bold[s_bold[j]][j], K_j])
        x_j = ToInteger(Truncate(M_j, secparams.L_M // 2))
        y_j = ToInteger(Skip(M_j, secparams.L_M // 2))

        if x_j >= secparams.p_prime or y_j >= secparams.p_prime:
            return None

        p_bold.append(Point(x_j, y_j))

    return p_bold
Пример #7
0
def GetNIZKPChallenge(y, t, kappa, secparams):
    """
    Algorithm 7.4: Computes a NIZKP challenge c ∈ Z_q for a given public value
    y and a public commitment t. The domains Y and T of the input values are
    unspecified.

    Args:
        y (unspecified):                    Public value
        t (unspecified):                    Commitment
        kappa (int):                        Soundness strength 1 <= kappa <= 8L
        secparams (SecurityParams):         Collection of public security parameters

    Returns:
        mpz:                                The NIZKP challenge
    """

    AssertInt(kappa)
    assert kappa >= 1 and kappa <= 8 * secparams.L, "Constraint for kappa: 1 <= kappa <= 8L"
    AssertClass(secparams, SecurityParams)

    c = mpz(ToInteger(RecHash([y, t], secparams)) % 2 ^ kappa)

    return c
Пример #8
0
def GetGenerators(n, secparams):
    """
    Algorithm 7.3: Computes n independent generators of G_q. The algorithm is an adaption of the NIST standard FIPS PUB 186-4 [1, Appendix A.2.3].
    The string "chVote" guarantees that the resulting values are specific for chVote. In a more efficient implementation of this algorithm, the list of resulting generators is accumulated in a cache
    or precomputed for the largest expected value n_max >= n.

    Args:
       n (int):                             The number of primes to be calculated
       secparams (SecurityParams):          Collection of public security parameters

    Returns:
       list of mpz:                         a list with independent generators of G_p (mpz)
    """

    AssertInt(n)
    AssertClass(secparams, SecurityParams)
    assert n >= 0, "n must be greater than or equal 0"

    generators = []

    for i in range(n):
        x = 0

        while True:
            x += 1
            h = mpz(
                ToInteger(RecHash(["chVote", "ggen", i, x], secparams)) %
                secparams.p)
            h = (h**2) % secparams.p

            if h not in (0, 1):
                break

        generators.append(h)

    return generators
Пример #9
0
def GenResponse(v, a_bold, pk, n_bold, k_bold, E_bold, P_bold, secparams):
    """
    Algorithm 7.25: Generates the response beta for the given OT query a. The messages to
    transfer are byte array representations of the n points (p_v,1, ... p_v,n). Along with beta,
    the algorithm also returns the randomizations r used to generate the response.

    Args:
        v (int):                            Voter Index
        a_bold (list of mpz):               Queries
        pk (mpz):                           Encryption Key
        n_bold (list of int):               Number of candidates
        k_bold (list of int):               Number of selections
        E_bold (list of list):              Eligibility matrix
        P_bold (list of list):              Points N x n
        secparams (SecurityParams):         Collection of public security parameters

    Returns:
        tuple:                              (beta, r)
    """

    AssertInt(v)
    AssertList(a_bold)
    for a in a_bold:
        assert IsMember(a[0],
                        secparams), "All elements of a_bold must be in G_q"
    for a in a_bold:
        assert IsMember(a[1],
                        secparams), "All elements of a_bold must be in G_q"
    AssertMpz(pk)
    assert IsMember(pk, secparams), "Public key must be in G_q"
    assert pk != mpz(1), "Public key cannot be equal to 1"
    AssertList(n_bold)
    AssertList(k_bold)
    AssertList(E_bold)
    AssertList(P_bold)
    AssertClass(secparams, SecurityParams)

    n = sum(n_bold)
    k = len(a_bold)
    t = len(n_bold)
    M = []

    z_1 = randomMpz(secparams.q, secparams)
    z_2 = randomMpz(secparams.q, secparams)

    beta = []
    b_bold = []

    for j in range(k):
        beta.append(randomQuadResMpz(secparams))
        b_j = gmpy2.powmod(a_bold[j][0], z_1, secparams.p)
        b_j *= gmpy2.powmod(a_bold[j][1], z_2, secparams.p)
        b_j *= beta[j]
        b_j %= secparams.p
        b_bold.append(b_j)

    l_M = ceil(secparams.L_M / secparams.L)
    p_bold = GetPrimes(n, secparams)

    n_prime = 0
    k_prime = 0

    C_bold = [[None for i in range(sum(k_bold))] for i in range(n)]

    for l in range(len(k_bold)):
        if E_bold[v][l] != 0:
            for i in range(n_prime, n_prime + n_bold[l]):
                p_prime_i = gmpy2.powmod(p_bold[i], z_1, secparams.p)
                M.append(
                    ToByteArrayN(P_bold[v][i].x, secparams.L_M // 2) +
                    ToByteArrayN(P_bold[v][i].y, secparams.L_M // 2))

                for j in range(k_prime, k_prime + E_bold[v][l] * k_bold[l]):
                    k_ij = p_prime_i * beta[j] % secparams.p
                    k_tmp = bytearray()

                    for c in range(l_M):
                        k_tmp += RecHash([k_ij, c], secparams)

                    K_ij = Truncate(k_tmp, secparams.L_M)
                    C_bold[i][j] = XorByteArray([M[i], K_ij])

            k_prime = k_prime + E_bold[v][l] * k_bold[l]
        n_prime = n_prime + n_bold[l]

    d = (gmpy2.powmod(pk, z_1, secparams.p) *
         gmpy2.powmod(secparams.g, z_2, secparams.p)) % secparams.p
    beta = Response(b_bold, C_bold, d)
    z = (z_1, z_2)

    return (beta, z)