public EncryptedHand requestDecryptHand(EncryptedHand encHand,
			final User usr) throws InvalidSubscriptionException, IOException,
			InterruptedException {

		final Subscription encSub = elvin.subscribe(NOT_TYPE + " == '"
				+ DECRYPT_HAND_REPLY + "' && " + GAME_ID + " == '"
				+ gameHost.getID() + "' && " + REQ_USER + " == '"
				+ user.getID() + "'");
		Notification not;
		encryptedHand = null;

		encSub.addListener(new NotificationListener() {
			public void notificationReceived(NotificationEvent e) {

				System.out
						.println("Got reply from requesting user to decrypt hand.");

				byte[] tmpBytes = (byte[]) e.notification.get(ENCRYPTED_HAND);

				try {
					encryptedHand = (EncryptedHand) Passable
							.readObject(tmpBytes);
					if (!sigServ.validateSignature(encryptedHand,
							usr.getPublicKey())) {
						// sig failed!
						callCheat(SIGNATURE_FAILED);
						System.exit(0);
					}
				} catch (Exception e1) {
					shutdown();
					System.exit(0);
				}

				synchronized (encSub) {
					encSub.notify();
				}

			}
		});

		not = new Notification();
		not.set(NOT_TYPE, DECRYPT_HAND_REQUEST);
		not.set(GAME_ID, gameHost.getID());
		not.set(SOURCE_USER, user.getID());
		not.set(REQ_USER, usr.getID());
		not.set(ENCRYPTED_HAND, encHand.writeObject());

		synchronized (encSub) {
			elvin.send(not);
			// wait until received reply
			encSub.wait();
		}

		encSub.remove();

		return encryptedHand;
	}