gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r24524 - in gnunet-java: . doc src/org/gnunet/construct src


From: gnunet
Subject: [GNUnet-SVN] r24524 - in gnunet-java: . doc src/org/gnunet/construct src/org/gnunet/construct/parsers src/org/gnunet/mesh src/org/gnunet/testing src/org/gnunet/util src/org/gnunet/voting src/org/grothoff test/org/gnunet/dht test/org/gnunet/mesh test/org/gnunet/statistics test/org/gnunet/testing test/org/gnunet/util
Date: Thu, 25 Oct 2012 02:18:02 +0200

Author: dold
Date: 2012-10-25 02:18:02 +0200 (Thu, 25 Oct 2012)
New Revision: 24524

Added:
   gnunet-java/src/org/gnunet/mesh/LocalAckMessage.java
   gnunet-java/src/org/gnunet/mesh/MeshRunabout.java
   gnunet-java/src/org/gnunet/mesh/MulticastMessage.java
   gnunet-java/src/org/gnunet/mesh/OriginMessage.java
   gnunet-java/src/org/gnunet/mesh/UnicastMessage.java
   gnunet-java/src/org/gnunet/voting/BogusAuthority.java
   gnunet-java/src/org/gnunet/voting/CallForVoters.java
   gnunet-java/src/org/gnunet/voting/ElectionSupervisor.java
   gnunet-java/src/org/gnunet/voting/GroupPublicKey.java
   gnunet-java/src/org/gnunet/voting/TallyKeyShare.java
   gnunet-java/src/org/gnunet/voting/TransmitShareVerification.java
   gnunet-java/src/org/gnunet/voting/Voter.java
Removed:
   gnunet-java/src/org/gnunet/voting/FullPublicKey.java
   gnunet-java/src/org/gnunet/voting/ShareVerification.java
   gnunet-java/src/org/gnunet/voting/SpecializedKeyShare.java
   gnunet-java/src/org/gnunet/voting/VotingAlgorithm.java
   gnunet-java/test/org/gnunet/util/MeshTest.java
Modified:
   gnunet-java/ISSUES
   gnunet-java/doc/voting.pdf
   gnunet-java/doc/voting.tex
   gnunet-java/src/org/gnunet/construct/MessageLoader.java
   gnunet-java/src/org/gnunet/construct/MsgMap.txt
   gnunet-java/src/org/gnunet/construct/parsers/FixedSizeIntegerArrayParser.java
   gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
   gnunet-java/src/org/gnunet/mesh/ClientConnectMessage.java
   gnunet-java/src/org/gnunet/mesh/Mesh.java
   gnunet-java/src/org/gnunet/mesh/TunnelCreateMessage.java
   gnunet-java/src/org/gnunet/testing/TestingSubsystem.java
   gnunet-java/src/org/gnunet/util/Client.java
   gnunet-java/src/org/gnunet/util/Configuration.java
   gnunet-java/src/org/gnunet/util/Connection.java
   gnunet-java/src/org/gnunet/util/PeerIdentity.java
   gnunet-java/src/org/gnunet/util/Server.java
   gnunet-java/src/org/gnunet/util/Service.java
   gnunet-java/src/org/gnunet/voting/Authority.java
   gnunet-java/src/org/gnunet/voting/Ballot.java
   gnunet-java/src/org/gnunet/voting/VotingSimulation.java
   gnunet-java/src/org/grothoff/Runabout.java
   gnunet-java/test/org/gnunet/dht/DHTTest.java
   gnunet-java/test/org/gnunet/mesh/MeshTest.java
   gnunet-java/test/org/gnunet/statistics/StatisticsTest.java
   gnunet-java/test/org/gnunet/testing/TestingSetupTest.java
Log:
updated voting, continued mesh implementation

Modified: gnunet-java/ISSUES
===================================================================
--- gnunet-java/ISSUES  2012-10-24 21:32:21 UTC (rev 24523)
+++ gnunet-java/ISSUES  2012-10-25 00:18:02 UTC (rev 24524)
@@ -1,48 +1,93 @@
 
+* in a real network:
+ * what do we do if an authority is not responsive during key generation?
+ * there's no way to prove that to other authorities
+ * maybe send a "i tried to send message <msg> to authority n, it didn't work, 
please try yourself"
+   to the other authorities
+ * => if it works, great, if it doesn't, other authorities are convinced that 
the offending authority is down
 
-* the voting protocol needs a broadcast channel with memory, mesh does not 
really do this
- * so the bulletin board is implemented by the authorities
+ * numbering authorities:
+  * non-participating authority's pubkey is g^0 = 1
+  * what if the voting supervisor sends the authorities fake numbers?
+   * e.g. authority A_1 gets another numbering than A_2
+   * authorities should just check with each other
 
-* in general, what are the necessary communication patterns?
- * a clients asks all authorities to
-  * accept a vote
-  * show the election status
-  * hand out e.g. the one-purpose-key for encryption of the final tally
+ * complaints:
+  * during key share verification
+   * offending authorities are excluded by the cooperating peers
+  * reporting the pubkey to the supervisor
+  * during vote casting
+   * voter should be notified
+  * during tally counting
 
-questions:
- * how do the authorities know the voter sent them the same votes?
-  * in a naive implementation, after only one vote, Theta(n^2) messages have 
to be exchanged
- * => probably have to exchange their information
- * is it really necessary for the voter to check all authorities?
 
-=> how about a separate realization / abstraction of the bulletin board?
- * the voter only has to query one authority (values should be signed by 
multiple authorities)
- * the voter only has to send her vote to one authority
- * ... and it is thus less complex for the authorities to register the unique 
vote
+* documentation: how should I describe the whole voting process?
 
+* next step in the implementation: signing
+* what should we use for signing by the authorities?
+ * gnunet uses RSA-2048 (?), probably makes sense to use the same here
 
-* the implementation is (hopefully) much more readable by now
- * suggestions?
+* there are approx. 4-5 different kinds of more or less publicly available 
keys, we should agree on a terminology
+ * sigma_i
+ * w_i : TallyKey
+ * h_i
+ * h : group pubkey
+ * authority pubkey for signatures
 
 
-how does the process of voting work?
- * a single party (the election initiator) should create the election, with a 
description
- * the initiator creates certificates that allows someone to act as an 
authority
-  * generally, we don't want just anybody to be able to be a authority, as one 
could just contribute enough authorities
-    to break the threshold
- * the initiator creates certificates for the voters
- * what are use-cases where this does not work?
- * when has an election ended? a point in time?
+* why is the commitment to the *public* key even necessary?
 
+* style question: punctuation and displayed equations
 
-one realistic use case of electronic voting would be the german e-petition 
https://epetitionen.bundestag.de/
+-----------------------------------------------------------------
 
 
+* coverty
+ * there will be many unread field warnings for the construct messages
 
 
------------------------------------------------------
 
+* what is pogen.sh, and why do I have to run it sometimes / why doesn't make 
do this?
 
-* why is the commitment to the *public* key even necessary?
+* next steps in the simulation?
+ * probably switch from the synchronous implementation to async
+  * use mesh right away? or a simpler communication simulation, based on 
scheduler
 
-* style question: punctuation and displayed equations
+* how's the progress in testbed/testing?
+
+* peer vs user:
+ * authority should be a peer (as an authority has to be reachable in the 
network)
+ * i don't see any reason for the voter to be a peer
+  * only has to send ballot to an authority *somehow*, can be mesh, web 
interface, ...
+
+* about the ballot dissemination:
+ * 
http://redlinernotes.com/docs/Classics/Epidemic%20Algorithms%20for%20Replicated%20Database%20Maintenance.pdf
+   (Epidemic algorithms for replicated database maintenance)
+   turned out to be the most useful of the papers
+ * rumor mongering
+  * new votes are "hot" (=being spread) until enough other authorities already 
know about it
+ * anti-entropy => randomly selected pair of authorities resoves their 
differences
+  * optimization: recent-update list gets sent first, then only hash is 
compared
+  * used to keep rumor mongering going
+ * after voting period:
+   * naive solution: anti-entropy has to be executed for all authority pairs
+   * probably better:
+    * a few authorities pull all votes
+    * ... and distribute them.
+    * could use signatures, so only one authority has to collect all ballots
+     * receivers of the collected ballots only check signatures, no more 
communication costs
+ * will be challenging to select and test the right parameters
+
+
+* discuss PKIs
+ * I don't really know where to start there
+ * ePA would be quite interesing, but again, where to start?
+ * WoT:
+  * GPG itself has no API, but there's 
http://www.gnupg.org/related_software/gpgme/
+ * whole PKI in java http://www.ejbca.org/download.html
+
+
+* problem with statistics_watch unit case
+ * service does not respond to restart! it should be killed afer a timeout ...
+ * otherwise we can't simulate failure
+

Modified: gnunet-java/doc/voting.pdf
===================================================================
(Binary files differ)

Modified: gnunet-java/doc/voting.tex
===================================================================
--- gnunet-java/doc/voting.tex  2012-10-24 21:32:21 UTC (rev 24523)
+++ gnunet-java/doc/voting.tex  2012-10-25 00:18:02 UTC (rev 24524)
@@ -36,24 +36,24 @@
   \item Let $x := \sum_{i=1}^{n} x_i$ be the private key. Note that no single 
authority should be able to know $x$.
   \item Every authority $A_i$ chooses a random $x_i \in \ZZ_q$, and publishes 
$h_i := g^{x_i}$.
   \item Let $h := g^{x}$ is the public key, which can be computed as $h = 
\prod_{i=1}^{n} h_i$.
-  \item Every authority $P_i$ generates the random polynomial
+  \item Every authority $A_i$ generates the random polynomial
     \begin{equation}
       f_i(z) = \sum_{l=0}^{k-1} f_{i,l}^{l},
     \end{equation}
     with $f_i(z) \in \ZZ_q[z]$, where $f_{i,0} = 0$ and $f_{i,l} \in \ZZ_q$ is 
chosen randomly for $l \ne 0$.
     It follows by definition that $f_i(0) = x_i$.
-  \item Every authority $P_i$ publishes $(F_{i,l})_{l=1,\dots,k-1}$, where 
+  \item Every authority $A_i$ publishes $(F_{i,l})_{l=1,\dots,k-1}$, where 
     \begin{equation}
       F_{i,l} = g^{f_{i,l}}
     \end{equation} 
     is the commitment of authority $A_j$ to the value of $f_{i,l}$.
-  \item Now every authority $P_i$ secretly sends
+  \item Now every authority $A_i$ secretly sends
     \begin{equation} \label{eq:sendshares}
       s_{i,j} = f_i(j)
     \end{equation} 
-    to each authority $P_j$.
+    to each authority $A_j$.
   \item \todo{Do we need to prove the consistency? Doesn't it just follow from 
the fact that it is the same computation, only in the exponent of $g$?}
-    $P_i$ verifies the share received from $P_j$ is consistent with the 
previously published values by
+    $A_i$ verifies the share received from $A_j$ is consistent with the 
previously published values by
     verifying that
     \begin{equation}
       g^{s_{i,j}} = \prod_{l=0}^{k-1} F_{jl}^{(i^l)}.
@@ -61,7 +61,7 @@
     This equation follows directly from raising $g$ to both
     sides of equation \eqref{eq:sendshares}.
   \todo{I think it should be illustrated why this works / what happens with 
the polynomials}
-  \item $P_i$ computes his share of $x$ as $s_i = \sum_{j=1}^n s_{ji}$.
+  \item $A_i$ computes his share of $x$ as $s_i = \sum_{j=1}^n s_{ji}$.
   \item Each authority $A_i$ publishes
     \begin{equation}
       \sigma_i := g^{s_i}
@@ -72,17 +72,17 @@
 
 \section{Cooperative Decryption}
 \begin{itemize}
-  \item The full private key can be restored by a set at least $k$ cooperating 
authorities $\Lambda \subseteq \{P_1,\dots,P_n\}$, $k \le |\Lambda|$, for 
example by using Lagrange interpolation:
+  \item The full private key can be restored by a set at least $k$ cooperating 
authorities $\Lambda \subseteq \{A_1,\dots,A_n\}$, $k \le |\Lambda|$, for 
example by using Lagrange interpolation:
     \begin{equation} \label{eq:pkey}
-      x = \sum_{P_j \in \Lambda} s_j \lambda_{j,\Lambda}
+      x = \sum_{A_j \in \Lambda} s_j \lambda_{j,\Lambda}
     \end{equation}
     where the Lagrange coefficients are
     \begin{equation}
       \lambda_{j,\Lambda} := \prod_{\substack{
-      P_l \in \Lambda \\ l \neq j} } \frac{l}{l-k}.
+      A_l \in \Lambda \\ l \neq j} } \frac{l}{l-k}.
     \end{equation}
   Note that this formula is only used for the derivation of the cooperative 
encryption process, and authorities never actually should cooperate to restore 
the public key $x$.
-  \item To decrypt an ElGamal encryption $(c_1, c_2) = (g^y, h^y m)$ of the 
message $m \in G_q$, each authority $P_j$ broadcasts $w_j = c_1^{s_j}$.
+  \item To decrypt an ElGamal encryption $(c_1, c_2) = (g^y, h^y m)$ of the 
message $m \in G_q$, each authority $A_j$ broadcasts $w_j = c_1^{s_j}$.
   \item To prove that an authority has computed $w_j$ correctly, it has to 
prove in zero-knowledge that
     \[
       s_j = \log_g \sigma_j = \log_{c_1} w_j,
@@ -90,7 +90,7 @@
     in words that $w_j$ has actually been computed with the authority's share.
   \item By raising $c_1$ to both sides of equation \eqref{eq:pkey} and then 
dividing $c_2$ by both sides, we get
     \[
-      m = c_2 / \prod_{P_j \in \Lambda} w_j^{\lambda_{j,\Lambda}}.
+      m = c_2 / \prod_{A_j \in \Lambda} w_j^{\lambda_{j,\Lambda}}.
     \]
 \end{itemize}
 

Modified: gnunet-java/src/org/gnunet/construct/MessageLoader.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/MessageLoader.java     2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/construct/MessageLoader.java     2012-10-25 
00:18:02 UTC (rev 24524)
@@ -85,10 +85,15 @@
         } catch (IOException e) {
             throw new RuntimeException("something went wrong with loading 
MsgMap.txt");
         }
+
         while (resources.hasMoreElements()) {
             loadMessageMap(resources.nextElement());
         }
 
+        if (tagmap.isEmpty()) {
+            logger.warn("message map empty");
+        }
+
     }
 
     public static void loadMessageMap(URL loc) {

Modified: gnunet-java/src/org/gnunet/construct/MsgMap.txt
===================================================================
--- gnunet-java/src/org/gnunet/construct/MsgMap.txt     2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/src/org/gnunet/construct/MsgMap.txt     2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -17,12 +17,16 @@
 org.gnunet.util.GnunetMessage$Body|142=org.gnunet.dht.ClientPutMessage
 org.gnunet.util.GnunetMessage$Body|67=org.gnunet.core.ConnectNotifyMessage
 org.gnunet.util.GnunetMessage$Body|76=org.gnunet.core.SendMessage
+org.gnunet.util.GnunetMessage$Body|286=org.gnunet.mesh.LocalAckMessage
 org.gnunet.util.GnunetMessage$Body|74=org.gnunet.core.SendMessageRequest
 org.gnunet.util.GnunetMessage$Body|75=org.gnunet.core.SendMessageReady
 org.gnunet.util.GnunetMessage$Body|153=org.gnunet.dht.MonitorStartStop
 
org.gnunet.util.GnunetMessage$Body|155=org.gnunet.dht.ClientPutConfirmationMessage
+org.gnunet.util.GnunetMessage$Body|262=org.gnunet.mesh.OriginMessage
 
org.gnunet.util.GnunetMessage$Body|323=org.gnunet.nse.NetworkSizeEstimation$UpdateMessage
+org.gnunet.util.GnunetMessage$Body|260=org.gnunet.mesh.UnicastMessage
 
org.gnunet.util.GnunetMessage$Body|321=org.gnunet.nse.NetworkSizeEstimation$StartMessage
+org.gnunet.util.GnunetMessage$Body|261=org.gnunet.mesh.MulticastMessage
 org.gnunet.util.GnunetMessage$Body|144=org.gnunet.dht.ClientGetStopMessage
 org.gnunet.util.GnunetMessage$Body|145=org.gnunet.dht.ClientResultMessage
 org.gnunet.util.GnunetMessage$Body|332=org.gnunet.peerinfo.InfoMessage
@@ -37,4 +41,4 @@
 org.gnunet.util.GnunetMessage$Body|168=org.gnunet.statistics.SetMessage
 
org.gnunet.util.GnunetMessage$Body|173=org.gnunet.statistics.WatchResponseMessage
 org.gnunet.util.GnunetMessage$Body|172=org.gnunet.statistics.WatchMessage
-# generated 2012/09/12 20:26:38
+# generated 2012/10/25 01:44:43

Modified: 
gnunet-java/src/org/gnunet/construct/parsers/FixedSizeIntegerArrayParser.java
===================================================================
--- 
gnunet-java/src/org/gnunet/construct/parsers/FixedSizeIntegerArrayParser.java   
    2012-10-24 21:32:21 UTC (rev 24523)
+++ 
gnunet-java/src/org/gnunet/construct/parsers/FixedSizeIntegerArrayParser.java   
    2012-10-25 00:18:02 UTC (rev 24524)
@@ -46,6 +46,7 @@
 
     @Override
     public int getSize(final Message srcObj) {
+        final Object arr = ReflectUtil.justGet(srcObj, targetField);
         return byteSize * elemNumber;
     }
 

Modified: gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java      
2012-10-24 21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java      
2012-10-25 00:18:02 UTC (rev 24524)
@@ -47,6 +47,11 @@
     @Override
     public int getSize(final Message src) {
         Message inner = (Message) ReflectUtil.justGet(src, targetField);
+        if (inner == null) {
+            if (optional)
+                return 0;
+            throw new AssertionError();
+        }
         return nestedParser.getSize(inner);
     }
 
@@ -85,7 +90,11 @@
 
     @Override
     public int write(final ByteBuffer dstBuf, final Message src) {
-        return nestedParser.write(dstBuf, (Message) ReflectUtil.justGet(src, 
targetField));
+        Object nestedMessage = ReflectUtil.justGet(src, targetField);
+        if (nestedMessage == null) {
+            return 0;
+        }
+        return nestedParser.write(dstBuf, (Message) nestedMessage);
     }
 
     @Override

Modified: gnunet-java/src/org/gnunet/mesh/ClientConnectMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/ClientConnectMessage.java   2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/mesh/ClientConnectMessage.java   2012-10-25 
00:18:02 UTC (rev 24524)
@@ -4,8 +4,10 @@
 import org.gnunet.util.GnunetMessage;
 
 /**
- * ...
+ * Allows a client to register with the service.
  *
+ * Direction: client -> service
+ *
  * @author Florian Dold
  */
 @UnionCase(272)
@@ -14,8 +16,14 @@
     public int applications_length;
     @UInt16
     public int types_length;
+    /**
+     * List of applications that this client claims to provide.
+     */
     @VariableSizeIntegerArray(lengthField = "applications_length", signed = 
false, bitSize = 32)
     public int[] apps_list;
+    /**
+     * Message types that this client understands.
+     */
     @VariableSizeIntegerArray(lengthField = "types_length", signed = false, 
bitSize = 16)
     public int[] types_list;
 }

Added: gnunet-java/src/org/gnunet/mesh/LocalAckMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/LocalAckMessage.java                        
        (rev 0)
+++ gnunet-java/src/org/gnunet/mesh/LocalAckMessage.java        2012-10-25 
00:18:02 UTC (rev 24524)
@@ -0,0 +1,18 @@
+package org.gnunet.mesh;
+
+import org.gnunet.construct.UInt32;
+import org.gnunet.construct.UnionCase;
+import org.gnunet.util.GnunetMessage;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
address@hidden(286)
+public class LocalAckMessage implements GnunetMessage.Body {
+    @UInt32
+    public int tid;
+    @UInt32
+    public int maxPid;
+}

Modified: gnunet-java/src/org/gnunet/mesh/Mesh.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/Mesh.java   2012-10-24 21:32:21 UTC (rev 
24523)
+++ gnunet-java/src/org/gnunet/mesh/Mesh.java   2012-10-25 00:18:02 UTC (rev 
24524)
@@ -21,6 +21,7 @@
 package org.gnunet.mesh;
 
 import com.google.common.collect.Maps;
+import org.gnunet.construct.Construct;
 import org.gnunet.requests.Request;
 import org.gnunet.requests.RequestQueue;
 import org.gnunet.util.*;
@@ -39,26 +40,28 @@
     private static final Logger logger = LoggerFactory
             .getLogger(Mesh.class);
 
+
     private static final int INITIAL_WINDOW_SIZE = 8;
     private static final int ACK_THRESHOLD = INITIAL_WINDOW_SIZE / 2;
 
-
-
     private RequestQueue requestQueue;
     private TunnelEndHandler tunnelEndHandler;
-    private Runabout messageReceiver;
+    private MeshRunabout messageReceiver;
     private int[] applications;
     private InboundTunnelHandler inboundTunnelHandler;
 
+    private final int LOCAL_TUNNEL_ID_CLI = 0x80000000;
+    private final int LOCAL_TUNNEL_ID_SERV = 0xB0000000;
 
-    private int nextTunnelId = 0x80000000;
+    private int nextTunnelId = LOCAL_TUNNEL_ID_CLI;
 
-    Map<Integer, RootTunnel> rootTunnelMap = Maps.newTreeMap();
+    /**
+     * Stores all tunnels created by this client, referenced by their local 
tunnel id.
+     */
+    private Map<Integer, Tunnel> tunnelMap = Maps.newTreeMap();
 
 
-    public class RootTunnel extends Tunnel {
-
-
+    public class OriginTunnel extends Tunnel {
         public DisconnectHandler disconnectHandler;
         public ConnectHandler connectHandler;
 
@@ -105,7 +108,7 @@
          * @param appType application type that must be supported by the peer
          *                 (MESH should discover peer in proximity handling 
this type)
          */
-        public void requestConnectByType (int appType) {
+        public void requestConnectByType(int appType) {
             ConnectByTypeRequest r = new ConnectByTypeRequest();
             r.appType = appType;
             requestQueue.add(r);
@@ -117,7 +120,7 @@
          *
          * @param description string describing the destination node 
requirements
          */
-        public void requestConnectByType (String description) {
+        public void requestConnectByType(String description) {
 
         }
 
@@ -127,7 +130,7 @@
          *
          * @param peer peer to add
          */
-        public void requestConnectAdd (PeerIdentity peer) {
+        public void requestConnectAdd(PeerIdentity peer) {
 
         }
 
@@ -146,14 +149,70 @@
         }
     }
 
+    public class TunnelTransmitRequest extends Request {
+
+        class Sink implements Connection.MessageSink {
+            byte[] payload;
+            @Override
+            public void send(GnunetMessage.Body m) {
+                if (payload != null) {
+                    throw new AssertionError("only one payload allowed per 
transmitter");
+                }
+                payload = Construct.toBinary(GnunetMessage.fromBody(m));
+            }
+        }
+
+        public PeerIdentity target;
+        public MessageTransmitter transmitter;
+        public Tunnel tunnel;
+
+        @Override
+        public void transmit(Connection.MessageSink sink) {
+            Sink s = new Sink();
+            transmitter.transmit(s);
+
+            if (tunnel.tunnelId >= LOCAL_TUNNEL_ID_SERV) {
+                // we are not the origin, thus can only send to origin
+                OriginMessage m = new OriginMessage();
+                m.tid = tunnel.tunnelId;
+                m.pid = tunnel.nextSentPacketId++;
+                m.payload = s.payload;
+                m.oid = new PeerIdentity();
+                m.sender = m.oid;
+                sink.send(m);
+            } else if (target == null) {
+                // multicast, we are origin
+                MulticastMessage m = new MulticastMessage();
+                m.tid = tunnel.tunnelId;
+                m.pid = tunnel.nextSentPacketId++;
+                m.payload = s.payload;
+                sink.send(m);
+            } else {
+                // unicast
+                System.out.println("sending unicast");
+                UnicastMessage m = new UnicastMessage();
+                m.destination = target;
+                m.oid = new PeerIdentity();
+                m.tid = tunnel.tunnelId;
+                m.pid = tunnel.nextSentPacketId++;
+                m.payload = s.payload;
+                sink.send(m);
+            }
+
+
+        }
+    }
+
     public class Tunnel {
-        int tunnelId;
+        protected int tunnelId;
 
-        int nextSentPacketId = 0;
-        int maxSentPacketId = INITIAL_WINDOW_SIZE - 1;
-        int lastRecvPacketId = -1;
-        int maxRecvPacketId = 0;
+        private int nextSentPacketId = 0;
+        private int maxSentPacketId = INITIAL_WINDOW_SIZE - 1;
+        private int lastRecvPacketId = -1;
+        private int maxRecvPacketId = 0;
 
+        private TunnelTransmitRequest waitingTunnelTransmitRequest;
+
         /**
          * Ask the mesh to call "notify" once it is ready to transmit the
          * given number of bytes to the specified tunnel or target.
@@ -173,19 +232,51 @@
          *         memory); if NULL is returned, "notify" will NOT be called.
          */
         public Cancelable notifyTransmitReady(RelativeTime maxdelay, 
PeerIdentity target, int notify_size, MessageTransmitter transmitter) {
-            return null;
+
+            final TunnelTransmitRequest request = new TunnelTransmitRequest();
+            request.target = target;
+            request.transmitter = transmitter;
+            request.tunnel = this;
+            request.setDeadline(maxdelay.toAbsolute());
+
+            if (nextSentPacketId <= maxSentPacketId) {
+                final Cancelable cancel = requestQueue.add(request);
+
+                return new Cancelable() {
+                    @Override
+                    public void cancel() {
+                        cancel.cancel();
+                    }
+                };
+            } else {
+                // we have to wait until we get a local ack from the service
+                waitingTunnelTransmitRequest = request;
+
+                return new Cancelable() {
+                    @Override
+                    public void cancel() {
+                        if (waitingTunnelTransmitRequest == request) {
+                            waitingTunnelTransmitRequest = null;
+                        }
+                    }
+                };
+            }
         }
 
         public void destroy() {
-            // ...
+            // todo
         }
-
     }
 
 
+    /**
+     * A request to initialize the connection with the mesh service.
+     */
     public class ClientConnectRequest extends Request {
         @Override
         public void transmit(Connection.MessageSink sink) {
+            System.out.println("transmit called " + this);
+
             ClientConnectMessage ccm = new ClientConnectMessage();
             ccm.applications_length = applications.length;
             ccm.apps_list = applications;
@@ -203,9 +294,9 @@
     }
 
     public static class TunnelCreateRequest extends Request {
-        public RootTunnel tunnel;
+        public OriginTunnel tunnel;
 
-        public TunnelCreateRequest(RootTunnel rootTunnel) {
+        public TunnelCreateRequest(OriginTunnel rootTunnel) {
             tunnel = rootTunnel;
         }
 
@@ -220,16 +311,49 @@
 
     private class MeshMessageReceiver extends RunaboutMessageReceiver {
         public void visit(PeerAdd b) {
-            RootTunnel r = rootTunnelMap.get(b.tunnelId);
-            if (r == null) {
-                logger.warn("server got confused with tunnel IDs, ignoring 
message");
+            Tunnel r = tunnelMap.get(b.tunnelId);
+            if (r == null || !(r instanceof OriginTunnel)) {
+                logger.warn("server got confused with tunnel IDs on peer add, 
ignoring message");
                 return;
             }
-            if (r.connectHandler != null) {
-                r.connectHandler.onConnect(r, b.peer);
+            OriginTunnel ot = (OriginTunnel) r;
+            if (ot.connectHandler != null) {
+                ot.connectHandler.onConnect(ot, b.peer);
             }
         }
 
+        public void visit(TunnelCreateMessage m) {
+            Tunnel t = new Tunnel();
+            t.tunnelId = m.tunnel_id;
+            if (inboundTunnelHandler != null) {
+                inboundTunnelHandler.onInboundTunnel(t, m.otherEnd);
+            }
+        }
+
+        public void visit(UnicastMessage m) {
+            messageReceiver.setSender(m.oid);
+            messageReceiver.visitAppropriate(Construct.parseAs(m.payload, 
GnunetMessage.class).body);
+        }
+
+        public void visit(MulticastMessage m) {
+            messageReceiver.setSender(m.oid);
+            messageReceiver.visitAppropriate(Construct.parseAs(m.payload, 
GnunetMessage.class).body);
+        }
+
+        public void visit(OriginMessage m) {
+            messageReceiver.setSender(m.sender);
+            messageReceiver.visitAppropriate(Construct.parseAs(m.payload, 
GnunetMessage.class).body);
+        }
+
+        public void visit(LocalAckMessage m) {
+            Tunnel t = tunnelMap.get(m.tid);
+            if (t == null) {
+                logger.warn("server got confused with tunnel IDs on ack, 
ignoring message");
+                return;
+            }
+            t.maxRecvPacketId = m.maxPid;
+        }
+
         @Override
         public void handleError() {
         }
@@ -237,7 +361,7 @@
 
 
     public Mesh(Configuration cfg, InboundTunnelHandler inboundTunnelHandler,
-                TunnelEndHandler tunnelEndHandler, Runabout messageReceiver, 
int... applications) {
+                TunnelEndHandler tunnelEndHandler, MeshRunabout 
messageReceiver, int... applications) {
         this.tunnelEndHandler = tunnelEndHandler;
         this.messageReceiver = messageReceiver;
         this.applications = applications;
@@ -253,15 +377,16 @@
      * Create a new tunnel (we're initiator and will be allowed to add/remove 
peers
      * and to broadcast).
      *
-     * @param connectHandler function to call when peers are actually connected
-     * @param disconnectHandler function to call when peers are disconnected
+     * @param connectHandler callback for when a new peer connects to the 
tunnel, either because the origin added him,
+     *                       or the client joined the tunnel
+     * @param disconnectHandler callback for when when a peer is disconnected
      */
-    public RootTunnel createTunnel(ConnectHandler connectHandler, 
DisconnectHandler disconnectHandler) {
-        RootTunnel tunnel = new RootTunnel();
+    public OriginTunnel createTunnel(ConnectHandler connectHandler, 
DisconnectHandler disconnectHandler) {
+        OriginTunnel tunnel = new OriginTunnel();
         tunnel.connectHandler = connectHandler;
         tunnel.disconnectHandler = disconnectHandler;
         tunnel.tunnelId = nextTunnelId++;
-        rootTunnelMap.put(tunnel.tunnelId, tunnel);
+        tunnelMap.put(tunnel.tunnelId, tunnel);
         tunnel.registerWithService();
         return tunnel;
     }
@@ -278,7 +403,7 @@
      * @param regex string with the regular expression describing local 
services.
      */
     public void announceRegex(String regex) {
-
+        throw new UnsupportedOperationException("not implemented");
     }
 
 

Added: gnunet-java/src/org/gnunet/mesh/MeshRunabout.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/MeshRunabout.java                           
(rev 0)
+++ gnunet-java/src/org/gnunet/mesh/MeshRunabout.java   2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -0,0 +1,19 @@
+package org.gnunet.mesh;
+
+import org.gnunet.util.PeerIdentity;
+import org.grothoff.Runabout;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class MeshRunabout extends Runabout {
+    private PeerIdentity sender;
+    /* package private */ void setSender(PeerIdentity sender) {
+        this.sender = sender;
+    }
+    public PeerIdentity getSender() {
+        return sender;
+    }
+}

Added: gnunet-java/src/org/gnunet/mesh/MulticastMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/MulticastMessage.java                       
        (rev 0)
+++ gnunet-java/src/org/gnunet/mesh/MulticastMessage.java       2012-10-25 
00:18:02 UTC (rev 24524)
@@ -0,0 +1,27 @@
+package org.gnunet.mesh;
+
+import org.gnunet.construct.*;
+import org.gnunet.util.GnunetMessage;
+import org.gnunet.util.PeerIdentity;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
address@hidden(261)
+public class MulticastMessage implements GnunetMessage.Body {
+    /**
+     * Tunnel ID
+     */
+    @UInt32
+    public int tid;
+    @UInt32
+    public int ttl;
+    @UInt32
+    public int pid;
+    @NestedMessage
+    public PeerIdentity oid;
+    @FillWith @UInt8
+    public byte[] payload;
+}

Added: gnunet-java/src/org/gnunet/mesh/OriginMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/OriginMessage.java                          
(rev 0)
+++ gnunet-java/src/org/gnunet/mesh/OriginMessage.java  2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -0,0 +1,27 @@
+package org.gnunet.mesh;
+
+import org.gnunet.construct.*;
+import org.gnunet.util.GnunetMessage;
+import org.gnunet.util.PeerIdentity;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
address@hidden(262)
+public class OriginMessage implements GnunetMessage.Body {
+    @UInt32
+    public int tid;
+    @UInt32
+    public int ttl;
+    @UInt32
+    public int pid;
+    @NestedMessage
+    public PeerIdentity oid;
+    @NestedMessage
+    public PeerIdentity sender;
+    @FillWith
+    @UInt8
+    public byte[] payload;
+}

Modified: gnunet-java/src/org/gnunet/mesh/TunnelCreateMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/TunnelCreateMessage.java    2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/mesh/TunnelCreateMessage.java    2012-10-25 
00:18:02 UTC (rev 24524)
@@ -23,8 +23,6 @@
     /**
      * Only present if sent from server to client (purpose b)
      */
-    /*
     @NestedMessage(optional = true)
     public PeerIdentity otherEnd;
-    */
 }

Added: gnunet-java/src/org/gnunet/mesh/UnicastMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/mesh/UnicastMessage.java                         
(rev 0)
+++ gnunet-java/src/org/gnunet/mesh/UnicastMessage.java 2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -0,0 +1,27 @@
+package org.gnunet.mesh;
+
+import org.gnunet.construct.*;
+import org.gnunet.util.GnunetMessage;
+import org.gnunet.util.PeerIdentity;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
address@hidden(260)
+public class UnicastMessage implements GnunetMessage.Body {
+    @UInt32
+    public int tid;
+    @UInt32
+    public int ttl;
+    @UInt32
+    public int pid;
+    @NestedMessage
+    public PeerIdentity oid;
+    @NestedMessage
+    public PeerIdentity destination;
+    @FillWith
+    @UInt8
+    public byte[] payload;
+}

Modified: gnunet-java/src/org/gnunet/testing/TestingSubsystem.java
===================================================================
--- gnunet-java/src/org/gnunet/testing/TestingSubsystem.java    2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/testing/TestingSubsystem.java    2012-10-25 
00:18:02 UTC (rev 24524)
@@ -137,5 +137,6 @@
         if (response == null || !response.equals("restarted")) {
             throw new TestingSetup.SetupException("wrapper did not cooperate");
         }
+        logger.debug("restart successful");
     }
 }

Modified: gnunet-java/src/org/gnunet/util/Client.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Client.java 2012-10-24 21:32:21 UTC (rev 
24523)
+++ gnunet-java/src/org/gnunet/util/Client.java 2012-10-25 00:18:02 UTC (rev 
24524)
@@ -19,6 +19,7 @@
  */
 package org.gnunet.util;
 
+import com.google.common.base.Optional;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -93,9 +94,10 @@
         }
 
         // get port of this service from the configuration
-        port = (int) cfg.getValueNumber(serviceName, "PORT");
+        Optional<Long> portOption = cfg.getValueNumber(serviceName, "PORT");
+        port = portOption.get().intValue();
         // get the hostname from the configuration
-        hostname = cfg.getValueString(serviceName, "HOSTNAME");
+        hostname = cfg.getValueString(serviceName, "HOSTNAME").get();
         if (hostname == null || hostname.isEmpty()) {
             throw new 
Configuration.ConfigurationException(String.format("hostname of service '%s' 
empty", serviceName));
         }

Modified: gnunet-java/src/org/gnunet/util/Configuration.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Configuration.java  2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/src/org/gnunet/util/Configuration.java  2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -21,6 +21,7 @@
 package org.gnunet.util;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
 import com.google.common.collect.HashBasedTable;
 import com.google.common.collect.Table;
 import com.google.common.io.Files;
@@ -119,21 +120,19 @@
      * @param choices list of legal values
      * @return matching value from choices
      */
-    public String getValueChoice(String section, String option,
+    public Optional<String> getValueChoice(String section, String option,
                                  Iterable<String> choices) {
-        String value = getValueString(section, option);
-        if (value == null) {
-            throw new ParsingError(String.format(
-                    "Failure in configuration section %s: value not found",
-                    section));
+        Optional<String> value = getValueString(section, option);
+        if (!value.isPresent()) {
+            return value;
         }
         for (String c : choices) {
-            if (c.equals(value)) {
+            if (c.equals(value.get())) {
                 return value;
             }
         }
-        throw new ParsingError(String.format(
-                "Failure in configuration section %s: invalid value", 
section));
+        logger.error("Failure in configuration section {}: invalid value", 
section);
+        return Optional.absent();
     }
 
 
@@ -144,18 +143,18 @@
      * @param option  option of interest
      * @return null if value not in configuration, the option's value otherwise
      */
-    public long getValueNumber(String section, String option) {
-        String num_str = getValueString(section, option);
-        if (num_str == null) {
+    public Optional<Long> getValueNumber(String section, String option) {
+        Optional<String> num_str = getValueString(section, option);
+        if (!num_str.isPresent()) {
             logSectionSources(section);
-            throw new ParsingError("Failure in configuration section "
-                    + section + " option " + option + ": value empty");
+            return Optional.absent();
         }
         try {
-            return Long.parseLong(num_str);
+            return Optional.of(Long.parseLong(num_str.get()));
         } catch (NumberFormatException e) {
-            throw new ParsingError("Failure in configuration section "
+            logger.error("Failure in configuration section "
                     + section + " option " + option + ": " + e.getMessage(), 
e);
+            return Optional.absent();
         }
     }
 
@@ -175,9 +174,11 @@
      * @param option  option of interest
      * @return value
      */
-    public String getValueString(String section, String option) {
-        ensureSectionExists(section);
-        return sections.get(section, option);
+    public Optional<String> getValueString(String section, String option) {
+        if (haveValue(section, option)) {
+            return Optional.of(sections.get(section, option));
+        }
+        return Optional.absent();
     }
 
     /**
@@ -187,28 +188,31 @@
      * @param option  option of interest
      * @return true, false, null
      */
-    public boolean getValueYesNo(String section, String option) {
-        final String v = getValueChoice(section, option,
+    public Optional<Boolean> getValueYesNo(String section, String option) {
+        final Optional<String> v = getValueChoice(section, option,
                 Arrays.asList("YES", "NO"));
-        if (v == null) {
+        if (!v.isPresent()) {
             Set<String> sources = sectionSources.get(section);
             if (sources == null) {
                 logger.info("No sources for section '{}'", section);
             } else {
                 logger.info("Sources for section '{}': {}", section, sources);
             }
-            throw new ParsingError(String.format(
+            logger.error(String.format(
                     "Failure in configuration section '%s': option '%s' not 
found",
                     section, option));
+            return Optional.absent();
         }
-        if (v.equals("YES")) {
-            return true;
+        if (v.get().equalsIgnoreCase("YES")) {
+            return Optional.of(true);
         }
-        if (v.equals("NO")) {
-            return false;
+        if (v.get().equalsIgnoreCase("NO")) {
+            return Optional.of(false);
         }
-        throw new ParsingError(
-                "Configuration error: value not recognized as YES or NO");
+
+        logger.error(String.format("Configuration error: section '%s', option 
'%s' not recognized as YES or NO", section, option));
+
+        return Optional.absent();
     }
 
     /**

Modified: gnunet-java/src/org/gnunet/util/Connection.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Connection.java     2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/src/org/gnunet/util/Connection.java     2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -249,6 +249,8 @@
                 } else {
                     schedule();
                 }
+            } else if (ctx.reasons.contains(Scheduler.Reason.SHUTDOWN)) {
+                // nothing to do!
             } else {
                 // XXX: what to do here?
                 throw new RuntimeException("receive failed");
@@ -293,6 +295,8 @@
         }
 
         public void cancel() {
+            logger.debug("canceled");
+
             if (transmitTask != null) {
                 transmitTask.cancel();
                 transmitTask = null;
@@ -312,12 +316,12 @@
             }
             try {
                 int n = connectionChannel.write(transmitBuffer);
-                logger.debug("connectionChannel has written " + n + " bytes to 
" + connectionChannel.socket().toString());
+                // logger.debug("connectionChannel has written " + n + " bytes 
to " + connectionChannel.socket().toString());
             } catch (IOException e) {
                 throw new IOError(e);
             }
             if (transmitBuffer.remaining() == 0) {
-                logger.debug("sent " + transmitBuffer.position() + "bytes 
complete message");
+                //logger.debug("sent " + transmitBuffer.position() + "bytes 
complete message");
                 if (nextTransmitHelper == null) {
                     currentTransmitHelper = null;
                 } else {
@@ -452,7 +456,12 @@
         }
     }
 
+
     private void finishConnect(SocketChannel channel) {
+        if (isConnected()) {
+            return;
+        }
+
         boolean connected;
         try {
             connected = channel.finishConnect();

Modified: gnunet-java/src/org/gnunet/util/PeerIdentity.java
===================================================================
--- gnunet-java/src/org/gnunet/util/PeerIdentity.java   2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/src/org/gnunet/util/PeerIdentity.java   2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -37,6 +37,13 @@
 
     static final String HEXES = "0123456789ABCDEF";
 
+    /**
+     * Creates a zero-filled peer identity
+     */
+    public PeerIdentity() {
+        data = new byte[64];
+    }
+
     public String getHex() {
         final StringBuilder hex = new StringBuilder( 2 * data.length );
         for (final byte b : data) {

Modified: gnunet-java/src/org/gnunet/util/Server.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Server.java 2012-10-24 21:32:21 UTC (rev 
24523)
+++ gnunet-java/src/org/gnunet/util/Server.java 2012-10-25 00:18:02 UTC (rev 
24524)
@@ -125,11 +125,6 @@
         private Connection connection;
 
         /**
-         * When do we disconnect the client after it has been idle?
-         */
-        private RelativeTime clientTimeout;
-
-        /**
          * When referenceCount==0, the server is allowed to drop the client 
after a timeout.
          */
         private int referenceCount = 0;
@@ -157,7 +152,6 @@
          */
         private ClientHandle(SocketChannel sock) {
             connection = new Connection(sock);
-            clientTimeout = idleTimeout;
             // start receiving
             receiveDone(true);
         }
@@ -254,13 +248,6 @@
         }
 
         /**
-         * Change the idle timeout of this particular client.
-         */
-        public void setTimeout(RelativeTime newTimeout) {
-            this.clientTimeout = newTimeout;
-        }
-
-        /**
          * Ask the server to disconnect from the given client.
          * <p/>
          * The client will be disconnected from the server, no matter what the 
current reference count is.

Modified: gnunet-java/src/org/gnunet/util/Service.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Service.java        2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/src/org/gnunet/util/Service.java        2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -79,9 +79,9 @@
     }
 
     public void runHook() {
-        String ip4AddrList = getConfiguration().getValueString(serviceName, 
"ACCEPT_FROM");
-        String ip6AddrList = getConfiguration().getValueString(serviceName, 
"ACCEPT_FROM6");
-        int port = (int) getConfiguration().getValueNumber(serviceName, 
"PORT");
+        String ip4AddrList = getConfiguration().getValueString(serviceName, 
"ACCEPT_FROM").get();
+        String ip6AddrList = getConfiguration().getValueString(serviceName, 
"ACCEPT_FROM6").get();
+        int port = getConfiguration().getValueNumber(serviceName, 
"PORT").get().intValue();
 
         LinkedList<SocketAddress> addrs = new LinkedList<SocketAddress>();
 

Modified: gnunet-java/src/org/gnunet/voting/Authority.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/Authority.java    2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/src/org/gnunet/voting/Authority.java    2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -1,6 +1,11 @@
 package org.gnunet.voting;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
 import java.math.BigInteger;
+import java.util.List;
+import java.util.Map;
 
 /**
  * ...
@@ -8,45 +13,45 @@
  * @author Florian Dold
  */
 public class Authority {
-    private final BigInteger privateKeyShare;
-    private final BigInteger[] secretPolynomial;
-    private final ShareVerification shareVerification;
+    private BigInteger privateKeyShare;
+    private BigInteger[] secretPolynomial;
+    private TransmitShareVerification shareVerification;
 
-    private final int authorityId;
+    private int authorityId;
 
-    private BigInteger receivedShare;
+    private BigInteger receivedShare = BigInteger.ZERO;
 
     private VotingParameters parameters;
+    private List<Authority> participatingAuthorities;
 
-    public Authority(int authorityId, VotingParameters parameters) {
-        this.authorityId = authorityId;
-        this.parameters = parameters;
-        this.privateKeyShare = parameters.generateZq();
-        this.secretPolynomial = new BigInteger[parameters.authorityThreshold];
+    private List<Ballot> ballots = Lists.newLinkedList();
 
-        this.secretPolynomial[0] = privateKeyShare;
-        for (int i = 1; i < parameters.authorityThreshold; ++i) {
-            secretPolynomial[i] = parameters.generateZq();
-        }
+    private Map<Integer, TallyKeyShare> specializedKeyShares = 
Maps.newTreeMap();
 
-        shareVerification = new ShareVerification(secretPolynomial, 
parameters);
+    private Cyphertext encryptedTally;
+    private BigInteger tallyBaseG;
 
-        receivedShare = BigInteger.ZERO;
+
+    /**
+     * The commitments of each authority to it's share of the group secret.
+     */
+    Map<Integer, BigInteger> shareCommitments = Maps.newTreeMap();
+
+    private GroupPublicKey groupPublicKey;
+
+
+    public Authority() {
     }
 
     public BigInteger getPublicKeyShare() {
         return parameters.g.modPow(privateKeyShare, parameters.p);
     }
 
-    public ShareVerification getShareVerification() {
-        return shareVerification;
-    }
-
     public BigInteger createShareForAuthority(int j) {
-        return CryptoUtil.evaluatePolynomial(secretPolynomial, 
BigInteger.valueOf(j+1), parameters.q);
+        return CryptoUtil.evaluatePolynomial(secretPolynomial, 
BigInteger.valueOf(j), parameters.q);
     }
 
-    public void verifyShare(BigInteger distributionShare, ShareVerification 
senderVerification) {
+    public void verifyShare(BigInteger distributionShare, 
TransmitShareVerification senderVerification) {
         BigInteger v = parameters.g.modPow(distributionShare, parameters.p);
         BigInteger prod = BigInteger.ONE;
         for (int l = 0; l < parameters.authorityThreshold; ++l) {
@@ -59,7 +64,7 @@
         }
     }
 
-    public void receiveShareFromAuthority(BigInteger distributionShare, 
ShareVerification senderVerification) {
+    public void acceptShareFromAuthority(BigInteger distributionShare, 
TransmitShareVerification senderVerification, Authority sender) {
         verifyShare(distributionShare, senderVerification);
         receivedShare = receivedShare.add(distributionShare);
     }
@@ -68,11 +73,194 @@
         return authorityId;
     }
 
-    public SpecializedKeyShare generateSpecializedKeyShare(Cyphertext 
encryptedTally) {
-        return new SpecializedKeyShare(encryptedTally.c1, receivedShare, 
parameters);
+    /**
+     * Supervisor -> Authority
+     *
+     * @param authorityId
+     * @param parameters
+     * @return
+     */
+    public BigInteger inviteAuthority(int authorityId, VotingParameters 
parameters) {
+        this.authorityId = authorityId;
+        this.parameters = parameters;
+
+        this.privateKeyShare = parameters.generateZq();
+        this.secretPolynomial = new BigInteger[parameters.authorityThreshold];
+
+        this.secretPolynomial[0] = privateKeyShare;
+        for (int i = 1; i < parameters.authorityThreshold; ++i) {
+            secretPolynomial[i] = parameters.generateZq();
+        }
+
+        shareVerification = new TransmitShareVerification(secretPolynomial, 
parameters);
+
+        return getPublicKeyShare();
     }
 
-    public BigInteger getSigma() {
-        return parameters.g.modPow(receivedShare, parameters.p);
+    /**
+     * Supervisor -> Authority.
+     *
+     * @param participatingAuthorities
+     */
+    public void generateKeyWithAuthorities(List<Authority> 
participatingAuthorities) {
+        this.participatingAuthorities = participatingAuthorities;
+
+        for (Authority otherAuthority : participatingAuthorities) {
+            
otherAuthority.acceptShareFromAuthority(createShareForAuthority(otherAuthority.getId()),
 shareVerification, this);
+        }
     }
+
+    public void acceptBallot(Ballot ballot) {
+        verifyBallot(ballot);
+        // todo: check duplicates
+        ballots.add(ballot);
+
+    }
+
+    public void acceptGroupPublicKey(GroupPublicKey key) {
+        groupPublicKey = key;
+    }
+
+    public void acceptSpecializedKeyShare(TallyKeyShare share, Authority 
sender) {
+        specializedKeyShares.put(sender.getId(), share);
+        verifyTallyKeyShare(share);
+    }
+
+    public void distributeTallyKey() {
+        computeEncryptedTally();
+
+        for (Authority other : participatingAuthorities) {
+            TallyKeyShare tallyKeyShare = new TallyKeyShare(encryptedTally.c1, 
receivedShare, parameters);
+            other.acceptSpecializedKeyShare(tallyKeyShare, this);
+        }
+    }
+
+    private void computeEncryptedTally() {
+        BigInteger votesX = BigInteger.ONE;
+        BigInteger votesY = BigInteger.ONE;
+        for (Ballot ballot : ballots) {
+            votesX = votesX.multiply(ballot.x).mod(parameters.p);
+            votesY = votesY.multiply(ballot.y).mod(parameters.p);
+        }
+
+        encryptedTally = new Cyphertext(votesX, votesY);
+    }
+
+    private void decryptTallyToBaseG() {
+        Map<Integer, BigInteger> lagrangeCoefficients = Maps.newTreeMap();
+        for (int j : specializedKeyShares.keySet()) {
+            BigInteger n = BigInteger.ONE;
+            BigInteger d = BigInteger.ONE;
+            for (int l : specializedKeyShares.keySet()) {
+                if (l != j) {
+                    n = n.multiply(BigInteger.valueOf(l));
+                    d = 
d.multiply(BigInteger.valueOf(l).subtract(BigInteger.valueOf(j)));
+                }
+            }
+            lagrangeCoefficients.put(j, 
n.multiply(d.modInverse(parameters.q)).mod(parameters.q));
+        }
+
+        BigInteger prod = BigInteger.ONE;
+        for (int authorityIndex : specializedKeyShares.keySet()) {
+            BigInteger wp = 
specializedKeyShares.get(authorityIndex).w.modPow(lagrangeCoefficients.get(authorityIndex),
 parameters.p);
+            prod = prod.multiply(wp).mod(parameters.p);
+        }
+
+        tallyBaseG = 
encryptedTally.c2.multiply(prod.modInverse(parameters.p)).mod(parameters.p);
+    }
+
+    public int decryptTally() {
+        decryptTallyToBaseG();
+
+        int resultRestored = 0;
+        boolean success = false;
+
+        for (int l = -ballots.size(); l <= ballots.size(); ++l) {
+            if (tallyBaseG.equals(parameters.g.modPow(BigInteger.valueOf(l), 
parameters.p))) {
+                success = true;
+                resultRestored = l;
+                break;
+            }
+        }
+
+        if (!success) {
+            throw new AssertionError();
+        }
+        return resultRestored;
+    }
+
+    /*
+    * Sigma is the the authority's commitment to its share
+    */
+    public void verifyTallyKeyShare(TallyKeyShare share) {
+        BigInteger p = parameters.p;
+        BigInteger g = parameters.g;
+
+        BigInteger c1 = share.c1;
+        BigInteger a = share.a;
+        BigInteger r = share.r;
+        BigInteger b = share.b;
+        BigInteger c = share.c;
+
+        // verifier
+        BigInteger expected1 = g.modPow(r, p);
+        BigInteger received1 = a.multiply(share.sigma.modPow(c, p)).mod(p);
+
+        BigInteger expected2 = c1.modPow(r, p);
+        BigInteger received2 = b.multiply(share.w.modPow(c, p)).mod(p);
+
+        if ((!expected1.equals(received1)) || (!expected2.equals(received2))) {
+            System.err.println(expected1);
+            System.err.println(received1);
+            throw new AssertionError("zero knowledge proof for decryption 
failed");
+        }
+    }
+
+
+
+    public void verifyBallot(Ballot ballot) {
+        BigInteger g = parameters.g;
+        BigInteger p = parameters.p;
+        BigInteger h = groupPublicKey.getKey();
+        // verifier
+
+        BigInteger voterId = ballot.voterId;
+        BigInteger x = ballot.x;
+        BigInteger y = ballot.y;
+        BigInteger a_1 = ballot.a_1;
+        BigInteger a_2 = ballot.a_2;
+        BigInteger b_1 = ballot.b_1;
+        BigInteger b_2 = ballot.b_2;
+        BigInteger c = ballot.c;
+        BigInteger d_1 = ballot.d_1;
+        BigInteger d_2 = ballot.d_2;
+        BigInteger r_1 = ballot.r_1;
+        BigInteger r_2 = ballot.r_2;
+
+
+        // todo: we should blame someone here, not throw exceptions
+
+
+        if (!c.equals(CryptoUtil.hash(voterId, x, y, a_1, b_1, a_2, 
b_2).mod(parameters.q))) {
+            throw new AssertionError();
+        }
+
+        if (!c.equals(d_1.add(d_2).mod(p))) {
+            throw new AssertionError();
+        }
+        if (!a_1.equals(g.modPow(r_1, p).multiply(x.modPow(d_1, p)).mod(p))) {
+            throw new AssertionError();
+        }
+        if (!b_1.equals(h.modPow(r_1, p).multiply(y.multiply(g).modPow(d_1, 
p)).mod(p))) {
+            throw new AssertionError();
+        }
+
+        if (!a_2.equals(g.modPow(r_2, p).multiply(x.modPow(d_2, p)).mod(p))) {
+            throw new AssertionError();
+        }
+
+        if (!b_2.equals(h.modPow(r_2, 
p).multiply(y.multiply(g.modInverse(p)).modPow(d_2, p)).mod(p))) {
+            throw new AssertionError();
+        }
+    }
 }

Modified: gnunet-java/src/org/gnunet/voting/Ballot.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/Ballot.java       2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/src/org/gnunet/voting/Ballot.java       2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -1,10 +1,6 @@
 package org.gnunet.voting;
 
-import com.google.common.base.Objects;
-
 import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 
 /**
  * ...
@@ -21,13 +17,13 @@
     private VotingParameters parameters;
 
 
-    public Ballot(boolean v, BigInteger voterId, FullPublicKey fullPublicKey, 
VotingParameters parameters) {
+    public Ballot(boolean v, BigInteger voterId, GroupPublicKey 
groupPublicKey, VotingParameters parameters) {
         this.voterId = voterId;
         this.parameters = parameters;
 
         BigInteger g = parameters.g;
         BigInteger p = parameters.p;
-        BigInteger h = fullPublicKey.getKey();
+        BigInteger h = groupPublicKey.getKey();
 
 
         if (v) {
@@ -74,10 +70,10 @@
         }
     }
 
-    public void verify(FullPublicKey fullPublicKey) {
+    public void verify(GroupPublicKey groupPublicKey) {
         BigInteger g = parameters.g;
         BigInteger p = parameters.p;
-        BigInteger h = fullPublicKey.getKey();
+        BigInteger h = groupPublicKey.getKey();
         // verifier
 
 
@@ -91,9 +87,6 @@
         if (!a_1.equals(g.modPow(r_1, p).multiply(x.modPow(d_1, p)).mod(p))) {
             throw new AssertionError();
         }
-        if (!b_1.equals(h.modPow(r_1, p).multiply(y.multiply(g).modPow(d_1, 
p)).mod(p))) {
-            throw new AssertionError();
-        }
 
         if (!a_2.equals(g.modPow(r_2, p).multiply(x.modPow(d_2, p)).mod(p))) {
             throw new AssertionError();
@@ -102,5 +95,11 @@
         if (!b_2.equals(h.modPow(r_2, 
p).multiply(y.multiply(g.modInverse(p)).modPow(d_2, p)).mod(p))) {
             throw new AssertionError();
         }
+
+        if (!b_1.equals(h.modPow(r_1, p).multiply(y.multiply(g).modPow(d_1, 
p)).mod(p))) {
+            throw new AssertionError();
+        }
+
+
     }
 }

Added: gnunet-java/src/org/gnunet/voting/BogusAuthority.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/BogusAuthority.java                       
        (rev 0)
+++ gnunet-java/src/org/gnunet/voting/BogusAuthority.java       2012-10-25 
00:18:02 UTC (rev 24524)
@@ -0,0 +1,9 @@
+package org.gnunet.voting;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class BogusAuthority extends Authority {
+}

Added: gnunet-java/src/org/gnunet/voting/CallForVoters.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/CallForVoters.java                        
        (rev 0)
+++ gnunet-java/src/org/gnunet/voting/CallForVoters.java        2012-10-25 
00:18:02 UTC (rev 24524)
@@ -0,0 +1,14 @@
+package org.gnunet.voting;
+
+import java.util.List;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class CallForVoters {
+    public List<Authority> authorities;
+    public VotingParameters parameters;
+    public GroupPublicKey publicKey;
+}

Added: gnunet-java/src/org/gnunet/voting/ElectionSupervisor.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/ElectionSupervisor.java                   
        (rev 0)
+++ gnunet-java/src/org/gnunet/voting/ElectionSupervisor.java   2012-10-25 
00:18:02 UTC (rev 24524)
@@ -0,0 +1,105 @@
+package org.gnunet.voting;
+
+import com.google.common.collect.Lists;
+
+import java.math.BigInteger;
+import java.util.List;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class ElectionSupervisor {
+    /**
+     * Accumulator for the group public key.
+     * todo: actually we should record the group publice key share of each 
authority seperately
+     */
+    private BigInteger groupPublicKeyAccum = BigInteger.ONE;
+
+    private VotingParameters parameters;
+
+    /**
+     * Authorities that will be invited for participation
+     */
+    private List<Authority> availableAuthorities;
+
+    /**
+     * Authorities that have agreed to participate.
+     */
+    private List<Authority> participatingAuthorities = Lists.newArrayList();
+
+
+
+    private enum Phase { START, INVITED, KEYS_GENERATED, PUBKEY_PUBLISHED}
+
+    private Phase currentPhase = Phase.START;
+
+
+    public ElectionSupervisor(List<Authority> availableAuthorities, 
VotingParameters parameters) {
+        this.parameters = parameters;
+        this.availableAuthorities = availableAuthorities;
+    }
+
+    /**
+     * Send an invitation to all available authorities
+     */
+    public void inviteAuthorities() {
+        if (currentPhase != Phase.START) {
+            throw new AssertionError();
+        }
+
+        int nextAuthorityNumber = 1;
+        for (Authority authority : availableAuthorities) {
+            BigInteger part = authority.inviteAuthority(nextAuthorityNumber, 
parameters);
+            nextAuthorityNumber += 1;
+            if (part != null) {
+                participatingAuthorities.add(authority);
+                groupPublicKeyAccum = 
groupPublicKeyAccum.multiply(part).mod(parameters.p);
+            }
+        }
+
+        currentPhase = Phase.INVITED;
+    }
+
+    public CallForVoters createCallForVote() {
+        if (currentPhase != Phase.PUBKEY_PUBLISHED) {
+            throw new AssertionError();
+        }
+
+        CallForVoters callForVoters = new CallForVoters();
+        callForVoters.authorities = participatingAuthorities;
+        callForVoters.parameters = parameters;
+        callForVoters.publicKey = new GroupPublicKey(groupPublicKeyAccum);
+        return callForVoters;
+
+    }
+
+
+    public void ascertainGroupPublicKey() {
+        if (currentPhase != Phase.KEYS_GENERATED) {
+            throw new AssertionError();
+        }
+
+        for (Authority authority : participatingAuthorities) {
+            authority.acceptGroupPublicKey(new 
GroupPublicKey(groupPublicKeyAccum));
+        }
+
+        currentPhase = Phase.PUBKEY_PUBLISHED;
+
+    }
+
+
+    /**
+     * Publish participating authorities of the key generation, receiving 
authorities will start the key generation.
+     */
+    public void startKeyGeneration() {
+        if (currentPhase != Phase.INVITED) {
+            throw new AssertionError();
+        }
+        for (Authority authority : participatingAuthorities) {
+            authority.generateKeyWithAuthorities(participatingAuthorities);
+        }
+        currentPhase = Phase.KEYS_GENERATED;
+    }
+}

Deleted: gnunet-java/src/org/gnunet/voting/FullPublicKey.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/FullPublicKey.java        2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/voting/FullPublicKey.java        2012-10-25 
00:18:02 UTC (rev 24524)
@@ -1,24 +0,0 @@
-package org.gnunet.voting;
-
-import java.math.BigInteger;
-
-/**
- * ...
- *
- * @author Florian Dold
- */
-public class FullPublicKey {
-    final BigInteger key;
-
-    public FullPublicKey(Authority[] authorities, VotingParameters parameters) 
{
-        BigInteger h = BigInteger.ONE;
-        for (Authority authority : authorities) {
-            h = h.multiply(authority.getPublicKeyShare()).mod(parameters.p);
-        }
-        key = h;
-    }
-
-    public BigInteger getKey() {
-        return key;
-    }
-}

Copied: gnunet-java/src/org/gnunet/voting/GroupPublicKey.java (from rev 24325, 
gnunet-java/src/org/gnunet/voting/FullPublicKey.java)
===================================================================
--- gnunet-java/src/org/gnunet/voting/GroupPublicKey.java                       
        (rev 0)
+++ gnunet-java/src/org/gnunet/voting/GroupPublicKey.java       2012-10-25 
00:18:02 UTC (rev 24524)
@@ -0,0 +1,28 @@
+package org.gnunet.voting;
+
+import java.math.BigInteger;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class GroupPublicKey {
+    final BigInteger key;
+
+    public GroupPublicKey(Authority[] authorities, VotingParameters 
parameters) {
+        BigInteger h = BigInteger.ONE;
+        for (Authority authority : authorities) {
+            h = h.multiply(authority.getPublicKeyShare()).mod(parameters.p);
+        }
+        key = h;
+    }
+
+    public GroupPublicKey(BigInteger groupPublicKey) {
+        this.key = groupPublicKey;
+    }
+
+    public BigInteger getKey() {
+        return key;
+    }
+}

Deleted: gnunet-java/src/org/gnunet/voting/ShareVerification.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/ShareVerification.java    2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/voting/ShareVerification.java    2012-10-25 
00:18:02 UTC (rev 24524)
@@ -1,18 +0,0 @@
-package org.gnunet.voting;
-
-import java.math.BigInteger;
-
-/**
- * ...
- *
- * @author Florian Dold
- */
-public class ShareVerification {
-    public final BigInteger[] coeffs;
-    public ShareVerification(BigInteger[] secretPolynomial, VotingParameters 
parameters) {
-        coeffs = new BigInteger[secretPolynomial.length];
-        for (int i = 0; i < secretPolynomial.length; ++i) {
-            coeffs[i] = parameters.g.modPow(secretPolynomial[i], parameters.p);
-        }
-    }
-}

Deleted: gnunet-java/src/org/gnunet/voting/SpecializedKeyShare.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/SpecializedKeyShare.java  2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/voting/SpecializedKeyShare.java  2012-10-25 
00:18:02 UTC (rev 24524)
@@ -1,58 +0,0 @@
-package org.gnunet.voting;
-
-import java.math.BigInteger;
-
-/**
- * ...
- *
- * @author Florian Dold
- */
-public class SpecializedKeyShare {
-    final public BigInteger specializedShare;
-
-    final public BigInteger c1;
-    final public BigInteger a, b, c, r;
-
-    final VotingParameters parameters;
-
-    public SpecializedKeyShare(BigInteger c1, BigInteger share, 
VotingParameters parameters) {
-        this.parameters = parameters;
-        this.c1 = c1;
-
-        specializedShare = c1.modPow(share, parameters.p);
-
-        BigInteger p = parameters.p;
-        BigInteger g = parameters.g;
-
-        // prover
-        BigInteger beta = parameters.generateZq();
-        a = g.modPow(beta, p);
-        b = c1.modPow(beta, p);
-        // verifier
-        c = CryptoUtil.hash(a, b);
-        // prover
-        r = beta.add(share.multiply(c));
-    }
-
-    /*
-     * Sigma is the the authority's commitment to its share
-     */
-    public void verify(BigInteger sigma) {
-        BigInteger p = parameters.p;
-        BigInteger g = parameters.g;
-
-        // verifier
-        BigInteger expected1 = g.modPow(r, p);
-        BigInteger received1 = a.multiply(sigma.modPow(c, p)).mod(p);
-
-        BigInteger expected2 = c1.modPow(r, p);
-        BigInteger received2 = b.multiply(specializedShare.modPow(c, 
p)).mod(p);
-
-        if ((!expected1.equals(received1)) || (!expected2.equals(received2))) {
-            System.err.println(expected1);
-            System.err.println(received1);
-            throw new AssertionError("zero knowledge proof for decryption 
failed");
-        }
-    }
-}
-

Copied: gnunet-java/src/org/gnunet/voting/TallyKeyShare.java (from rev 24325, 
gnunet-java/src/org/gnunet/voting/SpecializedKeyShare.java)
===================================================================
--- gnunet-java/src/org/gnunet/voting/TallyKeyShare.java                        
        (rev 0)
+++ gnunet-java/src/org/gnunet/voting/TallyKeyShare.java        2012-10-25 
00:18:02 UTC (rev 24524)
@@ -0,0 +1,41 @@
+package org.gnunet.voting;
+
+import java.math.BigInteger;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class TallyKeyShare {
+    final public BigInteger w;
+
+    final public BigInteger sigma;
+
+    final public BigInteger c1;
+    final public BigInteger a, b, c, r;
+
+    final VotingParameters parameters;
+
+    public TallyKeyShare(BigInteger c1, BigInteger share, VotingParameters 
parameters) {
+        this.parameters = parameters;
+        this.c1 = c1;
+
+        sigma = parameters.g.modPow(share, parameters.p);
+
+        w = c1.modPow(share, parameters.p);
+
+        BigInteger p = parameters.p;
+        BigInteger g = parameters.g;
+
+        // prover
+        BigInteger beta = parameters.generateZq();
+        a = g.modPow(beta, p);
+        b = c1.modPow(beta, p);
+        // verifier
+        c = CryptoUtil.hash(a, b);
+        // prover
+        r = beta.add(share.multiply(c));
+    }
+}
+

Copied: gnunet-java/src/org/gnunet/voting/TransmitShareVerification.java (from 
rev 24325, gnunet-java/src/org/gnunet/voting/ShareVerification.java)
===================================================================
--- gnunet-java/src/org/gnunet/voting/TransmitShareVerification.java            
                (rev 0)
+++ gnunet-java/src/org/gnunet/voting/TransmitShareVerification.java    
2012-10-25 00:18:02 UTC (rev 24524)
@@ -0,0 +1,18 @@
+package org.gnunet.voting;
+
+import java.math.BigInteger;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class TransmitShareVerification {
+    public final BigInteger[] coeffs;
+    public TransmitShareVerification(BigInteger[] secretPolynomial, 
VotingParameters parameters) {
+        coeffs = new BigInteger[secretPolynomial.length];
+        for (int i = 0; i < secretPolynomial.length; ++i) {
+            coeffs[i] = parameters.g.modPow(secretPolynomial[i], parameters.p);
+        }
+    }
+}

Added: gnunet-java/src/org/gnunet/voting/Voter.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/Voter.java                                
(rev 0)
+++ gnunet-java/src/org/gnunet/voting/Voter.java        2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -0,0 +1,31 @@
+package org.gnunet.voting;
+
+import java.math.BigInteger;
+
+/**
+ * ...
+ *
+ * @author Florian Dold
+ */
+public class Voter {
+    boolean b;
+    BigInteger voterId;
+    private CallForVoters callForVoters;
+
+    public Voter(CallForVoters callForVoters) {
+        b = CryptoUtil.random.nextBoolean();
+        voterId = new BigInteger(64, CryptoUtil.random);
+        this.callForVoters = callForVoters;
+    }
+
+    public Ballot generateBallot() {
+        return new Ballot(b, voterId, callForVoters.publicKey, 
callForVoters.parameters);
+    }
+
+    public void vote() {
+        Ballot ballot = generateBallot();
+        for (Authority authority : callForVoters.authorities) {
+            authority.acceptBallot(ballot);
+        }
+    }
+}

Deleted: gnunet-java/src/org/gnunet/voting/VotingAlgorithm.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/VotingAlgorithm.java      2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/voting/VotingAlgorithm.java      2012-10-25 
00:18:02 UTC (rev 24524)
@@ -1,323 +0,0 @@
-package org.gnunet.voting;
-
-import java.math.BigInteger;
-import java.util.Random;
-
-public class VotingAlgorithm {
-
-
-    public static void main(String... args) {
-        final int authorityCount = 10;
-        // minimum required number of cooperating authorities
-        final int k = 6;
-        final VotingParameters parameters = 
VotingParameters.generateRandomParameters(64, 10, authorityCount, k);
-
-        final BigInteger p = parameters.getP();
-        final BigInteger q = parameters.getQ();
-        final BigInteger g = parameters.getG();
-
-        if (!(g.compareTo(p) < 0)) {
-            throw new AssertionError();
-        }
-
-
-
-        // parts of the private key x, one part for each authority
-        BigInteger[] xParts = new BigInteger[authorityCount];
-        // The full private key, sum of the parts. Initialized with the 
additive identity.
-        BigInteger x = BigInteger.ZERO;
-
-        // parts of the public key h, one part for each authority
-        BigInteger[] hParts = new BigInteger[authorityCount];
-        // The full public key, product of the parts. Initialized with the 
multiplicative identity.
-        BigInteger h = BigInteger.ONE;
-
-        for (int j = 0; j < authorityCount; ++j) {
-            xParts[j] = parameters.generateZq();
-            hParts[j] = g.modPow(xParts[j], p);
-            x = x.add(xParts[j]).mod(q);
-            h = h.multiply(hParts[j]).mod(p);
-        }
-
-        if (!g.modPow(x, p).equals(h)) {
-            throw new AssertionError("math problem");
-        }
-
-
-        // f[j][i] is the coefficient of x^i for the polynomial of authority 
j-1.
-        BigInteger[][] f = new BigInteger[authorityCount][];
-        // checkF[j][i] = g^(f[j][i]) mod p
-        // used to check the share parts of each authority
-        BigInteger[][] checkF = new BigInteger[authorityCount][];
-
-        // generate the random polynomials
-        for (int j = 0; j < authorityCount; ++j) {
-            f[j] = new BigInteger[k];
-            checkF[j] = new BigInteger[k];
-            for (int i = 1; i < k; ++i) {
-                f[j][i] = parameters.generateZq();
-                checkF[j][i] = g.modPow(f[j][i], p);
-            }
-            f[j][0] = xParts[j];
-            checkF[j][0] = g.modPow(f[j][0], p);
-        }
-
-        // shareParts[j][i] is the polynomial f_j of authority j evaluated at i
-        // note that shareParts[j][0] is the private key part of authority j
-        BigInteger[][] shareParts = new BigInteger[authorityCount][];
-
-
-        // create the transmitted shared by evaluation the polynomials
-        for (int j = 0; j < authorityCount; ++j) {
-            shareParts[j] = new BigInteger[authorityCount];
-            for (int i = 0; i < authorityCount; ++i) {
-                shareParts[j][i] = CryptoUtil.evaluatePolynomial(f[j], 
BigInteger.valueOf(i + 1), q);
-            }
-        }
-
-
-        // verification of the received shares:
-        for (int j = 0; j < authorityCount; ++j) {
-            // P_j verifies that the shares he received are valid
-            for (int i = 0; i < authorityCount; ++i) {
-                BigInteger v = g.modPow(shareParts[i][j], p);
-                BigInteger prod = BigInteger.ONE;
-                for (int l = 0; l < k; ++l) {
-                    BigInteger exp = BigInteger.valueOf(j+1).pow(l);
-                    prod = prod.multiply(checkF[i][l].modPow(exp, p)).mod(p);
-                }
-                if (!v.equals(prod)) {
-                    throw new AssertionError("verification of transmitted 
shared failed");
-                }
-            }
-        }
-
-
-
-
-        BigInteger[] shares = new BigInteger[authorityCount];
-
-        // compute each authority's share as the sum of parts it received
-        for (int j = 0; j < authorityCount; j++) {
-            shares[j] = BigInteger.ZERO;
-            for (int i = 0; i < authorityCount; ++i) {
-                shares[j] = shares[j].add(shareParts[i][j]);
-            }
-        }
-
-
-        BigInteger[] lagrangeBase = new BigInteger[k];
-        for (int j = 1; j <= k; ++j) {
-            BigInteger n = BigInteger.ONE;
-            BigInteger d = BigInteger.ONE;
-            for (int l = 1; l <= k; ++l) {
-                if (l == j) {
-                    continue;
-                }
-                n = n.multiply(BigInteger.valueOf(l));
-                d = 
d.multiply(BigInteger.valueOf(l).subtract(BigInteger.valueOf(j)));
-            }
-            lagrangeBase[j-1] = n.multiply(d.modInverse(q)).mod(q);
-        }
-
-        BigInteger xReconstructed = BigInteger.ZERO;
-        for (int j = 0; j < k; ++j) {
-            xReconstructed = 
xReconstructed.add(shares[j].multiply(lagrangeBase[j])).mod(q);
-        }
-
-        //System.out.println(xReconstructed);
-        //System.out.println(x);
-
-        if (!g.modPow(xReconstructed, p).equals(h)) {
-            throw new AssertionError("key reconstruction failed");
-        }
-
-
-        BigInteger message = parameters.generateGq();
-        Cyphertext cyphertext = parameters.encrypt(message, h);
-        BigInteger[] w = new BigInteger[k];
-        for (int i = 0; i < k; ++i) {
-            w[i] = cyphertext.c1.modPow(shares[i], p);
-        }
-
-
-        // zero knowledge proof
-        for (int i = 0; i < k; ++i) {
-            // sigma is made public
-            BigInteger sigma = g.modPow(shares[i], p);
-            // prover
-            BigInteger beta = parameters.generateZq();
-            BigInteger a = g.modPow(beta, p);
-            BigInteger b = cyphertext.c1.modPow(beta, p);
-            // verifier
-            BigInteger c = parameters.generateZq();
-            // prover
-            BigInteger r = beta.add(shares[i].multiply(c));
-            // verifier
-            BigInteger expected1 = g.modPow(r, p);
-            BigInteger received1 =  a.multiply(sigma.modPow(c, p)).mod(p);
-
-            BigInteger expected2 = cyphertext.c1.modPow(r, p);
-            BigInteger received2 =  b.multiply(w[i].modPow(c, p)).mod(p);
-
-            if ((!expected1.equals(received1)) || 
(!expected2.equals(received2))) {
-                System.err.println(expected1);
-                System.err.println(received1);
-                throw new AssertionError("zero knowledge proof for decryption 
failed");
-            }
-        }
-
-        BigInteger messageRestored = cyphertext.c2;
-
-        for (int i = 0; i < k; ++i) {
-            BigInteger v = w[i].modPow(lagrangeBase[i], p);
-            messageRestored = messageRestored.multiply(v.modInverse(p)).mod(p);
-        }
-
-        if (!message.equals(messageRestored)) {
-            throw new AssertionError("decryption failed");
-        }
-
-
-        simulateBallotZKP1(h, parameters);
-        simulateBallotZKP2(h, parameters);
-
-        final int voteCount = 25;
-        int result = 0;
-
-        Cyphertext votes[] = new Cyphertext[voteCount];
-        for (int i = 0; i < voteCount; ++i) {
-            if (CryptoUtil.random.nextBoolean()) {
-                votes[i] = parameters.encrypt(g, h);
-                result++;
-            } else {
-                votes[i] = parameters.encrypt(g.modInverse(p), h);
-                result--;
-            }
-        }
-
-        BigInteger votesX = BigInteger.ONE;
-        BigInteger votesY = BigInteger.ONE;
-        for (int i = 0; i < voteCount; ++i) {
-            votesX = votesX.multiply(votes[i].c1).mod(p);
-            votesY = votesY.multiply(votes[i].c2).mod(p);
-        }
-
-        // for convenice decrypted with the full private key, the above tests 
demonstrates that this
-        // is equally possible without revealing the private key
-        BigInteger resultG = votesY.multiply(votesX.modPow(x, 
p).modInverse(p)).mod(p);
-        int resultRestored = 0;
-        boolean success = false;
-
-        for (int l = -voteCount; l <= voteCount; ++l) {
-            if (resultG.equals(g.modPow(BigInteger.valueOf(l), p))) {
-                success = true;
-                resultRestored = l;
-                break;
-            }
-        }
-
-        if (!success) {
-            throw new AssertionError();
-        }
-
-        if (resultRestored != result) {
-            throw new AssertionError();
-        }
-    }
-
-    public static void simulateBallotZKP1(BigInteger h, VotingParameters 
parameters) {
-        final BigInteger p = parameters.getP();
-        final BigInteger q = parameters.getQ();
-        final BigInteger g = parameters.getG();
-
-        // prover
-        BigInteger alpha = parameters.generateZq();
-        BigInteger w = parameters.generateZq();
-        BigInteger r_1 = parameters.generateZq();
-        BigInteger d_1 = parameters.generateZq();
-
-        BigInteger x = g.modPow(alpha, p);
-        BigInteger y = h.modPow(alpha, p).multiply(g).mod(p);
-
-        BigInteger a_1 = g.modPow(r_1, p).multiply(x.modPow(d_1, p)).mod(p);
-        BigInteger b_1 = h.modPow(r_1, p).multiply(y.multiply(g).modPow(d_1, 
p)).mod(p);
-        BigInteger a_2 = g.modPow(w, p);
-        BigInteger b_2 = h.modPow(w, p);
-
-        // verifier
-        BigInteger c = parameters.generateZq();
-
-        // prover
-        BigInteger d_2 = c.subtract(d_1);
-        BigInteger r_2 = w.subtract(alpha.multiply(d_2));
-
-        // verifier
-        if (!c.equals(d_1.add(d_2).mod(p))) {
-            throw new AssertionError();
-        }
-        if (!a_1.equals(g.modPow(r_1, p).multiply(x.modPow(d_1, p)).mod(p))) {
-            throw new AssertionError();
-        }
-        if (!b_1.equals(h.modPow(r_1, p).multiply(y.multiply(g).modPow(d_1, 
p)).mod(p))) {
-            throw new AssertionError();
-        }
-
-        if (!a_2.equals(g.modPow(r_2, p).multiply(x.modPow(d_2, p)).mod(p))) {
-            throw new AssertionError();
-        }
-
-        if (!b_2.equals(h.modPow(r_2, 
p).multiply(y.multiply(g.modInverse(p)).modPow(d_2, p)).mod(p))) {
-            throw new AssertionError();
-        }
-    }
-
-
-    public static void simulateBallotZKP2(BigInteger h, VotingParameters 
parameters) {
-        final BigInteger p = parameters.getP();
-        final BigInteger q = parameters.getQ();
-        final BigInteger g = parameters.getG();
-
-        // prover
-        BigInteger alpha = parameters.generateZq();
-        BigInteger w = parameters.generateZq();
-        BigInteger r_2 = parameters.generateZq();
-        BigInteger d_2 = parameters.generateZq();
-
-        BigInteger x = g.modPow(alpha, p);
-        BigInteger y = h.modPow(alpha, p).multiply(g.modInverse(p)).mod(p);
-
-        BigInteger a_1 = g.modPow(w, p);
-        BigInteger b_1 = h.modPow(w, p);
-        BigInteger a_2 = g.modPow(r_2, p).multiply(x.modPow(d_2, p)).mod(p);
-        BigInteger b_2 = h.modPow(r_2, 
p).multiply(y.multiply(g.modInverse(p)).modPow(d_2, p)).mod(p);
-
-
-        // verifier
-        BigInteger c = parameters.generateZq();
-
-        // prover
-        BigInteger d_1 = c.subtract(d_2);
-        BigInteger r_1 = w.subtract(alpha.multiply(d_1));
-
-        // verifier
-        if (!c.equals(d_1.add(d_2).mod(p))) {
-            throw new AssertionError();
-        }
-        if (!a_1.equals(g.modPow(r_1, p).multiply(x.modPow(d_1, p)).mod(p))) {
-            throw new AssertionError();
-        }
-        if (!b_1.equals(h.modPow(r_1, p).multiply(y.multiply(g).modPow(d_1, 
p)).mod(p))) {
-            throw new AssertionError();
-        }
-
-        if (!a_2.equals(g.modPow(r_2, p).multiply(x.modPow(d_2, p)).mod(p))) {
-            throw new AssertionError();
-        }
-
-        if (!b_2.equals(h.modPow(r_2, 
p).multiply(y.multiply(g.modInverse(p)).modPow(d_2, p)).mod(p))) {
-            throw new AssertionError();
-        }
-    }
-}
-

Modified: gnunet-java/src/org/gnunet/voting/VotingSimulation.java
===================================================================
--- gnunet-java/src/org/gnunet/voting/VotingSimulation.java     2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/src/org/gnunet/voting/VotingSimulation.java     2012-10-25 
00:18:02 UTC (rev 24524)
@@ -2,195 +2,120 @@
 
 import com.google.common.collect.Lists;
 
-import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 
 /**
- * ...
+ * Simulation of the voting protocol.
  *
  * @author Florian Dold
  */
 public class VotingSimulation {
     public static void main(String... args) {
-
         final int authorityCount = 10;
         final int authorityThreshold = 6;
         final VotingParameters parameters = 
VotingParameters.generateRandomParameters(64, 10, authorityCount, 
authorityThreshold);
 
-        Authority[] authorities = new Authority[authorityCount];
-        for (int i = 0; i < authorityCount; ++i) {
-            authorities[i] = new Authority(i + 1, parameters);
-        }
+        List<Authority> availableAuthorities = 
spawnAuthorities(authorityCount, authorityCount);
 
-        FullPublicKey fullPublicKey = new FullPublicKey(authorities, 
parameters);
+        final ElectionSupervisor supervisor = new 
ElectionSupervisor(availableAuthorities, parameters);
 
-        ShareVerification[] shareVerifications = new 
ShareVerification[authorityCount];
+        supervisor.inviteAuthorities();
 
-        for (int i = 0; i < authorityCount; ++i) {
-            shareVerifications[i] = authorities[i].getShareVerification();
-        }
+        // todo: what if to little authorities accepted the invitation?
 
-        for (int i = 0; i < authorityCount; ++i) {
-            for (int j = 0; j < authorityCount; ++j) {
-                BigInteger distributionShare = 
authorities[i].createShareForAuthority(j);
-                // receiving shares also verifies them
-                authorities[j].receiveShareFromAuthority(distributionShare, 
shareVerifications[i]);
-            }
-        }
+        supervisor.startKeyGeneration();
 
-        // each authority publishes a commitment to its received share
-        BigInteger[] sigmas = new BigInteger[authorityCount];
-        for (int i = 0; i < authorityCount; ++i) {
-            sigmas[i] = authorities[i].getSigma();
-        }
+        supervisor.ascertainGroupPublicKey();
 
-        final int voterCount = 100;
-        int realTally = 0;
-        Ballot[] ballots = new Ballot[voterCount];
-        for (int i = 0; i < voterCount; ++i) {
-            boolean v = CryptoUtil.random.nextBoolean();
-            realTally += v ? 1 : -1;
-            // choice of 64 bits for voter id is totally arbitrary
-            BigInteger voterId = new BigInteger(64, CryptoUtil.random);
-            ballots[i] = new Ballot(v, voterId, fullPublicKey, parameters);
-            // to the non-interactive zero-knowledge-proof
-            ballots[i].verify(fullPublicKey);
-        }
+        CallForVoters callForVoters = supervisor.createCallForVote();
 
+        List<Voter> voters = spawnVoters(callForVoters, 100, 50);
 
-        Cyphertext encryptedTally = countTally(ballots, parameters);
+        int checkTally = countCheckTally(voters);
 
-
-        SpecializedKeyShare[] specializedKeyShares = new 
SpecializedKeyShare[authorityCount];
-
-        for (int i = 0; i < authorityCount; ++i) {
-            specializedKeyShares[i] = 
authorities[i].generateSpecializedKeyShare(encryptedTally);
-            specializedKeyShares[i].verify(sigmas[i]);
+        for (Voter voter : voters) {
+            voter.vote();
         }
 
+        // todo: make sure every authority has the same votes
 
-        int[] authorityIndices = randomSelection(authorityCount, 
authorityThreshold);
-
-        System.out.println("Ai: "  + authorityIndices.length);
-        System.out.println("thresh: "  + parameters.authorityThreshold);
-
-
-        int decryptedTally = decryptTally(encryptedTally, 
specializedKeyShares, authorityIndices, voterCount, parameters);
-
-        System.out.println("expected: " + realTally);
-        System.out.println("got: " + decryptedTally);
-
-        if (realTally != decryptedTally) {
-            throw new AssertionError();
+        for (Authority authority : callForVoters.authorities) {
+            authority.distributeTallyKey();
         }
-    }
 
-    /*
-     * Return between authorityThreshold and authorityCount indices
-     */
-    private static int[] randomSelection(int authorityCount, int 
authorityThreshold) {
-        ArrayList<Integer> x = Lists.newArrayListWithCapacity(authorityCount);
-        for (int i = 0; i < authorityCount; ++i) {
-            x.add(i);
-        }
-        Collections.shuffle(x);
-        int len = CryptoUtil.random.nextInt(authorityCount - 
authorityThreshold) + authorityThreshold;
-        int[] arr = new int[len];
-        for (int i = 0; i < len; ++i) {
-            arr[i] = x.get(i);
-        }
-        return arr;
-    }
+        // todo: blame authorities that failed the zero knowledge proof
 
-    private static int decryptTally(Cyphertext encryptedTally, 
SpecializedKeyShare[] specializedKeyShares, int[] authorityIndices, int 
voteCount, VotingParameters parameters) {
-        BigInteger resultG = decryptWithSpecializedKey(encryptedTally, 
specializedKeyShares, authorityIndices, parameters);
+        for (Authority authority : callForVoters.authorities) {
+            int tally = authority.decryptTally();
 
-        int resultRestored = 0;
-        boolean success = false;
-
-        for (int l = -voteCount; l <= voteCount; ++l) {
-            if (resultG.equals(parameters.g.modPow(BigInteger.valueOf(l), 
parameters.p))) {
-                success = true;
-                resultRestored = l;
-                break;
+            if (tally != checkTally) {
+                throw new AssertionError();
             }
         }
 
-        if (!success) {
-            throw new AssertionError();
-        }
-        return resultRestored;
-
     }
 
-    private static BigInteger decryptWithSpecializedKey(Cyphertext cyphertext, 
SpecializedKeyShare[] specializedKeyShares, int[] authorityIndices, 
VotingParameters parameters) {
-        /*
-        BigInteger[] lagrangeBase = new 
BigInteger[parameters.authorityThreshold];
-        for (int j = 1; j <= parameters.authorityThreshold; ++j) {
-            BigInteger n = BigInteger.ONE;
-            BigInteger d = BigInteger.ONE;
-            for (int l = 1; l <= parameters.authorityThreshold; ++l) {
-                if (l == j) {
-                    continue;
-                }
-                n = n.multiply(BigInteger.valueOf(l));
-                d = 
d.multiply(BigInteger.valueOf(l).subtract(BigInteger.valueOf(j)));
-            }
-            lagrangeBase[j - 1] = 
n.multiply(d.modInverse(parameters.q)).mod(parameters.q);
+    private static int countCheckTally(List<Voter> voters) {
+        int tally = 0;
+        for (Voter voter : voters) {
+            tally += voter.b ? 1 : -1;
         }
-        */
+        return tally;
+    }
 
 
-
-        // the coefficients for non-participating authorities are invalid 
gibberish
-        BigInteger[] lagrangeBase = new BigInteger[parameters.authorityCount];
-        for (int j = 1; j <= parameters.authorityCount; j++) {
-            BigInteger n = BigInteger.ONE;
-            BigInteger d = BigInteger.ONE;
-            for (int l = 1; l <= parameters.authorityCount; ++l) {
-                boolean skip = true;
-                // only count participating authorities in
-                for (int authorityIndex : authorityIndices) {
-                    if (authorityIndex == l-1) {
-                        skip = false;
-                    }
-                }
-                if ((l == j) || skip) {
-                    continue;
-                }
-                n = n.multiply(BigInteger.valueOf(l));
-                d = 
d.multiply(BigInteger.valueOf(l).subtract(BigInteger.valueOf(j)));
+    /**
+     * Create all authorities involved in the election, where some authorities 
are bogus authorities.
+     *
+     * @param authorityCount number of returned authorities
+     * @param authorityThreshold minimum number of honest authorities
+     * @return list of authorities
+     */
+    public static List<Authority> spawnAuthorities(int authorityCount, int 
authorityThreshold) {
+        List<Authority> authorities = Lists.newArrayList();
+        Collection<Integer> honestAuthorityIndices = 
VotingSimulation.randomIndices(authorityCount, authorityThreshold);
+        for (int i = 0; i < authorityCount; ++i) {
+            if (honestAuthorityIndices.contains(i)) {
+                authorities.add(new Authority());
             }
-            lagrangeBase[j-1] = 
n.multiply(d.modInverse(parameters.q)).mod(parameters.q);
         }
+        return authorities;
+    }
 
-        /*
-        BigInteger prod = BigInteger.ONE;
-        for (int i = 0; i < parameters.authorityThreshold; ++i) {
-            BigInteger wp = 
specializedKeyShares[i].specializedShare.modPow(lagrangeBase[i], parameters.p);
-            prod = prod.multiply(wp).mod(parameters.p);
-        }
-        */
 
-        BigInteger prod = BigInteger.ONE;
-        for (int authorityIndex : authorityIndices) {
-            BigInteger wp = 
specializedKeyShares[authorityIndex].specializedShare.modPow(lagrangeBase[authorityIndex],
 parameters.p);
-            prod = prod.multiply(wp).mod(parameters.p);
+    /**
+     * Create voters, where some voters may be malicious.
+     *
+     * @param callForVote description of the election for the voter
+     * @param voterCount number of all voters
+     * @param honestVoterCount number of honest, non-malicious voters
+     */
+    private static List<Voter> spawnVoters(CallForVoters callForVote, int 
voterCount, int honestVoterCount) {
+        List<Voter> voters = Lists.newArrayList();
+        for (int i = 0; i < voterCount; ++i) {
+            voters.add(new Voter(callForVote));
         }
-
-        return 
cyphertext.c2.multiply(prod.modInverse(parameters.p)).mod(parameters.p);
+        return voters;
     }
 
-    private static Cyphertext countTally(Ballot[] ballots, VotingParameters 
parameters) {
-        BigInteger votesX = BigInteger.ONE;
-        BigInteger votesY = BigInteger.ONE;
-        for (Ballot ballot : ballots) {
-            votesX = votesX.multiply(ballot.x).mod(parameters.p);
-            votesY = votesY.multiply(ballot.y).mod(parameters.p);
+    /*
+     * Return between authorityThreshold and authorityCount indices
+     */
+    private static List<Integer> randomIndices(int authorityCount, int 
authorityThreshold) {
+        ArrayList<Integer> x = Lists.newArrayListWithCapacity(authorityCount);
+        for (int i = 0; i < authorityCount; ++i) {
+            x.add(i);
         }
-
-        return new Cyphertext(votesX, votesY);
-
+        Collections.shuffle(x);
+        int len;
+        if (authorityCount == authorityThreshold) {
+            len = authorityThreshold;
+        } else {
+            len = CryptoUtil.random.nextInt(authorityCount - 
authorityThreshold) + authorityThreshold;
+        }
+        return Collections.unmodifiableList(x.subList(0, len));
     }
 }

Modified: gnunet-java/src/org/grothoff/Runabout.java
===================================================================
--- gnunet-java/src/org/grothoff/Runabout.java  2012-10-24 21:32:21 UTC (rev 
24523)
+++ gnunet-java/src/org/grothoff/Runabout.java  2012-10-25 00:18:02 UTC (rev 
24524)
@@ -266,7 +266,7 @@
                                     throw new RunaboutException(e.toString());
                                 } catch (InvocationTargetException e) {
                                     System.err.println("stacktrace:");
-                                    e.getCause().printStackTrace(System.out);
+                                    e.getCause().printStackTrace(System.err);
                                     throw new 
RunaboutException(e.getCause().toString());
                                 }
                             }

Modified: gnunet-java/test/org/gnunet/dht/DHTTest.java
===================================================================
--- gnunet-java/test/org/gnunet/dht/DHTTest.java        2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/test/org/gnunet/dht/DHTTest.java        2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -31,6 +31,8 @@
 public class DHTTest {
     @Test(timeout = 1000)
     public void test_dht_put() {
+        Program.configureLogging();
+
         final Wrapper<Boolean> putFinished = new Wrapper<Boolean>(true);
 
         TestingSubsystem ts = new TestingSubsystem("dht");

Modified: gnunet-java/test/org/gnunet/mesh/MeshTest.java
===================================================================
--- gnunet-java/test/org/gnunet/mesh/MeshTest.java      2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/test/org/gnunet/mesh/MeshTest.java      2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -1,7 +1,6 @@
 package org.gnunet.mesh;
 
 import junit.framework.Assert;
-import org.gnunet.construct.Construct;
 import org.gnunet.testing.TestingSubsystem;
 import org.gnunet.util.*;
 import org.grothoff.Runabout;
@@ -14,42 +13,51 @@
  */
 public class MeshTest {
 
+
     @Test
-    public void test_dummy() {
-
-    }
-
     public void test_mesh_connect() {
-        Program.configureLogging();
+        Program.configureLogging("DEBUG");
 
         final TestingSubsystem ts = new TestingSubsystem("mesh");
         Configuration cfg = ts.getConfiguration();
 
         final Wrapper<Boolean> gotInbound = new Wrapper<Boolean>();
+        final Wrapper<Boolean> gotMessage = new Wrapper<Boolean>();
 
         InboundTunnelHandler inbound = new InboundTunnelHandler() {
             @Override
             public void onInboundTunnel(Mesh.Tunnel tunnel, PeerIdentity 
initiator) {
+                System.out.println("inbound tunnel");
                 gotInbound.set(true);
             }
         };
 
-        Runabout r = new Runabout() {
+        final Wrapper<Mesh> m1_ref = new Wrapper<Mesh>();
+        final Wrapper<Mesh> m2_ref = new Wrapper<Mesh>();
+
+        MeshRunabout r = new MeshRunabout() {
             public void visit(TestMessage m) {
-
+                gotMessage.set(true);
+                m1_ref.get().disconnect();
+                m2_ref.get().disconnect();
             }
         };
 
+        // creates origin tunnel, adds m2
         Mesh m1 = new Mesh(cfg, null, null, r, 1);
         Mesh m2 = new Mesh(cfg, inbound, null, r, 1);
 
-        final Mesh.RootTunnel tunnel = m1.createTunnel(new ConnectHandler() {
+        m1_ref.set(m1);
+        m2_ref.set(m2);
+
+        final Mesh.OriginTunnel tunnel = m1.createTunnel(new ConnectHandler() {
             @Override
             public void onConnect(Mesh.Tunnel tunnel, PeerIdentity peer) {
                 System.out.println("peer added to tunnel");
                 tunnel.notifyTransmitReady(RelativeTime.FOREVER, peer, 4, new 
MessageTransmitter() {
                     @Override
                     public void transmit(Connection.MessageSink sink) {
+                        System.out.println("sending!");
                         sink.send(new TestMessage());
                     }
 
@@ -61,6 +69,7 @@
             }
         }, null);
 
+        // addDelayed so that m2 is ready to be connected
         Scheduler.addDelayed(RelativeTime.SECOND, new Scheduler.Task() {
             @Override
             public void run(Scheduler.RunContext ctx) {
@@ -68,7 +77,6 @@
             }
         });
 
-
         Scheduler.run();
     }
 }

Modified: gnunet-java/test/org/gnunet/statistics/StatisticsTest.java
===================================================================
--- gnunet-java/test/org/gnunet/statistics/StatisticsTest.java  2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/test/org/gnunet/statistics/StatisticsTest.java  2012-10-25 
00:18:02 UTC (rev 24524)
@@ -61,7 +61,7 @@
 
     @Test(timeout = 1000)
     public void test_simple() {
-        Program.configureLogging();
+        Program.configureLogging("DEBUG");
         final TestingSubsystem ts = new TestingSubsystem("statistics");
 
         final Statistics stat = new Statistics(ts.getConfiguration());
@@ -146,9 +146,9 @@
     }
 
 
-    @Test(timeout = 1000)
+    @Test(timeout = 10000)
     public void test_watch() {
-        Program.configureLogging();
+        Program.configureLogging("DEBUG");
         final TestingSubsystem ts = new TestingSubsystem("statistics");
 
         final Wrapper<Integer> updates = new Wrapper<Integer>(0);
@@ -196,6 +196,7 @@
         stat.watch("gnj-test", "test", new StatisticsReceiver() {
             @Override
             public void onReceive(String subsystem, String name, long value) {
+                System.out.println("received");
                 updates.set(updates.get() + 1);
                 if (updates.get() == 4) {
                     stat.destroy();

Modified: gnunet-java/test/org/gnunet/testing/TestingSetupTest.java
===================================================================
--- gnunet-java/test/org/gnunet/testing/TestingSetupTest.java   2012-10-24 
21:32:21 UTC (rev 24523)
+++ gnunet-java/test/org/gnunet/testing/TestingSetupTest.java   2012-10-25 
00:18:02 UTC (rev 24524)
@@ -20,6 +20,7 @@
 
 package org.gnunet.testing;
 
+import org.gnunet.util.Program;
 import org.junit.Test;
 
 /**
@@ -28,9 +29,10 @@
 public class TestingSetupTest {
     @Test(timeout = 1000)
     public void test_testing() {
+        Program.configureLogging();
         // could be any service, just use statistics
         TestingSubsystem ts = new TestingSubsystem("statistics");
-        String port = ts.getConfiguration().getValueString("statistics", 
"PORT");
+        String port = ts.getConfiguration().getValueString("statistics", 
"PORT").get();
         org.junit.Assert.assertTrue(port != null);
 
         ts.destroy();

Deleted: gnunet-java/test/org/gnunet/util/MeshTest.java
===================================================================
--- gnunet-java/test/org/gnunet/util/MeshTest.java      2012-10-24 21:32:21 UTC 
(rev 24523)
+++ gnunet-java/test/org/gnunet/util/MeshTest.java      2012-10-25 00:18:02 UTC 
(rev 24524)
@@ -1,36 +0,0 @@
-package org.gnunet.util;
-
-import org.gnunet.mesh.Mesh;
-import org.gnunet.testing.TestingSubsystem;
-import org.junit.Test;
-
-/**
- * ...
- *
- * @author Florian Dold
- */
-public class MeshTest {
-
-    @Test
-    public void test_tunnel_create() {
-        /*
-        Program.configureLogging("DEBUG", null);
-        TestingSubsystem ts = new TestingSubsystem("mesh");
-
-        Mesh m = new Mesh(ts.getConfiguration(), null, null, new 
RunaboutMessageReceiver() {
-            public void visit(TestMessage tm) {
-
-            }
-            @Override
-            public void handleError() {
-
-            }
-        });
-
-        m.createTunnel(null, null);
-
-        Sc
-        Sheduler.run();
-        */
-    }
-}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]