Esempio n. 1
0
def GenQuery(q_bold, pk, secparams):
    """
    Algorithm 7.20: Generates an OT query a from the prime numbers representing the
    voter's selection and a for a given public encryption key (which serves as a
    generator).

    Args:
        q_bold (list):                       Selected primes
        pk (mpz):                            Encryption key
        secparams (SecurityParams):          Collection of public security parameters

    Returns:
        (a, r):                              The OT query
    """

    AssertList(q_bold)
    AssertMpz(pk)
    AssertClass(secparams, SecurityParams)

    k = len(q_bold)
    a_bold = [None] * k
    r_bold = [None] * k

    for j in range(k):
        r_bold[j] = randomMpz(secparams.q, secparams)
        a_j_1 = (q_bold[j] *
                 gmpy2.powmod(pk, r_bold[j], secparams.p)) % secparams.p
        a_j_2 = gmpy2.powmod(secparams.g, r_bold[j], secparams.p)
        a_bold[j] = (a_j_1, a_j_2)

    return (a_bold, r_bold)
def CheckAllShuffleProofs(pi_bold, e_0_bold, E_bold, pk, secparams):
    """
    Algorithm: Checks if a chain of shuffle proofs generated by s different authorities is
    correct.

    Args:
       pi_bold (list of ShuffleProof):          Shuffle proof
       e_0_bold (list):                         ElGamal Encryptions
       E_bold (list):                           Shuffled ElGamal Encryptions
       pk (mpz):                                Encryption key pk
       secparams (SecurityParams):              Collection of public security parameters

    Returns:
        bool
    """
    AssertList(pi_bold)
    AssertList(e_0_bold)
    AssertList(E_bold)
    AssertMpz(pk)
    AssertClass(secparams, SecurityParams)

    N = len(e_0_bold)
    e_bold_tmp = []
    e_bold_tmp.append(e_0_bold)
    e_bold_tmp.extend(E_bold)

    for j in range(secparams.s):
        if not CheckShuffleProof(pi_bold[j], e_bold_tmp[j], e_bold_tmp[j + 1],
                                 pk, secparams):
            return False
    return True
def GenConfirmationProof(y, y_prime, y_hat, secparams):
    """
    Algorithm 7.32: Generates a NIZKP of knowledge of the secret confirmation
    credential y that matches with a given public confirmation credential y_hat.
    Note that this proof is equivalent to a Schnorr identification proof. For the
    verification of pi, see Alg. 7.36.

    Args:
        y:                                   Secret confirmation credential
        y_prime:                             Secret validity credential
        y_hat:                               Public confirmation credential
        secparams (SecurityParams):          Collection of public security parameters

    Returns:
        π:          The NIZKP challenge
    """

    AssertMpz(y)
    AssertClass(secparams, SecurityParams)

    w = randomMpz(secparams.q_hat, secparams)
    t = gmpy2.powmod(secparams.g_hat, w, secparams.p_hat)
    c = GetNIZKPChallenge(y_hat, t, secparams.tau, secparams)
    s = w + c * (y + y_prime) % secparams.q_hat
    pi = (t, s)

    return pi
Esempio n. 4
0
def ToString(x, k, A):
    """
    Algorithm 4.6: Computes a string representation of length k in big-endian order of a given non negative integer x in N

    Args:
       x (mpz):     Integer x ∈ N
       k (int)      String length k >= log_N (x)
       A (list)     Alphabet A = {c_1, ..., c_N}

    Returns:
       string:      The string representation of x
    """

    AssertMpz(x)
    AssertInt(k)
    AssertList(A)

    S = ""
    N = len(A)

    for i in reversed(range(k)):
        s_k = A[x % N]
        x = x // N
        S = s_k + S

    return S
Esempio n. 5
0
def GenShuffle(e_bold, pk, secparams):
    """
    Algorithm 7.41: Generates a random permutation psi and uses it to shuffle a given
    list e = (e_1, ..., e_n) of ElGamal encryptions e_i = (a_i, b_i) in G_q^2.
    With psi_N = {(j_1, ..., j_N) : j_i in {1,...,N}, j_i_1 != j_i_2, forAll i_1 != i2}
    we denote the set of all N! possible permutations of the values {1, ..., N}

    Args:
       e_bold (list):                      ElGamal Encryptions
       pk (mpz):                           Encryption key pk
       secparams (SecurityParams):         Collection of public security parameters

    Returns:
        tuple                              (e_prime, r_prime, psi)
    """

    AssertList(e_bold)
    AssertMpz(pk)

    psi_bold = GenPermutation(len(e_bold), secparams)
    e_prime_bold = []
    r_prime_bold = []

    N = len(e_bold)
    for i in range(N):
        (e_prime_i, r_prime_i) = GenReEncryption(e_bold[i], pk, secparams)
        e_prime_bold.append(e_prime_i)
        r_prime_bold.append(r_prime_i)

    e_prime_shuffled = [None] * len(e_prime_bold)
    for i in range(N):
        e_prime_shuffled[i] = e_prime_bold[psi_bold[i]]
    return (e_prime_shuffled, r_prime_bold, psi_bold)
Esempio n. 6
0
def CheckBallotProof(pi, x_hat, a_bold, pk, secparams):
    """
    Algorithm 7.24: Checks the correctness of a ballot proof Pi generated by Alg. 7.21. The
    public values of this proof are the public voting credential x_hat and the ElGamal encryption (a,b)

    Args:
        pi (BallotProof):                    Ballot proof pi = (t,s)
        x_hat (mpz):                         Voting credential x_hat
        a_bold (list):                       OT query a_bold
        pk (mpz):                            ElGamal key pk
        secparams (SecurityParams):          Collection of public security parameters

    Returns:
        bool:                                True if (t_1 == t'_1 and t_2 == t'_2 and t_3 == t'_3) holds
    """

    AssertClass(pi, BallotProof)
    AssertMpz(x_hat)
    AssertList(a_bold)
    AssertMpz(pk)
    AssertClass(secparams, SecurityParams)

    y = (x_hat, a_bold)
    t = pi[0]
    (t_1, t_2, t_3) = t
    s = pi[1]
    (s_1, s_2, s_3) = s

    c = GetNIZKPChallenge(y, t, secparams.tau, secparams)

    a_1 = mpz(1)
    a_2 = mpz(1)

    for j in range(len(a_bold)):
        a_1 = (a_1 * a_bold[j][0]) % secparams.p
        a_2 = (a_2 * a_bold[j][1]) % secparams.p
        # e = (a, b)

    t_prime_1 = (gmpy2.powmod(x_hat, -c, secparams.p_hat) * gmpy2.powmod(
        secparams.g_hat, s_1, secparams.p_hat)) % secparams.p_hat
    t_prime_2 = (gmpy2.powmod(a_1, -c, secparams.p) * s_2 *
                 gmpy2.powmod(pk, s_3, secparams.p)) % secparams.p
    t_prime_3 = (gmpy2.powmod(a_2, -c, secparams.p) *
                 gmpy2.powmod(secparams.g, s_3, secparams.p)) % secparams.p

    return t_1 == t_prime_1 and t_2 == t_prime_2 and t_3 == t_prime_3
Esempio n. 7
0
def GenBallot(X,
              s,
              pk,
              secparams,
              manipulatedPublicCredential=None,
              manipulatedPublicKey=None):
    """
    Algorithm 7.18: Generates a ballot based on the selection s and the voting code X. The
    ballot includes an OT query a and a proof pi. The algorithm also returns the random
    values used to generate the OT query. These random values are required in Alg. 7.27
    to derive the transferred messages from the OT response, which itself is generated by Alg. 7.25.

    Args:
        X (str):                            Voting Code X ∈ A_X^l_X
        s (list of int):                    Selection s = (s_1, ... , s_k), 1 <= s_1 < ... < s_k
        pk (mpz):                           ElGamal key pk ∈ G_p \ {1}
       secparams (SecurityParams):          Collection of public security parameters

    Returns:
        tuple:                              alpha = (r, Ballot) = (r, (x_hat, a, b, pi))
    """

    AssertMpz(pk)
    AssertList(s)
    AssertClass(secparams, SecurityParams)

    x = mpz(StringToInteger(X, secparams.A_X))
    x_hat = gmpy2.powmod(secparams.g_hat, x, secparams.p_hat)
    if manipulatedPublicCredential != None:
        x_hat = mpz(manipulatedPublicCredential)
    if manipulatedPublicKey != None:
        pk = mpz(manipulatedPublicKey)

    q_bold = GetSelectedPrimes(s, secparams)  # q = (q_1, ... , q_k)
    (a_bold, r_bold) = GenQuery(q_bold, pk, secparams)

    m = mpz(1)
    for j in range(len(q_bold)):
        m = m * q_bold[j]

    if m >= secparams.p:
        return None

    #a = mpz(1)
    #b = mpz(1)
    r = mpz(0)

    for j in range(len(q_bold)):
        #a = (a * a_bold[j][0]) % secparams.p
        #b = (b * a_bold[j][1]) % secparams.p
        r = (r + r_bold[j]) % secparams.q

    #e = (a, b)
    pi = GenBallotProof(x, m, r, x_hat, a_bold, pk, secparams)
    alpha = Ballot(x_hat, a_bold, pi)

    return (alpha, r_bold)
Esempio n. 8
0
def GenBallotProof(x, m, r, x_hat, a_bold, pk, secparams):
    """
    Algorithm 7.21: Generates a NIZKP, which proves that the ballot has been formed properly.
    This proof includes a proof of knowledge of the secret voting credential x that matches with
    the public voting credential x_hat. Note that this is equivalent to a Schnorr Identification proof.

    Args:
        x (mpz):                            Voting credential ∈ Z_q_hat
        m (mpz):                            Product of selected primes m ∈ G_q
        r (mpz):                            Randomization r ∈ Z_q
        a_bold (list):                      OT queries
        pk (mpz):                           Encryption key pk ∈ G_q
        secparams (SecurityParams):         Collection of public security parameters

    Returns:
        tuple:                              ((t_1, t_2, t_3), (s_1, s_2, s_3))
    """

    AssertMpz(x)
    AssertMpz(m)
    AssertMpz(r)
    AssertMpz(x_hat)
    AssertList(a_bold)
    AssertMpz(pk)
    AssertClass(secparams, SecurityParams)

    w_1 = randomMpz(secparams.q_hat, secparams)
    w_2 = randomQuadResMpz(secparams)
    w_3 = randomMpz(secparams.q, secparams)
    t_1 = gmpy2.powmod(secparams.g_hat, w_1, secparams.p_hat)
    t_2 = (w_2 * gmpy2.powmod(pk, w_3, secparams.p)) % secparams.p
    t_3 = gmpy2.powmod(secparams.g, w_3, secparams.p)

    y = (x_hat, a_bold)
    t = (t_1, t_2, t_3)
    c = GetNIZKPChallenge(y, t, secparams.tau, secparams)

    s_1 = (w_1 + c * x) % secparams.q_hat
    s_2 = (w_2 * gmpy2.powmod(m, c, secparams.p)) % secparams.p
    s_3 = (w_3 + c * r) % secparams.q

    s = (s_1, s_2, s_3)

    return BallotProof(t,s)
Esempio n. 9
0
def GenDecryptionProof(sk_j, pk_j, e_bold, b_prime_bold, secparams):
    """
    Algorithm 7.50: Generates a decryption proof relative to ElGamal encryptions e and
    partial decryptions b'. This is essentially a NIZKP of knowledge of the private key share
    sk_j satisfying b'_i = b_i^sk_j for all input encryptions e_i = (a_i, b_i) and pk_j = g^sk_j.
    Proof verification, see Alg. 7.52.

    Args:
        sj_j (mpz):                             Decryption key share
        pk_j (mpz):                             Encryption key share
        e_bold (list of ElGamalEncryption):     ElGamal encryptions e_bold
        b_prime_bold (list):                    Partial decryptions
        secparams (SecurityParams):             Collection of public security parameters

    Returns:
        DecryptionProof
    """
    AssertMpz(sk_j)
    AssertMpz(pk_j)
    AssertList(e_bold)
    AssertList(b_prime_bold)
    AssertClass(secparams, SecurityParams)

    w = randomMpz(secparams.q, secparams)
    t_0 = gmpy2.powmod(secparams.g, w, secparams.p)

    t_1_to_N = []
    N = len(e_bold)
    for i in range(N):
        t_1_to_N.append(gmpy2.powmod(e_bold[i].b, w, secparams.p))

    t = (t_0, t_1_to_N)

    b_bold = [e.b for e in e_bold]

    y = (pk_j, b_bold, b_prime_bold)
    c = GetNIZKPChallenge(y, t, secparams.tau, secparams)

    s = (w + c * sk_j) % secparams.q
    pi = DecryptionProof(t, s)

    return pi
Esempio n. 10
0
def GetPublicVoterData(x, y, y_prime, secparams):
    """
    Algorithm 7.11: Generates the public data for a single voter, which is sent to the bulletin board.

    Args:
       x (mpz):                            Secret voting credential
       y (mpz):                            Secret confirmation credential
       y_prime (mpz):                      Secret vote validity credential y_prime in Z_p_prime
       secparams (SecurityParams):         Collection of public security parameters

    Returns:
       tuple:                              Public data of a voter
    """

    AssertMpz(x)
    AssertMpz(y)
    AssertMpz(y_prime)
    AssertClass(secparams, SecurityParams)

    # h = ToInteger(RecHash(y_bold, secparams)) % secparams.q_hat
    x_hat = gmpy2.powmod(secparams.g_hat, x, secparams.p_hat)
    y_hat = gmpy2.powmod(secparams.g_hat, (y+y_prime) % secparams.q_hat, secparams.p_hat)

    return (x_hat, y_hat) # as d_hat
Esempio n. 11
0
def CheckBallot(v, alpha, pk, k_bold, E_bold, x_hat_bold, B, secparams):
    """
    Algorithm 7.22: Checks if a ballot alpha obtained from voter v is valid. For this, voter i
    must not have submitted a valid ballot before, pi must be valid, and x_hat must be the public
    voting credential of voter v. Note that parameter checking |a|  ki for ki  °tj1 kij is an important initial step of this algorithm.

    Args:
        v (int):                             Voter index
        alpha (Ballot):                      Ballot
        pk (mpz):                            Public Key
        k_bold (list):                       Number of selections
        E_bold (list):                       Eligibility matrix E
        x_hat_bold (list):                   Public voting credentials
        B (list):                            Ballot List
        secparams (SecurityParams):          Collection of public security parameters

    Returns:
        bool:                                True if the ballot is valid, False if not
    """

    AssertInt(v)
    AssertClass(alpha, Ballot)
    AssertMpz(pk)
    assert IsMember(pk, secparams), "pk must be in G_q"
    AssertList(k_bold)
    AssertList(x_hat_bold)
    AssertList(B)
    AssertClass(secparams, SecurityParams)

    k_prime = 0
    for j in range(len(k_bold)):
        k_prime = k_prime + E_bold[v][j] * k_bold[
            j]  # if voter i is eligible to cast a vote in election j, multiply 1 * the number of selections in j

    hasBallot = HasBallot(v, B, secparams)
    credentialCheck = x_hat_bold[v] == alpha.x_hat
    queryLength = len(alpha.a_bold) == k_prime
    if not hasBallot and credentialCheck and queryLength:
        ballotProofCheck = CheckBallotProof(alpha.pi, alpha.x_hat,
                                            alpha.a_bold, pk, secparams)
        if ballotProofCheck:
            return True, []

    return (False, [False, hasBallot, credentialCheck, queryLength])
Esempio n. 12
0
def CheckDecryptionProof(pi_prime, pk_j, e_bold, b_prime_bold, secparams):
    """
    Algorithm 7.52: Checks the correctness of a decryption proof  generated by Alg. 7.50.
    The public values are the ElGamal encryptions e, the partial decryptions b1, and the
    share pkj of the public encryption key.

    Args:
        pi_prime (DecryptionProof):                 Decryption
        pk_j (mpz):                                 Encryption key share
        e_bold (list of ElGamalEncryption):         ElGamal encryptions
        b_prime_bold (list):                        Partial decryptions
        secparams (SecurityParams):                 Collection of public security parameters

    Returns:
        bool:                                       (t_0 = t_prime_0) and for i = 1..N: t_i = t_prime_i
    """
    #AssertMpz(pi_prime)
    AssertMpz(pk_j)
    AssertList(e_bold)
    AssertList(b_prime_bold)
    AssertClass(secparams, SecurityParams)

    t_0 = pi_prime.t[0]
    t_1_to_N = pi_prime.t[1]

    b_bold = [e.b for e in e_bold]
    y = (pk_j, b_bold, b_prime_bold)
    c = GetNIZKPChallenge(y, pi_prime.t, secparams.tau, secparams)
    t_prime_0 = (gmpy2.powmod(pk_j, -c, secparams.p) * gmpy2.powmod(
        secparams.g, pi_prime.s, secparams.p)) % secparams.p

    t_prime_bold = []
    N = len(e_bold)
    for i in range(N):
        t_prime_bold.append(
            (gmpy2.powmod(b_prime_bold[i], -c, secparams.p) *
             gmpy2.powmod(b_bold[i], pi_prime.s, secparams.p)) % secparams.p)

    return (t_0 == t_prime_0 and t_prime_bold == t_1_to_N)
Esempio n. 13
0
def GetPublicKey(pk_bold, secparams):
    """
    Algorithm 7.16: Computes a public ElGamal encryption key pk ∈ G_q from given shares pk_j ∈ G_q

    Args:
       pk_bold (list of mpz):              List of public keys = (pk_1, ... , pk_s), pk_j ∈ G_q
       secparams (SecurityParams):         Collection of public security parameters

    Returns:
        mpz:                               Public Key pk
    """

    AssertList(pk_bold)
    AssertClass(secparams, SecurityParams)

    resultPk = mpz(1)

    for j in range(secparams.s):  # loop over s (authorities)
        resultPk = (resultPk * pk_bold[j]) % secparams.p

    AssertMpz(resultPk)

    return resultPk
Esempio n. 14
0
def GetPartialDecryptions(e_bold, sk_j, secparams):
    """
    Algorithm 7.49: Algorithm 7.49: Computes the partial decryptions of a given input list e of ElGamal
    encryption using a share sk_j of the private decryption key.

    Args:
       e_bold (list of ElGamalEncryption): ElGamal encryptions
       sk_j (mpz):                         Decryption key share
       secparams (SecurityParams):         Collection of public security parameters

    Returns:
        list of mpz                        Partial decryptions
    """

    AssertList(e_bold)
    AssertMpz(sk_j)
    AssertClass(secparams, SecurityParams)

    b_prime_bold = []
    N = len(e_bold)
    for i in range(N):
        b_prime_bold.append(gmpy2.powmod(e_bold[i][1], sk_j, secparams.p))

    return b_prime_bold
Esempio n. 15
0
def GenReEncryption(e, pk, secparams):
    """
    Algorithm 7.43: Generates a re-encryption e' = (a * pk^r', b*g^r') of the given ElGamal encryption
    e = (a,b) in G_q^2. The re-encryption e' is returned together with the randomization r' in Z_q

    Args:
       e (tuple):                          ElGamal encryption e = (a,b)
       pk (mpz):                           Encryption key pk
       secparams (SecurityParams):         Collection of public security parameters

    Returns:
        tuple         Re-Encryption (e', r')
    """

    AssertMpz(pk)
    AssertClass(secparams, SecurityParams)

    (a, b) = e
    r_prime = randomMpz(secparams.q, secparams)
    a_prime = (a * gmpy2.powmod(pk, r_prime, secparams.p)) % secparams.p
    b_prime = (b * gmpy2.powmod(secparams.g, r_prime, secparams.p)) % secparams.p
    e_prime = ElGamalEncryption(a_prime, b_prime)

    return (e_prime, r_prime)
Esempio n. 16
0
def CheckShuffleProof(pi, e_bold, e_prime_bold, pk, secparams):
    """
    Algorithm 7.48: Checks the correctness of a NIZKP of a shuffle pi generated by Alg. 7.44.
    The public values are the ElGamal encryptions e and e' and the public encryption key pk.

    Args:
       pi (ShuffleProof):                       Shuffle proof
       e_bold (list):                           ElGamal Encryptions
       e_prime_bold (list):                     Shuffled ElGamal Encryptions e'
       pk (mpz):                                Encryption key pk
       secparams (SecurityParams):              Collection of public security parameters

    Returns:
        ShuffleProof
    """
    AssertClass(pi, ShuffleProof)
    AssertList(e_bold)
    AssertList(e_prime_bold)
    AssertMpz(pk)
    AssertClass(secparams, SecurityParams)

    N = len(e_bold)
    c_bold = pi.c_bold
    c_hat_bold = pi.c_hat_bold

    s_1 = pi.s[0]
    s_2 = pi.s[1]
    s_3 = pi.s[2]
    s_4 = pi.s[3]
    s_hat = pi.s[4]  # tuple
    s_prime = pi.s[5]  # list

    t_1 = pi.t[0]
    t_2 = pi.t[1]
    t_3 = pi.t[2]
    t_4_1 = pi.t[3][0]
    t_4_2 = pi.t[3][1]
    t_hat = pi.t[4]

    assert len(
        e_prime_bold
    ) == N, "The size of e_prime_bold must be identical to N ( = len(e_bold))"
    assert len(
        c_bold
    ) == N, "The size of c_bold must be identical to N ( = len(e_bold))"
    assert len(
        c_hat_bold
    ) == N, "The size of c_bold must be identical to N ( = len(e_bold))"
    assert len(pi.t[3]) == 2, "The size of t_4 must be identical to 2"
    assert len(
        t_hat
    ) == N, "The size of t_hat must be identical to N ( = len(e_bold))"
    assert len(
        s_hat
    ) == N, "The size of s_hat must be identical to N ( = len(e_bold))"

    h_bold = GetGenerators(N, secparams)
    u_bold = GetNIZKPChallenges(N, (e_bold, e_prime_bold, c_bold),
                                secparams.tau, secparams)
    y = (e_bold, e_prime_bold, c_bold, c_hat_bold, pk)
    c = GetNIZKPChallenge(y, pi.t, secparams.tau, secparams)

    c_product = mpz(1)
    for i in range(N):
        c_product = (c_product * pi.c_bold[i]) % secparams.p

    h_product = mpz(1)
    for i in range(N):
        h_product = (h_product * h_bold[i]) % secparams.p

    c_line = (c_product * gmpy2.invert(h_product, secparams.p)) % secparams.p

    u = mpz(1)
    for i in range(N):
        u = (u * u_bold[i]) % secparams.q

    c_hat = (c_hat_bold[N - 1] * gmpy2.invert(
        gmpy2.powmod(secparams.h, u, secparams.p), secparams.p)) % secparams.p

    c_product2 = mpz(1)
    for i in range(N):
        c_product2 = (c_product2 * gmpy2.powmod(c_bold[i], u_bold[i],
                                                secparams.p)) % secparams.p
    c_tilde = c_product2 % secparams.p

    a_prime = mpz(1)
    for i in range(N):
        a_prime = (a_prime * gmpy2.powmod(e_bold[i].a, u_bold[i],
                                          secparams.p)) % secparams.p

    b_prime = mpz(1)
    for i in range(N):
        b_prime = (b_prime * gmpy2.powmod(e_bold[i].b, u_bold[i],
                                          secparams.p)) % secparams.p

    t_prime_1 = (gmpy2.powmod(c_line, -c, secparams.p) *
                 gmpy2.powmod(secparams.g, s_1, secparams.p)) % secparams.p
    t_prime_2 = (gmpy2.powmod(c_hat, -c, secparams.p) *
                 gmpy2.powmod(secparams.g, s_2, secparams.p)) % secparams.p
    h_product2 = mpz(1)
    for i in range(N):
        h_product2 = (h_product2 * gmpy2.powmod(h_bold[i], s_prime[i],
                                                secparams.p)) % secparams.p
    t_prime_3 = (gmpy2.powmod(c_tilde, -c, secparams.p) * gmpy2.powmod(
        secparams.g, s_3, secparams.p) * h_product2) % secparams.p

    a_prime_product = mpz(1)
    for i in range(N):
        a_prime_product = (a_prime_product * gmpy2.powmod(
            e_prime_bold[i].a, s_prime[i], secparams.p)) % secparams.p
    t_prime_4_1 = (gmpy2.powmod(a_prime, -c, secparams.p) * gmpy2.powmod(
        pk, -s_4, secparams.p) * a_prime_product) % secparams.p

    b_prime_product = mpz(1)
    for i in range(N):
        b_prime_product = (b_prime_product * gmpy2.powmod(
            e_prime_bold[i].b, s_prime[i], secparams.p)) % secparams.p
    t_prime_4_2 = (gmpy2.powmod(b_prime, -c, secparams.p) * gmpy2.powmod(
        secparams.g, -s_4, secparams.p) * b_prime_product) % secparams.p

    c_hat_bold_tmp = []
    c_hat_bold_tmp.append(secparams.h)
    c_hat_bold_tmp.extend(c_hat_bold)

    t_hat_prime_bold = [None] * N
    for i in range(N):
        t_hat_prime_bold[i] = (
            gmpy2.powmod(c_hat_bold_tmp[i + 1], -c, secparams.p) *
            gmpy2.powmod(secparams.g, s_hat[i], secparams.p) * gmpy2.powmod(
                c_hat_bold_tmp[i], s_prime[i], secparams.p)) % secparams.p

    return (t_1 == t_prime_1) and (t_2 == t_prime_2) and (
        t_3 == t_prime_3) and (t_4_1 == t_prime_4_1) and (
            t_4_2 == t_prime_4_2) and (t_hat == t_hat_prime_bold)
Esempio n. 17
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)
Esempio n. 18
0
def GenShuffleProof(e_bold, e_prime_bold, r_prime_bold, psi, pk, secparams):
    """
    Algorithm 7.44: Generates a NIZKP of shuffle relative to ElGamal encryptions e and e1,
    which is equivalent to proving knowledge of a permutation psi and randomizations r_prime such
    that e_prime = Shuffle_pk(e,r_prime,psi). The algorithm implements Wikström’s proof of a shuffle
    [19, 18], except for the fact that the offline and online phases are merged. For the proof
    verification, see Alg. 7.48. For further background information we refer to Section 5.5.

    Args:
       e_bold (list):                           ElGamal Encryptions
       e_prime_bold (list):                     Shuffled ElGamal Encryptions e'
       r_prime_bold (list):                     Re-encryption randomizations r'
       psi (list):                              Permutation
       pk (mpz):                                Encryption key pk
       secparams (SecurityParams):              Collection of public security parameters

    Returns:
        ShuffleProof
    """
    AssertList(e_bold)
    AssertList(e_prime_bold)
    AssertList(r_prime_bold)
    AssertList(psi)
    AssertMpz(pk)
    AssertClass(secparams, SecurityParams)

    N = len(e_bold)
    h_bold = GetGenerators(N, secparams)
    (c_bold, r_bold) = GenPermutationCommitment(psi, h_bold, secparams)
    u_bold = GetNIZKPChallenges(N, (e_bold, e_prime_bold, c_bold), secparams.tau, secparams)

    u_prime_bold = [None] * N
    for i in range(N):
        u_prime_bold[i] = u_bold[psi[i]]

    (c_hat_bold, r_hat_bold) = GenCommitmentChain(secparams.h, u_prime_bold, secparams)

    w_1 = randomMpz(secparams.q, secparams)
    w_2 = randomMpz(secparams.q, secparams)
    w_3 = randomMpz(secparams.q, secparams)
    w_4 = randomMpz(secparams.q, secparams)

    w_hat_bold = [None] * N
    w_prime_bold = [None] * N
    for i in range(N):
        w_hat_bold[i] = randomMpz(secparams.q, secparams)
        w_prime_bold[i] = randomMpz(secparams.q, secparams)


    # Computing the T values:

    t_1 = gmpy2.powmod(secparams.g, w_1, secparams.p)
    t_2 = gmpy2.powmod(secparams.g, w_2, secparams.p)

    h_product = mpz(1)
    for i in range(N):
        h_product = (h_product * gmpy2.powmod(h_bold[i],w_prime_bold[i], secparams.p) ) % secparams.p

    t_3 = (gmpy2.powmod(secparams.g, w_3, secparams.p) * h_product) % secparams.p

    a_prime_i_product = mpz(1)
    for i in range(N):
        a_prime_i_product = (a_prime_i_product * gmpy2.powmod(e_prime_bold[i].a, w_prime_bold[i], secparams.p)) % secparams.p
    t_4_1 = (gmpy2.powmod(pk, -w_4, secparams.p) * a_prime_i_product) % secparams.p

    b_prime_i_product = mpz(1)
    for i in range(N):
        b_prime_i_product = (b_prime_i_product * gmpy2.powmod(e_prime_bold[i].b, w_prime_bold[i], secparams.p)) % secparams.p
    t_4_2 = (gmpy2.powmod(secparams.g, -w_4, secparams.p) * b_prime_i_product) % secparams.p

    c_hat_bold_tmp = []
    c_hat_bold_tmp.append(secparams.h)
    c_hat_bold_tmp.extend(c_hat_bold)

    t_hat_bold = [None] * N
    for i in range(N):
        t_hat_bold[i] = (gmpy2.powmod(secparams.g, w_hat_bold[i], secparams.p) * gmpy2.powmod(c_hat_bold_tmp[i], w_prime_bold[i], secparams.p) ) % secparams.p

    del c_hat_bold_tmp[0]   # remove the element c_0 that we manually inserted ???????????

    t = (t_1, t_2, t_3, (t_4_1, t_4_2), t_hat_bold)

    # Computing the challenge:
    y = (e_bold, e_prime_bold, c_bold, c_hat_bold, pk)
    c = GetNIZKPChallenge(y, t, secparams.tau, secparams)

    # Computing the S values:
    r_line = mpz(0)
    for i in range(N):
        r_line = (r_line + r_bold[i]) % secparams.q

    s_1 = mpz(0)
    for i in range(N):
        s_1 = (w_1 + c * r_line) % secparams.q

    v_bold = [None] * N
    v_bold[N-1] = mpz(1)
    for i in reversed(range(N-1)):
        v_bold[i] = (u_prime_bold[i+1] * v_bold[i+1]) % secparams.q

    r_hat = mpz(0)
    for i in range(N):
        r_hat = (r_hat + (r_hat_bold[i] * v_bold[i])) % secparams.q
    s_2 = (w_2 + c * r_hat ) % secparams.q

    r_tilde = mpz(0)
    for i in range(N):
        r_tilde = (r_tilde + (r_bold[i] * u_bold[i])) % secparams.q
    s_3 = (w_3 + c* r_tilde ) % secparams.q

    r_prime = mpz(0)
    for i in range(N):
        r_prime = (r_prime + (r_prime_bold[i] * u_bold[i])) % secparams.q
    s_4 = (w_4 + c* r_prime ) % secparams.q

    s_hat_bold = [None] * N
    s_prime_bold = [None] * N
    for i in range(N):
        s_hat_bold[i] = (w_hat_bold[i] + (c * r_hat_bold[i])) % secparams.q
        s_prime_bold[i] = (w_prime_bold[i] + (c * u_prime_bold[i])) % secparams.q

    s = (s_1, s_2, s_3, s_4, s_hat_bold, s_prime_bold)

    pi = ShuffleProof(t,s,c_bold,c_hat_bold)

    return pi
Esempio n. 19
0
 def testGetNIZKPChallenge(self):
     for i in range(100):
         c = GetNIZKPChallenge("Test", "chvote", secparams_l3.tau,
                               secparams_l3)
         AssertMpz(c)
         assert c >= 0 and c <= 2 ^ secparams_l3.tau
Esempio n. 20
0
 def publicKeyShare(self, value):
     AssertMpz(value)
     self.state.publicKeyShare = value
Esempio n. 21
0
 def secretKeyShare(self, value):
     AssertMpz(value)
     self.state.secretKeyShare = value
Esempio n. 22
0
 def publicKey(self, value):
     AssertMpz(value)
     self.state.publicKey = value