示例#1
0
    def new_reputation(self, msg_args):
        """Handles a request to add a layer of encryption to the reputations.

		Passes on the reputation to the next server at the end.

		secret: Secret for ElGamal decryption.
		reputation: The reputation ciphertext.
		server_pub_keys: A list of the server public keys so far.
		init_id: The id of the server that was the first in the ring.
		"""
        secret, rep, server_pub_keys, init_id = msg_args
        if init_id != self.server_id:
            if init_id == Constants.INIT_ID:
                init_id = self.server_id

            # encrypt client reputation
            server_pub_keys.append(self.pub_key)
            self.secret = powm(secret, self.pri_key)
            secret = (secret * powm(Constants.G, self.eph_key)) % Constants.P
            rep = (rep * self.secret) % Constants.P
            rep = self.encryptElGamal(rep, server_pub_keys)

            # pass reputation to next server
            send(self.next_addr, [
                Constants.NEW_REPUTATION, secret, rep, server_pub_keys, init_id
            ])
        else:
            send(self.ciphertext_socket, [secret, rep])
            self.ciphertext_socket.close()
示例#2
0
    def verify_signature(self, msg, stp, sig):
        """Verifies signature in message posting.

		msg: The message to verify
		stp: The public key of the user
		sig: The signature

		Returns whether the signature is valid or not.
		"""
        r, s = sig
        u = powm(self.generator, msg_hash(msg, sha1))
        v = (powm(stp, r) * powm(r, s)) % Constants.P
        return u == v
示例#3
0
def _prove_simple(sock,
                  gamma,
                  r,
                  s,
                  g=Constants.G,
                  p=Constants.P,
                  q=Constants.Q):
    assert (len(r) == len(s))
    n = len(r)

    # step 1
    t = recv(sock)

    # step 2
    r_hat = [(r[i] - t) % q for i in range(n)]
    s_hat = [(s[i] - gamma * t) % q for i in range(n)]
    theta = [0] + [randkey(0, q - 1) for _ in range(2 * n - 1)]
    Theta = []
    for i in range(2 * n):
        if i < n:
            exp = (theta[i] * r_hat[i]) % q
            exp -= (theta[i + 1] * s_hat[i]) % q
            exp %= q
            Theta.append(powm(g, exp, p))
        else:
            exp = (theta[i] * gamma) % q
            exp -= theta[(i + 1) % (2 * n)]
            exp %= q
            Theta.append(powm(g, exp, p))
    send(sock, Theta)

    # step 3
    c = recv(sock)

    # step 4
    alpha = [c]
    tmp = c
    for i in range(2 * n - 1):
        if i < n:
            tmp = (tmp * divide(r_hat[i], s_hat[i], q)) % q
            alpha.append((tmp + theta[i + 1]) % q)
        elif i == n:
            inv = modinv(gamma, q)
            tmp = (c * powm(inv, (2 * n - 1) - i, q)) % q
            alpha.append((tmp + theta[i + 1]) % q)
        else:
            tmp = (tmp * gamma) % q
            alpha.append((tmp + theta[i + 1]) % q)
    send(sock, alpha)
示例#4
0
    def post(self, msg):
        """Post a message."""
        generator = sendrecv(self.server_addr, [Constants.GET_GENERATOR])

        stp = powm(generator, self.pri_key)
        sig = self.sign(msg, generator)

        send(self.server_addr, [Constants.NEW_MESSAGE, msg, stp, sig])
示例#5
0
文件: lrs.py 项目: ianzhou1/anonrep
def sign(msg, x_i, idx, L, g=Constants.G, p=Constants.P, q=Constants.Q):
    """Signs a message using a linkable ring signature.

	msg: The message to be signed
	x_i: The private key of the signer
	idx: The index of the public key in L
	L: List of public keys

	Returns the signature.
	"""
    n = len(L)
    c = [0 for _ in range(n)]
    s = [0 for _ in range(n)]

    # step 1
    h = H2(L, g, p, q)
    t = powm(h, x_i, p)

    # step 2
    u = randkey(0, q - 1)
    c[(idx + 1) % n] = H1([L, t, msg, powm(g, u, p), powm(h, u, p)])

    # step 3
    i = (idx + 1) % n
    while i != idx:
        s[i] = randkey(0, q - 1)
        z_1 = (powm(g, s[i], p) * powm(L[i], c[i], p)) % p
        z_2 = (powm(h, s[i], p) * powm(t, c[i], p)) % p
        c[(i + 1) % n] = H1([L, t, msg, z_1, z_2])
        i = (i + 1) % n

    # step 4
    s[idx] = (u - ((x_i * c[idx]) % q)) % q

    return (c[0], s, t)
示例#6
0
    def lrs_sign(self, msg):
        """Sign for LRS."""
        generator = sendrecv(self.server_addr, [Constants.GET_GENERATOR])
        stp_array = sendrecv(self.server_addr, [Constants.GET_STP_ARRAY])
        stp = powm(generator, self.pri_key)
        stp_idx = stp_array.index(stp)

        # modify stp_array to prevent duplicate voting
        stp_array.append(msg_hash(msg, sha1))

        return lrs.sign(msg, self.pri_key, stp_idx, stp_array, g=generator)
示例#7
0
    def announcement_fwd(self, ann_list, sec_inv):
        """Encrypts pseudonyms and decrypts reputations."""
        new_ann_list = [[], []]
        for nym in ann_list[0]:
            new_nym = powm(nym, self.eph_key)
            self.nym_list[new_nym] = nym
            new_ann_list[0].append(new_nym)
        for sec, rep in ann_list[1]:
            new_rep = self.decryptElGamal(sec_inv, rep)
            new_ann_list[1].append((sec, new_rep))

        return new_ann_list
示例#8
0
文件: lrs.py 项目: ianzhou1/anonrep
def verify(msg, L, c_0, s, t, g=Constants.G, p=Constants.P, q=Constants.Q):
    """Verifies a message signed with a linkable ring signature.

	msg: The message to be signed
	L: List of public keys
	c_0, s, t: The values returned by sign()

	Returns whether the signature is valid.
	"""
    n = len(L)
    c = [0 for _ in range(n)]
    c[0] = c_0

    h = H2(L, g, p, q)

    for i in range(n):
        z_1 = (powm(g, s[i], p) * powm(L[i], c[i], p)) % p
        z_2 = (powm(h, s[i], p) * powm(t, c[i], p)) % p
        c[(i + 1) % n] = H1([L, t, msg, z_1, z_2])

    return c_0 == c[0]
示例#9
0
    def sign(self, msg, generator):
        """Sign with ElGamal signature."""
        r, s = 0, 0

        while s == 0:
            k = randkeyRP(1, Constants.P - 2)
            r = powm(generator, k)
            s = (msg_hash(msg, sha1) - self.pri_key * r) * modinv(
                k, Constants.P - 1)
            s %= Constants.P - 1

        return (r, s)
示例#10
0
    def __init__(self, server_host, server_port, private_key=None):
        self.name = 'CLIENT'

        # core variables
        self.pri_key = randkey() if private_key is None else private_key
        self.pub_key = powm(Constants.G, self.pri_key)

        # socket variables
        self.server_addr = (server_host, server_port)

        # new client
        sendrecv(self.server_addr, [Constants.NEW_CLIENT, self.pub_key])
示例#11
0
def _verify_simple(sock,
                   Gamma,
                   R,
                   S,
                   g=Constants.G,
                   p=Constants.P,
                   q=Constants.Q):
    assert (len(R) == len(S))
    n = len(R)

    # step 1
    t = randkey(0, q - 1)
    send(sock, t)

    # step 2
    Theta = recv(sock)

    # step 3
    c = randkey(0, q - 1)
    send(sock, c)

    # step 4
    alpha = recv(sock)

    # step 5
    U = powm(g, -t % q, p)
    W = powm(Gamma, -t % q, p)
    R_hat = [(R[i] * U) % p for i in range(n)]
    S_hat = [(S[i] * W) % p for i in range(n)]

    ret = True
    for i in range(2 * n):
        if i < n:
            ver = powm(R_hat[i], alpha[i], p) * powm(S_hat[i],
                                                     -alpha[i + 1] % q, p)
            ver %= p
            ret = ret and (Theta[i] == ver)
        else:
            ver = powm(Gamma, alpha[i], p) * powm(
                g, -alpha[(i + 1) % (2 * n)] % q, p)
            ver %= p
            ret = ret and (Theta[i] == ver)

    return ret
示例#12
0
    def new_announcement(self, s, msg_args):
        """Handles a request to carry out one step of the announcement phase.

		generator: Generator for this server to use.
		ann_list_pre: Announcement list before the previous server's modifications.
		ann_list_post: Announcement list after the previous server's modifications.
		g_, h_: Verifiable shuffle parameters
		init_id: The id of the server that was the first in the ring.
		"""
        generator, ann_list_pre, ann_list_post, g_, h_, init_id = msg_args
        ann_list = ann_list_post

        if init_id != self.server_id:
            if init_id == Constants.INIT_ID:
                init_id = self.server_id
                ann_list = []
                ann_list.append(list(self.ltp_list.keys()))
                ann_list.append([(self.secret, v)
                                 for v in self.ltp_list.values()])

            else:
                # verify shuffle from prev server
                if not shuffle.verify(s, ann_list_pre, ann_list_post, g_, h_):
                    eprint(self.name, 'Verifiable shuffle failed.')
                    s.close()
                    return

            s.close()

            # update announcement list
            secret_inv = modinv(powm(self.secret, self.pri_key))
            new_ann_list = self.announcement_fwd(ann_list, secret_inv)

            # shuffle announcement list
            n = len(new_ann_list[0])
            pi = shuffle.generate_permutation(n)
            new_ann_list = [shuffle.shuffle(elts, pi) for elts in new_ann_list]

            # update generator and parameters
            new_generator = powm(generator, self.eph_key)
            beta = 1
            g_ = 1
            h_ = secret_inv

            # pass announcement list to next server
            s = socket.socket()
            s.connect(self.next_addr)
            send(s, [
                Constants.NEW_ANNOUNCEMENT, new_generator, ann_list,
                new_ann_list, g_, h_, init_id
            ])

            # prove shuffle to next server (if more than one server)
            if self.addr != self.next_addr:
                shuffle.prove(s, ann_list, new_ann_list, pi, beta, g_, h_)
        else:
            # verify shuffle from prev server (if more than one server)
            if self.addr != self.prev_addr:
                if not shuffle.verify(s, ann_list_pre, ann_list_post, g_, h_):
                    eprint(self.name, 'Verifiable shuffle failed.')
                    s.close()
                    return

            s.close()

            # initialize add announcement
            stp_list = list(zip(ann_list[0],
                                [rep for sec, rep in ann_list[1]]))
            stp_args = [stp_list, generator, Constants.INIT_ID]
            self.replace_stp(stp_args)
示例#13
0
    def __init__(self, host, port):
        self.name = 'SERVER'

        # identification
        self.server_id = Constants.INIT_ID
        self.prev_addr = None
        self.next_addr = None
        self.secret = None
        self.client_rep = None

        # core variables
        self.eph_key = randkey()
        self.pri_key = randkey()
        self.pub_key = powm(Constants.G, self.pri_key)
        self.secret = None  # secret used for encryption/decryption
        self.ltp_list = {
        }  # long-term pseudonyms and encrypted reputation scores
        self.stp_list = {
        }  # short-term pseudonyms and decrypted reputation scores
        self.stp_array = []  # short-term pseudonym array
        self.generator = None  # round-based global generator
        self.nym_list = {}  # pseudonym list used for decryption
        self.lrs_duplicates = set()  # duplicate feedback set

        # socket variables
        self.addr = (host, port)
        self.ss = socket.socket()
        self.ss.bind(self.addr)
        self.ss.listen(5)
        self.server_started = False

        send(config.COORDINATOR_ADDR,
             [Constants.NEW_SERVER, self.addr, self.pub_key])

        # respond dict for received messages
        self.respond = {
            Constants.NEW_CLIENT: self.new_client,
            Constants.NEW_REPUTATION: self.new_reputation,
            Constants.NEW_ANNOUNCEMENT: self.new_announcement,
            Constants.REPLACE_STP: self.replace_stp,
            Constants.NEW_MESSAGE: self.new_message,
            Constants.NEW_FEEDBACK: self.new_feedback,
            Constants.REV_ANNOUNCEMENT: self.rev_announcement,
            Constants.REPLACE_LTP: self.replace_ltp,
            Constants.UPDATE_ID: self.update_id,
            Constants.UPDATE_NEIGHBORS: self.update_neighbors,
            Constants.GET_GENERATOR: self.get_generator,
            Constants.GET_STP_ARRAY: self.get_stp_array,
            Constants.GET_CIPHERTEXTS: self.get_ciphertexts,
            Constants.GET_CLIENTS: self.get_clients,
            Constants.UPDATE_CLIENTS: self.update_clients,
        }

        # message type dict for received messages
        self.msg_types = {
            Constants.NEW_CLIENT: [int],
            Constants.NEW_REPUTATION: [int, int, list, int],
            Constants.NEW_ANNOUNCEMENT: [int, list, list, int, int, int],
            Constants.REPLACE_STP: [list, int, int],
            Constants.NEW_MESSAGE: [str, int, list],
            Constants.NEW_FEEDBACK: [int, str, int, list],
            Constants.REV_ANNOUNCEMENT: [int, list, list, list, int, int, int],
            Constants.REPLACE_LTP: [list, int, int],
            Constants.UPDATE_ID: [int],
            Constants.UPDATE_NEIGHBORS: [list, list],
            Constants.GET_GENERATOR: [],
            Constants.GET_STP_ARRAY: [],
            Constants.GET_CIPHERTEXTS: [],
            Constants.GET_CLIENTS: [],
            Constants.UPDATE_CLIENTS: [int, int, list],
        }

        assert set(self.respond.keys()) == set(self.msg_types.keys())
示例#14
0
文件: lrs.py 项目: ianzhou1/anonrep
def H2(msg, g, p, q):
    """Hash function 2."""
    val = H1(msg) % q
    return powm(g, val, p)
示例#15
0
def verify(sock,
           elts_pre,
           elts_post,
           g_,
           h_,
           g=Constants.G,
           p=Constants.P,
           q=Constants.Q):
    """Verify a zero-knowledge proof for the verifiable shuffle.

	sock: Socket to send messages through
	elts_pre: Elements before cryptographic operation
	elts_post: Elements after cryptographic operation
	g_, h_: Verifiable shuffle parameters
	"""
    nym_pre = elts_pre[0]
    nym_post = elts_post[0]
    XY_pre = elts_pre[1]
    XY_post = elts_post[1]

    assert (len(nym_pre) == len(nym_post))
    assert (len(XY_pre) == len(XY_post))
    assert (len(nym_pre) == len(XY_pre))
    n = len(nym_pre)

    # step 1
    A, C, U, W, Gamma, Lambda_1, Lambda_2 = recv(sock)

    # step 2
    rho = [randkey(0, q - 1) for _ in range(n)]
    B = [divide(powm(g, rho[i], p), U[i], p) for i in range(n)]
    send(sock, rho)

    # step 3
    D = recv(sock)

    # step 4
    lam = randkey(0, q - 1)
    send(sock, lam)

    # step 5
    tau, sigma = recv(sock)

    # step 6
    R = [(A[i] * powm(B[i], lam, p)) % p for i in range(n)]
    S = [(C[i] * powm(D[i], lam, p)) % p for i in range(n)]
    ret = _verify_simple(sock, Gamma, R, S, g, p, q)

    # step 7
    Phi_1 = 1
    Phi_2 = 1
    for i in range(n):
        X_i, Y_i = XY_pre[i]
        X_ibar, Y_ibar = XY_post[i]
        Phi_1 = (Phi_1 * powm(X_ibar, sigma[i], p) *
                 powm(X_i, -rho[i] % q, p)) % p
        Phi_2 = (Phi_2 * powm(Y_ibar, sigma[i], p) *
                 powm(Y_i, -rho[i] % q, p)) % p

    for i in range(n):
        ret = ret and (powm(Gamma, sigma[i], p) == (W[i] * D[i]) % p)

    ret = ret and (Phi_1 == (Lambda_1 * powm(g_, tau, p)) % p)
    ret = ret and (Phi_2 == (Lambda_2 * powm(h_, tau, p)) % p)

    return ret
示例#16
0
    def rev_announcement(self, s, msg_args):
        """Handles doing a reverse announcement.

		secret: Secret for ElGamal decryption.
		server_pub_keys: Public keys of servers.
		ann_list_pre: Announcement list before the previous server's modifications.
		ann_list_post: Announcement list after the previous server's modifications.
		g_, h_: Verifiable shuffle parameters
		init_id: The id of the server that was the first in the ring.
		"""
        (secret, server_pub_keys, ann_list_pre, ann_list_post, g_, h_,
         init_id) = msg_args
        ann_list = ann_list_post

        if init_id != self.server_id:
            if init_id == Constants.INIT_ID:
                init_id = self.server_id
                ann_list = []
                ann_list.append([k for k in self.stp_list.keys()])
                ann_list.append([(secret, v) for v in self.stp_list.values()])
            else:
                # verify shuffle from prev server
                if not shuffle.verify(s, ann_list_pre, ann_list_post, g_, h_):
                    eprint(self.name, 'Verifiable shuffle failed.')
                    s.close()
                    return

            s.close()

            self.eph_key = randkey()

            # update announcement list
            server_pub_keys.append(self.pub_key)
            self.secret = powm(secret, self.pri_key)
            secret = (secret * powm(Constants.G, self.eph_key)) % Constants.P
            ann_list[1] = [(sec, (rep * self.secret) % Constants.P)
                           for sec, rep in ann_list[1]]
            new_ann_list = self.announcement_bwd(ann_list, secret,
                                                 server_pub_keys)

            # shuffle announcement list
            n = len(new_ann_list[0])
            pi = shuffle.generate_permutation(n)
            new_ann_list = [shuffle.shuffle(elts, pi) for elts in new_ann_list]

            # update parameters
            beta = self.eph_key
            g_ = Constants.G
            h_ = 1
            for server_pub_key in server_pub_keys:
                h_ = (h_ * server_pub_key) % Constants.P

            # pass announcement list to next server
            s = socket.socket()
            s.connect(self.prev_addr)
            send(s, [
                Constants.REV_ANNOUNCEMENT, secret, server_pub_keys, ann_list,
                new_ann_list, g_, h_, init_id
            ])

            # prove shuffle to prev server
            if self.addr != self.prev_addr:
                shuffle.prove(s, ann_list, new_ann_list, pi, beta, g_, h_)
        else:
            # verify shuffle from next server (if more than one server)
            if self.addr != self.next_addr:
                if not shuffle.verify(s, ann_list_pre, ann_list_post, g_, h_):
                    eprint(self.name, 'Verifiable shuffle failed.')
                    s.close()
                    return

            s.close()

            # initialize add announcement
            ltp_list = list(zip(ann_list[0],
                                [rep for sec, rep in ann_list[1]]))
            ann_args = [ltp_list, secret, Constants.INIT_ID]
            self.replace_ltp(ann_args)
示例#17
0
    def encryptElGamal(self, rep, server_pub_keys):
        """ElGamal encryption of rep using server_pub_keys."""
        for server_pub_key in server_pub_keys:
            rep = (rep * powm(server_pub_key, self.eph_key)) % Constants.P

        return rep
示例#18
0
def prove(sock,
          elts_pre,
          elts_post,
          pi,
          beta,
          g_,
          h_,
          g=Constants.G,
          p=Constants.P,
          q=Constants.Q):
    """Generate a zero-knowledge proof for the verifiable shuffle.

	sock: Socket to send messages through
	elts_pre: Elements before cryptographic operation
	elts_post: Elements after cryptographic operation
	pi: Permutation list
	beta, g_, h_: Verifiable shuffle parameters
	"""
    nym_pre = elts_pre[0]
    nym_post = elts_post[0]
    XY_pre = elts_pre[1]
    XY_post = elts_post[1]

    assert (len(nym_pre) == len(nym_post))
    assert (len(XY_pre) == len(XY_post))
    assert (len(nym_pre) == len(XY_pre))
    n = len(nym_pre)
    pi_inv = [_ for _ in range(n)]
    for i in range(n):
        pi_inv[pi[i]] = i

    # step 1
    a = [randkey(0, q - 1) for _ in range(n)]
    u = [randkey(0, q - 1) for _ in range(n)]
    w = [randkey(0, q - 1) for _ in range(n)]
    tau_0 = randkey(0, q - 1)
    gamma = randkey(1, q - 1)

    Gamma = powm(g, gamma, p)
    A = [powm(g, a[i], p) for i in range(n)]
    C = [powm(A[pi[i]], gamma, p) for i in range(n)]
    U = [powm(g, u[i], p) for i in range(n)]
    W = [powm(g, gamma * w[i], p) for i in range(n)]
    Lambda_1 = powm(g_, tau_0 + sum([(w[i] * beta) % q for i in range(n)]), p)
    Lambda_2 = powm(h_, tau_0 + sum([(w[i] * beta) % q for i in range(n)]), p)
    for i in range(n):
        X_i, Y_i = XY_pre[i]
        Lambda_1 = (Lambda_1 * powm(X_i, (w[pi_inv[i]] - u[i]) % q, p)) % p
        Lambda_2 = (Lambda_2 * powm(Y_i, (w[pi_inv[i]] - u[i]) % q, p)) % p
    send(sock, [A, C, U, W, Gamma, Lambda_1, Lambda_2])

    # step 2
    rho = recv(sock)

    # step 3
    b = [(rho[i] - u[i]) % q for i in range(n)]
    d = [(gamma * b[pi[i]]) % q for i in range(n)]
    D = [powm(g, d[i], p) for i in range(n)]
    send(sock, D)

    # step 4
    lam = recv(sock)

    # step 5
    r = [(a[i] + lam * b[i]) % q for i in range(n)]
    s = [(gamma * r[pi[i]]) % q for i in range(n)]
    sigma = [(w[i] + b[pi[i]]) % q for i in range(n)]
    tau = (-tau_0 + sum([(b[i] * beta) % q for i in range(n)])) % q
    send(sock, [tau, sigma])

    # step 6
    _prove_simple(sock, gamma, r, s, g, p, q)