changeset 741:16035b12d7ae

Merged with Sphinx documentation.
author Martin Geisler <mg@daimi.au.dk>
date Tue, 29 Apr 2008 08:56:59 +0200
parents 7b4ea9675666 1d741230801b
children 88d4c3f9cee1
files doc/design-talk/design-talk.tex doc/design-talk/example.py doc/design-talk/sample-config.ini viff/runtime.py
diffstat 28 files changed, 1182 insertions(+), 821 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Apr 28 20:18:55 2008 +0200
+++ b/.hgignore	Tue Apr 29 08:56:59 2008 +0200
@@ -25,7 +25,6 @@
 
 # LaTeX outputs.
 *.{aux,dvi,log,nav,out,pdf,ps,snm,toc,vrb}
-doc/api/
 
 # Distutils generated files.
 build
--- a/MANIFEST.in	Mon Apr 28 20:18:55 2008 +0200
+++ b/MANIFEST.in	Tue Apr 29 08:56:59 2008 +0200
@@ -1,5 +1,3 @@
-include doc/design-talk/design-talk.pdf
-
 include doc/api/*.html
 include doc/api/*.gif
 include doc/api/*.png
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/conf.py	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+#
+# VIFF documentation build configuration file, created by
+# sphinx-quickstart on Mon Apr 21 08:54:10 2008.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# The contents of this file are pickled, so don't put values in the
+# namespace that aren't pickleable (module imports are okay, they're
+# removed automatically).
+#
+# All configuration values have a default value; values that are
+# commented out serve to show the default value.
+
+import sys
+
+# If your extensions are in another directory, add it here.
+#sys.path.append('some/directory')
+
+# Ensure we load VIFF from the parent directory.
+import os
+sys.path.insert(0, os.path.abspath('../'))
+
+# Make viff.util.wrapper a no-op.
+os.environ['VIFF_NO_WRAP'] = 'yes'
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = []
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'VIFF'
+copyright = '2008, VIFF Development Team'
+
+import viff
+
+# The default replacements for |version| and |release|, also used in
+# various other places throughout the built documents.
+#
+# The short X.Y version.
+version = viff.__version__
+# The full version, including alpha/beta/rc tags.
+release = viff.__version__
+
+# There are two options for replacing |today|: either, you set today
+# to some non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all
+# description unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in
+# the output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that
+# name must exist either in Sphinx' static/ path, or in one of the
+# custom paths given in html_static_path.
+html_style = 'default.css'
+
+# Add any paths that contain custom static files (such as style
+# sheets) here, relative to this directory. They are copied after the
+# builtin static files, so a file named "default.css" will overwrite
+# the builtin "default.css".
+html_static_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page
+# bottom, using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Content template for the index page.
+#html_index = ''
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page
+# names to template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If true, the reST sources are included in the HTML build as
+# _sources/<name>.
+#html_copy_source = True
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'VIFFdoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class
+# [howto/manual]).
+#latex_documents = []
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/config.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,18 @@
+
+Config Module
+=============
+
+.. automodule:: viff.config
+
+   .. autoclass:: Player
+      :members: prfs, dealer_prfs
+
+      .. attribute:: id
+                     host
+                     port
+
+         ID, hostname, and portnumber of the player.
+
+   .. autofunction:: generate_configs
+
+   .. autofunction:: load_config
--- a/doc/design-talk/design-talk.tex	Mon Apr 28 20:18:55 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,367 +0,0 @@
-\documentclass[t,noamsthm]{beamer}
-
-\mode<presentation>
-{
-  \usetheme{Goettingen}
-  \setbeamercovered{transparent}
-  \setbeamertemplate{navigation symbols}{}
-}
-
-\usepackage[english]{babel}
-\usepackage[latin1]{inputenc}
-\usepackage[T1]{fontenc}
-\usepackage{lmodern,textcomp}
-
-\title[VIFF]{Virtual Ideal Functionality Framework}
-
-\subtitle{High-Level Design Overview}
-
-\author{Martin Geisler}
-
-\institute[BRICS]{
-  BRICS\\
-  Department of Computer Science\\
-  University of Aarhus
-}
-
-\date{September 20th, 2007}
-
-% \pgfdeclareimage[height=0.5cm]{university-logo}{university-logo-filename}
-% \logo{\pgfuseimage{university-logo}}
-
-% If you wish to uncover everything in a step-wise fashion, uncomment
-% the following command: 
-%\beamerdefaultoverlayspecification{<+->}
-
-\usepackage{tikz}
-
-\newcommand{\rulecolor}{structure!60}
-\newcommand{\fillcolor}{structure!15}
-
-\tikzstyle{player}=[circle,fill=\fillcolor,draw=\rulecolor]
-\tikzstyle{every picture}=[thick]
-
-
-\usepackage{listings}
-\lstset{
-  language=Python,
-  basicstyle=\footnotesize,
-  columns=fullflexible,
-  showstringspaces=false,
-  frame=single,
-  framerule=0.8pt,
-  rulecolor=\color{\rulecolor},
-  backgroundcolor=\color{\fillcolor}
-}
-\newcommand{\py}[1]{\lstinline|#1|}
-
-\usepackage{nath} \delimgrowth=2
-
-\begin{document}
-
-\begin{frame}
-  \titlepage
-\end{frame}
-
-%\begin{frame}{Outline}
-%  \tableofcontents
-%  % You might wish to add the option [pausesections]
-%\end{frame}
-
-\section{Features}
-
-\begin{frame}{VIFF Features}
-
-  \begin{itemize}
-
-  \item API for writing secure multi-party computations
-    \begin{itemize}
-    \item Easy to use: \py{a + b + c} instead of \py{add(add(a, b), c)}
-    \item Simple if you already know Python
-    \item A custom language could be added
-    \end{itemize}
-
-  \item<2-> Efficient asynchronous design
-    \begin{itemize}
-    \item Automatic parallelism
-    \item Single-threaded (no locks!)
-    \end{itemize}
-    
-  \item<3-> Simple architecture
-    \begin{itemize}
-    \item Small code base (2,500 lines)
-    \item Few layers of abstraction\dots
-    \item \dots but hopefully sufficiently many
-    \end{itemize}
-
-  \end{itemize}
-
-\end{frame}
-
-\section{Example}
-
-\begin{frame}{Example MPC Calculation}
-
-  \begin{columns}
-
-    \column{0.5\textwidth}
-
-    \centering
-    \begin{tikzpicture}
-      \draw (0,0) + (90:2cm) node[player] (P1) {$P_1$}
-                  +(210:2cm) node[player] (P2) {$P_2$}
-                  +(330:2cm) node[player] (P3) {$P_3$};
-
-      \visible<1>{
-        \draw (P1.north) node[above] {$x$};
-        \draw (P2.south) node[below] {$y$};
-        \draw (P3.south) node[below] {$z$};
-      }
-
-      \visible<2>{
-        \draw[->] (P1) .. controls +(75:1cm) and +(105:1cm) ..
-          node[above,sloped] {$x_1$} (P1);
-        \draw[->] (P1) .. controls +(230:1cm) and +(70:1cm) ..
-          node[above,sloped] {$x_2$} (P2);
-        \draw[->] (P1) .. controls +(-50:1cm) and +(110:1cm) ..
-          node[above,sloped] {$x_3$} (P3);
-
-        \draw[->] (P2) .. controls +(50:1cm) and +(250:1cm) ..
-          node[below,sloped] {$y_1$} (P1);
-        \draw[->] (P2) .. controls +(225:1cm) and +(255:1cm) ..
-          node[below,xshift=1pt] {$y_2$} (P2);
-        \draw[->] (P2) .. controls +(10:1cm) and +(170:1cm) ..
-          node[above,sloped] {$y_3$} (P3);
-
-        \draw[->] (P3) .. controls +(130:1cm) and +(-70:1cm) ..
-          node[below,sloped] {$z_1$} (P1);
-        \draw[->] (P3) .. controls +(-170:1cm) and +(-10:1cm) ..
-          node[below,sloped] {$z_2$} (P2);
-        \draw[->] (P3) .. controls +(-75:1cm) and +(-45:1cm) ..
-          node[below,xshift=-1pt] {$z_3$} (P3);
-      }
-
-      \visible<3>{
-        \draw (P1.north) node[above] {$x_1$, $y_1$, $z_1$};
-        \draw (P2.south) node[below,xshift=6pt] {$x_2$, $y_2$, $z_2$};
-        \draw (P3.south) node[below,xshift=-6pt] {$x_3$, $y_3$, $z_3$};
-      }
-
-      \visible<4>{
-        \draw[<->,dashed] (P1) -- (P2);
-        \draw[<->,dashed] (P2) -- (P3);
-        \draw[<->,dashed] (P3) -- (P1);
-      }
-
-      \visible<5-6>{
-        \draw (P1.north) node[above] {$r_1$};
-        \draw (P2.south) node[below] {$r_2$};
-        \draw (P3.south) node[below] {$r_3$};
-      }
-
-      \visible<6>{
-        \draw[->] (P1) .. controls +(230:1cm) and +(70:1cm) ..
-          node[above,sloped] {$r_1$} (P2);
-        \draw[->] (P1) .. controls +(-50:1cm) and +(110:1cm) ..
-          node[above,sloped] {$r_1$} (P3);
-
-        \draw[->] (P2) .. controls +(50:1cm) and +(250:1cm) ..
-          node[below,sloped] {$r_2$} (P1);
-        \draw[->] (P2) .. controls +(10:1cm) and +(170:1cm) ..
-          node[above,sloped] {$r_2$} (P3);
-
-        \draw[->] (P3) .. controls +(130:1cm) and +(-70:1cm) ..
-          node[below,sloped] {$r_3$} (P1);
-        \draw[->] (P3) .. controls +(-170:1cm) and +(-10:1cm) ..
-          node[below,sloped] {$r_3$} (P2);
-      }
-
-      \visible<7>{
-        \draw (P1.north) node[above] {$r$};
-        \draw (P2.south) node[below] {$r$};
-        \draw (P3.south) node[below] {$r$};
-      }
-
-    \end{tikzpicture}
-
-    \column{0.5\textwidth}
-
-    \begin{itemize}
-    \item<1-> Players $P_1$, $P_2$, and $P_3$
-    \item<2-> Sharing $x$, $y$, and $z$
-    \item<4-> Compute $r= (x+y)\cdot z$
-    \item<6-> Opens the result $r$
-    \end{itemize}
-
-  \end{columns}
-\end{frame}
-
-\begin{frame}{Example VIFF Program}
-
-\mbox{}\vspace{-2\baselineskip}
-
-\begin{columns}
-  \column{0.625\textwidth}
-  \lstinputlisting[linerange={1-5}]{example.py}
-  \column{0.375\textwidth}
-  \begin{itemize}
-  \item Import standard and VIFF modules
-  \end{itemize}
-\end{columns}
-
-\vspace{-0.75\baselineskip}
-
-\begin{columns}
-  \column{0.625\textwidth}
-  \uncover<2->{\lstinputlisting[linerange={7-9}]{example.py}}
-  \column{0.375\textwidth}
-  \begin{itemize}
-  \item<2-> Load command line config
-  \end{itemize}
-\end{columns}
-
-\vspace{-0.75\baselineskip}
-
-\begin{columns}
-  \column{0.625\textwidth}
-  \uncover<3->{\lstinputlisting[linerange={11-13}]{example.py}}
-  \column{0.375\textwidth}
-  \begin{itemize}
-  \item<3-> Create Runtime, do calculation
-  \end{itemize}
-\end{columns}
-
-\vspace{-0.75\baselineskip}
-
-\begin{columns}
-  \column{0.625\textwidth}
-  \uncover<4->{\lstinputlisting[linerange={15-17}]{example.py}}
-  \column{0.375\textwidth}
-  \begin{itemize}
-  \item<4-> Open and print result
-  \end{itemize}
-\end{columns}
-
-\end{frame}
-
-\begin{frame}{Example Configuration File}
-
-  \lstdefinelanguage{ini}{
-    morecomment=[l]{\#},
-    moredelim=[s][\textbf]{[}{]},
-    moredelim=[s][\textbf]{[[}{]]},
-    moredelim=[s][\textbf]{[[[}{]]]}
-  }
-
-  \lstinputlisting[language=ini]{sample-config.ini}
-
-\end{frame}
-
-\section{Scheduling}
-
-\begin{frame}{Asynchronous Design}
-
-  \begin{columns}
-
-    \column{0.3\textwidth}
-
-    \begin{tikzpicture}
-      \tikzstyle{level 1}=[level distance=10mm]
-
-      \draw (-0.25,0) node {$r = (x+y) \cdot z$};
-      \draw (0,-0.5) node[xshift=-0.75pt,rotate=-90] {$\rightsquigarrow$};
-
-      \draw (0,-1) node {open}
-        child {node {\py{*}}
-          child {node {\py{+}}
-            child {node {x}}
-            child {node {y}}
-          }
-          child {node {z}}};
-    \end{tikzpicture}
-
-    \column{0.7\textwidth}
-
-    \begin{itemize}
-    \item Entire tree is scheduled as once
-    \item Operations wait on their operands
-    \item Results are sent when ready
-    \item Result is a form of ``greedy scheduling''
-    \item Implicit synchronization, no rounds
-    \end{itemize}
-
-  \end{columns}
-
-\end{frame}
-
-\begin{frame}{Greedy Scheduling}
-  Advantages:
-  \begin{itemize}
-  \item At least as efficient as round-based scheduling
-  \item No cost when adding primitives (modular design)
-  \item Automatic parallelism
-  \end{itemize}
-
-  Disadvantages:
-  \begin{itemize}
-  \item Not yet proven secure\dots
-  \end{itemize}
-\end{frame}
-
-
-\section{Current Status}
-
-\begin{frame}{What has been Implemented?}
-  \begin{itemize}
-  \item Shamir sharing
-  \item PRSS
-  \item Opening
-  \item Addition, multiplication, exclusive-or
-  \item Classic SCET comparison
-  \end{itemize}
-\end{frame}
-
-
-\begin{frame}{Assumptions}
-  
-  Current primitives assume:
-  \begin{itemize}
-  \item Fixed number of players
-  \item Passive and static adversary
-  \item Threshold adversary structure, $t < \frac n 2$
-  \end{itemize}
-
-  
-\end{frame}
-
-\section{Conclusion}
-
-\begin{frame}{Conclusion}
-
-\begin{itemize}
-\item VIFF offers a light-weight design for doing MPC
-\item Asynchronous design gives automatic parallelism
-\end{itemize}
-
-Installation instructions, source code and more:
-\begin{itemize}
-\item \url{http://viff.dk/}
-\end{itemize}
-
-\visible<2>{
-  \begin{center}
-    \bigskip
-    \begin{tikzpicture}
-      \draw node[rectangle,draw=\rulecolor,fill=\fillcolor,
-        inner sep=2.5em,font=\huge\bfseries] {Questions?};
-    \end{tikzpicture}
-  \end{center}
-}
-
-\end{frame}
-
-
-
-\end{document}
-
-% LocalWords:  VIFF API MPC PRSS SCET
--- a/doc/design-talk/example.py	Mon Apr 28 20:18:55 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-import sys
-from viff.field import GF
-from viff.config import load_config
-from viff.runtime import Runtime
-from viff.util import dprint
-
-Z31 = GF(31)
-my_id, conf = load_config(sys.argv[1])
-my_input = Z31(int(sys.argv[2]))
-
-rt = Runtime(conf, my_id, 1)
-x, y, z = rt.shamir_share(my_input)
-result = (x + y) * z
-
-opened_result = rt.open(result)
-dprint("Result: %s", opened_result)
-rt.wait_for(opened_result)
--- a/doc/design-talk/sample-config.ini	Mon Apr 28 20:18:55 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-[Player 1]
-  host = camel09
-  port = 7100
-[Player 2]
-  host = camel17
-  port = 7200
-[Player 3]
-  host = camel19
-  port = 7300
-  [[prss_keys]]
-    1 3 = 0x47D5B9B367DAFC9267EDF518AD5B5F396299L
-    2 3 = 0x7EBC55E5CF1D014D081EA428B5F35FD12C64L
-  [[prss_dealer_keys]]
-    [[[Dealer 1]]]
-      1 3 = 0x903039893A06800A0FA7175CED8CC17B873BL
-      2 3 = 0x11C91354237193397589A1D1C6455F87CB79L
-    # More PRSS keys...
-
-# End of config
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/field.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,23 @@
+
+Finite Fields Module
+====================
+
+.. automodule:: viff.field
+
+   .. autoclass:: FieldElement
+
+   .. autoclass:: GF256
+      :members: __add__, __mul__, __pow__, __div__, __neg__, __invert__, __eq__, __nonzero__
+
+      .. attribute:: GF256.modulus
+
+         Field modulus, always 256.
+
+      .. method:: GF256.__sub__(other)
+                  GF256.__xor__(other)
+
+         Subtraction and exclusive-or. Since GF(2^8) has
+         characteristic 2, these two operations are identical to
+         addition.
+
+   .. autofunction:: GF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/glossary.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,18 @@
+
+Glossary
+========
+
+.. glossary::
+
+   Ideal functionality
+     An ideal functionality is an uncorruptable party in an ideal
+     protocol.
+
+   Program counter
+     A label associated with an operation, used to identify the data
+     when it is received over the network. Please see :ref:`program-counters`.
+
+   VIFF
+     Abbreviation for *Virtual Ideal Functionality Framework*. VIFF
+     allows you to write programs which behave as if they had access
+     to an :term:`ideal functionality`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/implementation.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,17 @@
+
+Implementation
+==============
+
+VIFF consists of several modules which will be described next.
+
+.. toctree::
+   :maxdepth: 2
+
+   util
+   field
+   shamir
+   matrix
+   runtime
+   prss
+   config
+   program-counters
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/index.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,25 @@
+
+Welcome to VIFF's documentation!
+================================
+
+The Virtual Ideal Functionality Framework is a general framework for
+doing secure multi-party computation.
+
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   overview
+   install
+   implementation
+   glossary
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/install.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,247 @@
+.. -*- coding: utf-8 -*-
+.. (Links are marked with underscores, see the bottom of the file.)
+
+====================
+ Installation Guide
+====================
+
+VIFF is written in Python and uses the Twisted framework for
+asynchronous communication, (optionally) python-gnutls for secure
+communication, ConfigObj for configuration files, and GMPY for fast
+bignum arithmetic. You can find these components here:
+
+:Python:         http://python.org/
+:Twisted:        http://twistedmatrix.com/
+:python-gnutls:  http://pypi.python.org/pypi/python-gnutls/
+:ConfigObj:      http://voidspace.org.uk/python/configobj.html
+:GMPY:           http://code.google.com/p/gmpy/
+
+VIFF has been successfully tested with the following versions:
+
+:Python:         2.4.1 and 2.5.0
+:Twisted:        2.5.0 (there are `problems with 8.0.1`_)
+:python-gnutls:  1.1.4
+:ConfigObj:      4.4.0
+:GMPY:           1.0alpha and 1.0.2
+
+Please `report back`_ if you find that VIFF works with other versions
+than the ones listed here.
+
+Below you will find installation instructions for the different
+platforms on which we `test VIFF`_.
+
+
+Windows
+-------
+
+This describes the installation procedure for VIFF on Windows. It has
+been tested and verified on Windows XP Professional Version 2002 SP2
+and Windows Vista Ultimate SP1.
+
+1) Download and install Python_.
+
+2) Include the path to your Python installation (e.g. ``C:\Python25\``)
+   in the ``PATH`` system environment variable. One way to edit this
+   environment variable is by right-clicking My Computer in the Start
+   menu, selecting Properties, Advanced, and then pressing the
+   Environment Variables button.
+
+3) Download and install Twisted_.
+
+4) Download ConfigObj_ and enter::
+
+      python setup.py install
+
+   from the folder where you unzipped the files.
+
+5) Download and install GMPY_. If you are using Vista, right-click on
+   the installer and choose the option to run as administrator.
+
+6) In order to secure the channels between the players using TLS, you
+   need to download and install python-gnutls_. However, we haven't
+   had the time to test installation of this on Windows yet. Feel free
+   to contribute with details about this by sending an email to the
+   `VIFF mailing list`_.
+
+7) Download and install VIFF_. Note that if you are using the
+   installer on Vista, you will again need to run it as an
+   administrator.
+
+8) Proceed to `testing`_.
+
+
+Mac OS X
+--------
+
+This describes installation of VIFF on Max OS X 10.5.
+
+1) Download and install the full MacPython_ version 2.5 (the
+   Python-installation which comes with Mac OS X is not entirely
+   up-to-date).
+
+2) Download and Install Twisted_ from source. Notice again that Mac OS
+   X comes with a pre-installed version of Twisted, but this is not
+   the full Twisted installation. After installation change your
+   ``PYTHONPATH`` (in your ``~/.bash_profile``) to::
+
+      PATH="/Library/Python/2.5/site-packages:${PATH}"
+
+3) You can skip this step if you do not want secure connections.
+   Otherwise install python-gnutls_:
+
+   a) Install XCode_ from Apple which provides the GCC compiler.
+   b) Install gnutls_ (and required packages) from source.
+   c) Install python-gnutls_.
+
+4) Download ConfigObj_ and enter::
+
+      python setup.py install
+
+   from the folder where you unzipped the files.
+
+5) Download and install GMPY_ following the instructions in
+   ``gmpy-1.02.macosx.README.txt`` (under Downloads).
+
+6) Install VIFF from source (see below). If you prefer you can just
+   install it in site-packages, it makes no difference. For
+   developers, it is perhaps a better solution in to create a symbolic
+   link from the site-packages directory to the VIFF Python files
+   (``viff/viff/``), as otherwise you need to re-install VIFF each time
+   the project is modified.
+
+7) Proceed to `testing`_.
+
+
+GNU/Linux
+---------
+
+VIFF was originally developed on GNU/Linux and is well supported
+there. When installing the VIFF dependencies you either have the
+option of using your `package manager`_ or to install from source. VIFF
+itself must be installed `from source`_.
+
+
+Using a Package Manager
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Debian Lenny (testing)
+  You can install all dependencies by the command::
+
+     aptitude install python-twisted-core python-gnutls \
+                      python-configobj python-gmpy
+
+  The backslash indicates that both lines should be typed as a single
+  line in the terminal.
+
+Ubuntu
+  We expect that the instructions for Debian also apply here.
+
+
+If you know how to install using other package managers, please `let
+us know`_.
+
+VIFF itself is not yet packaged for any distribution, so you will have
+to install it from source as described below.
+
+
+Installing from Source
+~~~~~~~~~~~~~~~~~~~~~~
+
+If you do not have permission to use the package manager or simply
+prefer to install from source, then (assuming that Python is already
+installed) one can easily install VIFF and its dependencies by
+downloading and unpacking each of them and executing::
+
+   python setup.py install --home=$HOME/opt
+
+That will install everything under the given prefix. With the above
+command the Python modules are installed into::
+
+   $HOME/opt/lib/python
+
+and some programs are installed into::
+
+   $HOME/opt/bin
+
+You should add the first directory to the ``PYTHONPATH`` environment
+variable and the latter to the ``PATH`` environment variable.
+
+Bash uses can normally do this by adding::
+
+   export PYTHONPATH=$PYTHONPATH:$HOME/opt/lib/python
+   export PATH=$PATH:$HOME/opt/bin
+
+to their ``~/.bash_profile`` file, creating it if it is not already
+there. Consult the documentation for your shell to learn how
+environment variables are set.
+
+
+Testing
+-------
+
+To verify the installation, try out one of the applications. We will
+run the millionaires example with three players and a threshold of
+one. For this test, we will let all players run on localhost: Player 1
+will run on port 9001, player 2 on port 9002, and player 3 on port
+9003. The test is done on Windows, but it works the same on the other
+platforms. Do the following:
+
+1) Go to the ``viff/apps/`` directory and generate the needed
+   configuration files by entering::
+
+     python generate-config-files.py -n 3 -t 1
+     localhost:9001 localhost:9002 localhost:9003
+
+   Both lines should be entered as a single line.
+
+2) Open three separate command prompts and go to the ``viff/apps/``
+   directory in each. In the first, type::
+
+     python millionaires.py --no-tls player-3.ini
+
+   in the second, type::
+
+     python millionaires.py --no-tls player-2.ini
+
+   and in the last, type::
+
+     python millionaires.py --no-tls player-1.ini
+
+   Note that the order in wich you start the players is important: The
+   players must start in reverse order, e.g. the last player first. If
+   the installation works, you should see something like this from
+   e.g. player 3::
+
+      C:\viff\apps> python millionaires.py --no-tls player-3.ini 
+      Seeding random generator with random seed 7416
+      Not using TLS
+      I am Millionaire 3 and I am worth 20 millions.
+      From poorest to richest:
+        Millionaire 2
+        Millionaire 3 (20 millions)
+        Millionaire 1
+      Initiating shutdown sequence.
+
+   If something went wrong, then please `file a bug report`_ or report
+   it on the `VIFF mailing list`_. This will help us improve VIFF.
+
+
+.. _problems with 8.0.1: http://tracker.viff.dk/issue37
+.. _report back:
+.. _VIFF mailing list:
+.. _let us know: viff-devel@viff.dk
+
+.. _VIFF: http://viff.dk/
+.. _test VIFF: http://buildbot.viff.dk/
+.. _Python: http://python.org/
+.. _Twisted: http://twistedmatrix.com/
+.. _ConfigObj: http://voidspace.org.uk/python/configobj.html
+.. _GMPY: http://code.google.com/p/gmpy/
+.. _python-gnutls: http://pypi.python.org/pypi/python-gnutls/
+.. _MacPython: http://www.pythonmac.org
+.. _XCode: http://developer.apple.com/tools/xcode/
+.. _gnutls: http://www.gnu.org/software/gnutls/manual/gnutls.html
+            #Downloading-and-Installing
+.. _package manager: `Using a Package Manager`_
+.. _from source: `Installing from Source`_
+.. _file a bug report: http://tracker.viff.dk/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/matrix.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,10 @@
+
+Matrix Module
+=============
+
+.. automodule:: viff.matrix
+
+   .. autoclass:: Matrix
+      :members: __add__, __mul__, __str__, transpose, determinant
+
+   .. autofunction:: hyper
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/overview.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,97 @@
+
+Overview
+========
+
+VIFF allows you to write a program which will interact with other
+programs in order to execute a joint computation. This is called a
+multi-party computation, MPC for short.
+
+The programs will implement what we call a virtual :term:`ideal
+functionality` (IF). The idea is that the behavior of the programs
+should be indistinguishable from the behavior of programs interacting
+with a so-called ideal functionality. An ideal functionality is a
+player that cannot be corrupted, also known as a trusted third party
+(TTP).
+
+Interacting with an IF is easy: all players give their inputs to the
+IF, which computes the results. The results are then distributed to
+the correct players. The inputs and the results are sent over secure
+channels, and since the IF cannot be corrupted, this ideal protocol
+must be secure.
+
+In the real world there is no IF, but VIFF allows you to implement a
+virtual ideal functionality. The behavior of a bunch of programs using
+VIFF is indistinguishable from program running in the ideal world. It
+is indistinguishable in the sense that everything that can happen in
+the real world protocol could happen in the ideal world too. And since
+no attacks can occur in the ideal world, no attacks can occur in the
+real world as well. Such a multi-party computation (MPC) is called a
+secure multi-party computation (SMPC).
+
+Security Assumptions
+--------------------
+
+Please note that like all cryptographic systems, VIFF is only secure
+as long as certain assumptions are fulfilled. These assumptions
+include:
+
+- The adversary can only corrupt up to a certain threshold of the
+  total number of players. The threshold will normally be 1/2 of the
+  players, so for three players, at most one player may be corrupted
+  (there must be an honest majority).
+
+- The adversary is computationally bounded. The protocols used by VIFF
+  rely on certain computational hardness assumptions, and therefore
+  only polynomial time adversaries are allowed.
+
+- The adversary is passive. Being passive means that the adversary
+  only monitors the network traffic, but still follows the protocol.
+  We plan to add support for active (Byzantine) adversaries in a
+  future version.
+
+The precise assumptions for each protocol will eventually be included
+in the documentation for the corresponding method, but this has not
+yet been done.
+
+Architecture
+------------
+
+VIFF consists of several modules. The :mod:`viff.runtime` module
+contains the :class:`Runtime <viff.runtime.Runtime>` and :class:`Share
+<viff.runtime.Share>` classes, in which the main functionality is
+implemented. The :mod:`viff.field` module contains implementations of
+finite fields --- these are the values inside the shares. Other
+modules provide support functions.
+
+Layers
+""""""
+
+The main functionality in VIFF is implemented in the :class:`Runtime
+<viff.runtime.Runtime>` class. This class offers methods to do
+addition, multiplication, etc. These methods operate on :class:`Share
+<viff.runtime.Share>` instances.
+
+Shares hold either :class:`GFElement <viff.field.GF>` or :class:`GF256
+<viff.field.GF256>` elements and are created from the
+:meth:`shamir_share <viff.runtime.Runtime.shamir_share>` or
+:meth:`prss_share <viff.runtime.Runtime.prss_share>` :class:`Runtime
+<viff.runtime.Runtime>` methods. Shares overload the standard
+arithmetic operators, so you can write ``a + b - c * d`` with four
+shares, and it will be translated correctly into the appropriate
+method calls on the :class:`Runtime <viff.runtime.Runtime>` associated
+with the shares.
+
+A field element contain the concrete value on which we do
+calculations. This is just a normal Python (long) integer. The value
+is wrapped in an object that will keep track of doing modulo
+reductions as appropriate.
+
+So in a nutshell, VIFF has these layers:
+
+- Top-level layer for application programs: There you manipulate
+  Python integers or :class:`viff.runtime.Share` instances.
+
+- Runtime layer: The runtime deals with Python integers or shares.
+
+- Field elements: Deals with arithmetic over Python integers, but with
+  modulo reductions as needed.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/program-counters.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,202 @@
+
+.. _program-counters:
+
+Program Counters
+================
+
+When two players execute a large computation they need to agree with
+each other on a labelling of the individual operations so that they
+know where each received result belongs. In VIFF we call these labels
+*program counters*. We will try to explain the design of these
+counters in this document and list some ideas for alternative
+implementations.
+
+The basic setup in VIFF is a set of players who communicate over
+reliable point-to-point links, e.g., TCP or SSL connections. It is
+important to remember that these links guarantee that all transmitted
+messages arrive unchanged at the destination and that they arrive in
+the order sent.
+
+
+The naive solution
+------------------
+
+The very first version of VIFF network data was numbered in the most
+naive way possible: using a single counter for each player. This
+worked fine most of the time, but once in a while a test would fail to
+give the correct result. It was only when one ran thousands of
+multiplications that the bug appeared, but its cause was quite simple.
+Consider a program like this where we assume that the shares *a*, *b*,
+*c*, and *d* have already been correctly defined::
+
+  x = mul(a, b)
+  y = mul(c, d)
+
+Back then, the :func:`mul` function was implemented like this::
+
+  def mul(share_a, share_b):
+      inc_pc()
+      result = gather_shares([share_a, share_b])
+      result.addCallback(lambda (a, b): a * b)
+      result.addCallback(shamir_share)
+      result.addCallback(recombine, threshold=2*threshold)
+      return result
+
+where :func:`inc_pc` took care of incrementing the global program
+counter. This simple implementation worked 99.99% of the time with
+three players connected on a LAN, but once in a while it would fail to
+calculate the correct results.
+
+In our example program, :func:`shamir_share` is called twice: once
+when *a* and *b* are ready, and once when *c* and *d* are ready. Most
+of the time *a* and *b* are ready first on all players, and so they
+all agree on the program counter value for this call to
+:func:`shamir_share`. But when we have bad luck, they one player sees
+*c* and *d* arrive first and so the two calls to :func:`shamir_share`
+are switched for that player.
+
+The problem is the asynchronous nature of Twisted: all players agree
+on the execution tree, but depending on the exact timing they might
+reach the nodes in the tree in a different order. The tree looks like
+this in our little example:
+
+.. code-block:: none
+
+     x       y
+     |       |
+    mul     mul
+    / \     / \
+   a   b   c   d
+
+and the two :func:`mul` can be called in either order since they do
+not depend on each other.
+
+
+The working solution
+--------------------
+
+The solution used now in VIFF has two ingredients. First, callbacks
+that depend on the program counter (like `func`:shamir_share in our
+example above) are not added with :meth:`addCallback` but instead with
+the special :meth:`viff.runtime.BasicRuntime.schedule_callback`
+method. This method saves the program counter in effect at the time of
+the its call, and ensures that the saved program counter is
+temporarily made active when the callback is called.
+
+Secondly, the program counter is a *list* of counters. This is
+necessary to ensure that we can allocate new fresh counters at any
+point in the execution tree. The execution tree is never explicitly
+constructed in VIFF, so a simple static numbering is not possible.
+
+Instead we mark methods that need to increment the program counter
+with the :func:`viff.runtime.increment_pc` decorator. The program
+counter starts at the value ``[0]`` and the decorated method will now
+begin by doing::
+
+  self.program_counter[-1] += 1
+  self.program_counter.append(0)
+
+before it executes its body. When the body is finished, the method
+does::
+
+  self.program_counter.pop()
+
+before it returns. A method :meth:`foo` defined like this::
+
+  @increment_pc
+  def foo(self):
+      print "foo:", self.program_counter
+
+is thus turned into this::
+
+  def foo(self):
+      self.program_counter[-1] += 1
+      self.program_counter.append(0)
+      print "foo:", self.program_counter
+      self.program_counter.pop()
+
+and when executed starting from the initial program counter of ``[0]``
+we see that it prints ``foo: [1, 0]`` and leaves the program counter
+at ``[1]`` after it returns. It is very important that the program
+counter is left changed like this, for this means that the next call
+to :meth:`foo` will print ``foo: [2, 0]`` and increment the program
+counter to ``[2]``.
+
+If we have a method :meth:`bar` which calls :meth:`foo` several times::
+
+  @increment_pc
+  def bar(self):
+      print "bar:", self.program_counter
+      self.foo()
+      print "bar:", self.program_counter
+      self.foo()
+      print "bar:", self.program_counter
+
+then the result of calling :meth:`bar` will be:
+
+.. code-block:: none
+
+   bar: [1, 0]
+   foo: [1, 1, 0]
+   bar: [1, 1]
+   foo: [1, 2, 0]
+   bar: [1, 2]
+
+Notice how each sub-call adds another digit to the counter and how it
+increments the counter used at the level of the caller. This system
+ensures that all program counters are unique.
+
+
+Alternatives
+------------
+
+We have come up with some alternative solutions, which are detailed
+below. More good ideas are of course welcome!
+
+History-based labels
+""""""""""""""""""""
+
+An attractive alternative is to label data sent over the net based on
+its *history*. The idea is that we associate a label ``H(x)`` with
+each variable *x*. The history is defined when new variables are
+defined --- if ``x = a * b``, then we can set ``H(x) = ("mul", H(a),
+H(b))``. To avoid growing the history without bounds we can hash it
+with a cryptographic hash function to bring it down to a fixed size.
+
+The problem with this idea is that we sometimes need to assign a
+history to a variable that depends on no other variables. An example
+of this is the result of a call to :meth:`prss_share
+<viff.runtime.Runtime.prss_share>` which takes no useful arguments. A
+possible solution would be to add some dummy arguments on which the
+history could be based, even though they wont be used by the method.
+So if you would normally call the function :func:`hat` with no
+arguments to get a :class:`Rabbit` object, you have to change your
+code from this::
+
+  rabbit = hat()
+
+to this::
+
+  rabbit = hat(dummy=locals())
+
+where the call to :func:`locals` gives you access to the local
+variables. If the use of :func:`locals` could be hidden this might be
+an acceptable solution.
+
+Using the history of the variables has the big advantage that we label
+each piece of transmitted data with just information that is relevant
+to it: namely its position in the tree formed by the calculation and
+*not* its position in the execution tree formed by the implementation
+in VIFF. This is conceptually cleaner than the current solution.
+
+Program transformation
+""""""""""""""""""""""
+
+Another idea is to solve the labelling problem by having some external
+tool transform the program into one with explicit labels. Each send
+and each receive operation needs to be labelled and the labels much
+match pair-wise.
+
+It is not entirely clear how this should work in the presence of loops
+and if it is possible to implement this in an easier way than the
+current program counters.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/prss.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,12 @@
+
+PRSS Module
+===========
+
+.. automodule:: viff.prss
+
+   .. autoclass:: PRF
+      :members: __call__
+
+   .. autofunction:: prss
+
+   .. autofunction:: generate_subsets
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/runtime.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,88 @@
+
+Runtime Module
+==============
+
+.. automodule:: viff.runtime
+
+   .. autoclass:: Share
+      :members: clone
+
+   .. autoclass:: ShareList
+
+   .. autofunction gather_shares
+
+   .. autoclass:: ShareExchanger
+      :members: sendShare, sendData, loseConnection
+
+      .. attribute:: ShareExchanger.incoming_data
+
+         Data from our peer is put here, either as an empty
+         :class:`Deferred` if we are waiting on input from the player,
+         or the data itself if data is received from the other player
+         before we are ready to use it.
+
+   .. autofunction:: increment_pc
+
+   .. autofunction:: create_runtime
+
+   .. autoclass:: BasicRuntime
+      :members:
+
+      .. attribute:: BasicRuntime.id
+
+         Player ID. This is an integer in the range 1--*n* for *n*
+         players.
+
+      .. attribute:: BasicRuntime.threshold
+
+         Default threshold used by :meth:`Runtime.shamir_share`,
+         :meth:`Runtime.open`, and others.
+
+      .. attribute:: BasicRuntime.program_counter
+
+         Whenever a share is sent over the network, it must be
+         uniquely identified so that the receiving player known what
+         operation the share is a result of. This is done by
+         associating a *program counter* with each operation.
+
+         Keeping the program counter synchronized between all players
+         ought to be easy, but because of the asynchronous nature of
+         network protocols, all players might not reach the same parts
+         of the program at the same time.
+
+         Consider two players *A* and *B* who are both waiting on the
+         variables *a* and *b*. Callbacks have been added to *a* and
+         *b*, and the question is what program counter the callbacks
+         should use when sending data out over the network.
+
+         Let *A* receive input for *a* and then for *b* a little
+         later, and let *B* receive the inputs in reversed order so
+         that the input for *b* arrives first. The goal is to keep the
+         program counters synchronized so that program counter *x*
+         refers to the same operation on all players. Because the
+         inputs arrive in different order at different players,
+         incrementing a simple global counter is not enough.
+
+         Instead, a *tree* is made, which follows the tree of
+         execution. At the top level the program counter starts at
+         ``[0]``. At the next operation it becomes ``[1]``, and so on.
+         If a callback is scheduled (see :meth:`schedule_callback`) at
+         program counter ``[x, y, z]``, any calls it makes will be
+         numbered ``[x, y, z, 1]``, then ``[x, y, z, 2]``, and so on.
+
+         Maintaining such a tree of program counters ensures that
+         different parts of the program execution never reuses the
+         same program counter for different variables.
+
+         The :func:`increment_pc` decorator is responsible for
+         dynamically building the tree as the execution unfolds and
+         :meth:`schedule_callback` is responsible for scheduling
+         callbacks with the correct program counter.
+
+         See :ref:`program-counters` for more background information.
+
+   .. autoclass:: Runtime
+      :members:
+
+   .. autoclass:: ActiveRuntime
+      :members: mul, single_share_random, double_share_random, get_triple, generate_triples, broadcast
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/shamir.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,6 @@
+
+Shamir Module
+=============
+
+.. automodule:: viff.shamir
+   :members:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/util.txt	Tue Apr 29 08:56:59 2008 +0200
@@ -0,0 +1,27 @@
+
+Utility Functions Module
+========================
+
+.. automodule:: viff.util
+   :members:
+
+   .. envvar:: SEED
+
+      The :data:`rand` random generator is seeded using this
+      environment variable, if it is defined.
+
+   .. data:: rand
+
+      All VIFF code uses this random number generator for all
+      randomness needed.
+
+      The generator is by default initialized with a random seed,
+      unless the environment variable :envvar:`SEED` is set to a
+      value, in which case that value is used instead. If
+      :envvar:`SEED` is defined, but empty, then no seed is used and a
+      protocol run cannot be reproduced exactly.
+
+   .. envvar:: VIFF_NO_WRAP
+
+      Setting this environment variable to any value will turn
+      :func:`wrapper` into a no-op.
--- a/epydoc.conf	Mon Apr 28 20:18:55 2008 +0200
+++ b/epydoc.conf	Tue Apr 29 08:56:59 2008 +0200
@@ -11,3 +11,5 @@
 
 graph: classtree
 include-log: yes
+
+external-api: mod, func, data, const, class, exc, meth, attr, exc, file, envvar
--- a/run.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/run.py	Tue Apr 29 08:56:59 2008 +0200
@@ -104,18 +104,12 @@
     # Generate API docs in doc/api.
     epydoc('doc')
 
-    # First PDFLaTeX run...
-    execute(["pdflatex", "--interaction", "nonstopmode", "design-talk.tex"],
-            work_dir="doc/design-talk")
-    # Second run to update the table of contents.
-    execute(["pdflatex", "--interaction", "nonstopmode", "design-talk.tex"],
-            work_dir="doc/design-talk")
-
     # Retrieve the latest version of install.txt and authors.txt from
     # the website repository, and ship them as INSTALL and AUTHORS.
     for filename in ('install.txt', 'authors.txt'):
         url = 'http://hg.viff.dk/viff.dk/raw-file/tip/%s' % filename
-        print "Fetching %s" % url,
+        print "Fetching %s..." % url,
+        sys.stdout.flush()
         urlretrieve(url, filename[:-4].upper())
         print "done."
 
@@ -132,7 +126,7 @@
     target = "%s/api" % build
     ensure_dir(target)
     execute(["epydoc", "-vv", "--config", "epydoc.conf"],
-            {'EPYDOC': 'YES', 'target': target})
+            {'VIFF_NO_WRAP': 'YES', 'target': target})
 
 @command('coverage', 'build')
 def coverage(build):
--- a/viff/config.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/viff/config.py	Tue Apr 29 08:56:59 2008 +0200
@@ -15,19 +15,21 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-"""Functions for loading and saving player configurations.
+"""Functions for loading and saving player configurations. Each player
+participating in a protocol execution must know some information about
+the other players, namely their hostname and port number. The player
+also needs to know something about itself, namely the keys used for
+pseudo-random secret sharing (PRSS).
 
-Each player participating in a protocol execution must know some
-information about the other players, namely their hostname and port
-number. The player also needs to know something about itself, namely
-the keys used for pseudo-random secret sharing (PRSS).
+The :class:`Player` class encapsulates this information. Generating a
+player configuration is done using the :func:`generate_configs`
+function. The :file:`generate_config_files.py` script uses that
+function to generate a player config and save it in a number of
+:file:`.ini` files. Such a :file:`.ini` file can be loaded with the
+:func:`load_config` function.
+"""
 
-The L{Player} class encapsulates this information. Generating a player
-configuration is done using the L{generate_configs} function. The
-C{apps/generate_config_files.py} script uses that function to generate
-a player config and save it in a number of .ini files. Such a .ini
-file can be loaded with the L{load_config} function.
-"""
+__docformat__ = "restructuredtext"
 
 from configobj import ConfigObj
 
@@ -53,8 +55,8 @@
         of a pseudo-random secret sharing for sharing an element
         random to all players.
 
-        @return: mapping from player subsets to L{PRF} instances.
-        @returntype: L{dict} from L{frozenset} to L{PRF} instances.
+        Return a mapping from player subsets to :class:`viff.prss.PRF`
+        instances.
         """
         prfs = {}
         for subset, key in self.keys.iteritems():
@@ -68,8 +70,8 @@
         The pseudo-random functions are used when this player is the
         dealer in a pseudo-random secret sharing.
 
-        @return: mapping from player subsets to L{PRF} instances.
-        @returntype: L{dict} from L{frozenset} to L{PRF} instances.
+        Return a mapping from player subsets to :class:`viff.prss.PRF`
+        instances.
         """
         dealers = {}
         for dealer, keys in self.dealer_keys.iteritems():
@@ -95,8 +97,8 @@
     One of the players own the config file and for this player
     additional information on PRSS keys is available.
 
-    @return: owner ID and a mapping of player IDs to players.
-    @returntype: C{int}, C{dict} from C{int} to L{Player} instances.
+    Returns the owner ID and a mapping of player IDs to
+    :class:`Player` instances.
     """
 
     def s_unstr(str):
@@ -149,16 +151,14 @@
 def generate_configs(n, t, addresses=None, prefix=None):
     """Generate player configurations.
 
-    The configurations are returned as C{ConfigObj}s and can be saved
-    to disk if desired.
+    Generates *n* configuration objects with a threshold of *t*. The
+    *addresses* is an optional list of ``(host, port)`` pairs and
+    *prefix* is a filename prefix.
 
-    @param n: number of players.
-    @param t: threshold.
-    @param addresses: list of (host, port) pairs.
-    @param prefix: filename prefix.
+    The configurations are returned as :class:`ConfigObj` instances
+    and can be saved to disk if desired.
 
-    @return: mapping from player id to player configuration.
-    @returntype: C{dict} from C{int} to C{ConfigObj}.
+    Returns a mapping from player ID to player configuration.
     """
     players = frozenset(range(1, n+1))
     max_unqualified_subsets = generate_subsets(players, n-t)
--- a/viff/field.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/viff/field.py	Tue Apr 29 08:56:59 2008 +0200
@@ -15,11 +15,10 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-"""Modeling of Galois (finite) fields.
-
-The GF function creates classes which implements Galois (finite)
-fields of prime order whereas the GF256 class implements the the
-GF(2^8) field with characteristic 2.
+"""Modeling of Galois (finite) fields. The GF function creates classes
+which implements Galois (finite) fields of prime order whereas the
+:class:`GF256` class implements the the GF(2^8) field with
+characteristic 2.
 
 All fields work the same: instantiate an object from a field to get
 hold of an element of that field. Elements implement the normal
@@ -47,7 +46,7 @@
 {12}
 
 Square roots can be found for elements based on GF fields with a Blum
-prime modulus (see L{GF} for more information):
+prime modulus (see :func:`GF` for more information):
 
 >>> x.sqrt()
 {3}
@@ -62,10 +61,13 @@
     ...
 TypeError: unsupported operand type(s) for +: 'GFElement' and 'GFElement'
 
-The reason for the slightly confusing error message is that C{x} and
-C{z} are instances of two I{different} classes called C{GFElement}.
+The reason for the slightly confusing error message is that ``x`` and
+``z`` are instances of two *different* classes called ``GFElement``.
 """
 
+__docformat__ = "restructuredtext"
+
+
 from gmpy import mpz
 
 
@@ -75,15 +77,15 @@
 
 #: Logarithm table.
 #:
-#: Maps a value M{x} to M{log3(x)}. See L{_generate_tables}.
+#: Maps a value *x* to *log3(x)*. See `_generate_tables`.
 _log_table = {}
 #: Exponentiation table.
 #:
-#: Maps a value M{y} to M{3^y}. See L{_generate_tables}.
+#: Maps a value *y* to *3^y*. See `_generate_tables`.
 _exp_table = {}
 #: Inversion table.
 #:
-#: Maps a value M{x} to M{x^-1}. See L{_generate_tables}.
+#: Maps a value *x* to *x^-1*. See `_generate_tables`.
 _inv_table = {}
 
 
@@ -91,10 +93,10 @@
     """Generate tables with logarithms, antilogarithms (exponentials)
     and inverses.
 
-    This updates the L{_log_table}, L{_exp_table}, and L{_inv_table}
-    fields. The generator used is 0x03.
+    This updates the `_log_table`, `_exp_table`, and `_inv_table`
+    fields. The generator used is ``0x03``.
 
-    Code adapted from U{http://www.samiam.org/galois.html}.
+    Code adapted from http://www.samiam.org/galois.html.
     """
     a = 1
     for c in range(255):
@@ -164,7 +166,7 @@
     #: Subtract this and another GF256 element.
     #:
     #: Addition is its own inverse in GF(2^8) and so this is the same
-    #: as L{__add__}.
+    #: as `__add__`.
     __sub__ = __add__
     #: Subtract this and another GF256 element (reflected argument version).
     __rsub__ = __sub__
@@ -209,22 +211,14 @@
         return result
 
     def __div__(self, other):
-        """Division.
-
-        @param other: right-hand side.
-        @type other: GF256 element
-        """
+        """Division."""
         return self * ~other
 
     __truediv__ = __div__
     __floordiv__ = __div__
 
     def __rdiv__(self, other):
-        """Division (reflected argument version).
-
-        @param other: the left-hand side.
-        @type other: integer
-        """
+        """Division (reflected argument version)."""
         return GF256(other) / self
 
     __rtruediv__ = __rdiv__
@@ -237,7 +231,7 @@
     def __invert__(self):
         """Invertion.
 
-        @raise ZeroDivisionError: if trying to inverse the zero
+        Raises :exc:`ZeroDivisionError` if trying to inverse the zero
         element.
         """
         if self.value == 0:
--- a/viff/matrix.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/viff/matrix.py	Tue Apr 29 08:56:59 2008 +0200
@@ -15,14 +15,15 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-"""Matrix operations.
+"""Matrix operations. This module contains basic matrix operations as
+well as a function to build square hyper-invertible matrices. The
+matrix implementation provides operator overloading and works with any
+type that acts like a number, including :class:`viff.field.GF256` and
+:func:`viff.field.GF` elements.
+"""
 
-This module contains basic matrix operations as well as a function to
-build square hyper-invertible matrices. The matrix implementation
-provides operator overloading and works with any type that acts like a
-number, including L{viff.field.GF256} and L{viff.field.GF} elements.
+__docformat__ = "restructuredtext"
 
-"""
 
 from __future__ import division
 
@@ -31,11 +32,7 @@
     """A matrix."""
 
     def _init_zeros(self, m, n):
-        """Initialize a new m times n matrix containing zeros.
-
-        @param m: The number of rows.
-        @param n: The number of columns.
-        """
+        """Initialize a new zero matrix with *m* rows and *n* columns."""
         self.rows = [[0 for _ in range(n)] for _ in range(m)]
         self.m = m
         self.n = n
@@ -43,7 +40,7 @@
     def _init_set(self, rows):
         """Initializes a matrix to contain specific values.
 
-        @param rows: The rows of the matrix, given as a list of lists.
+        The *rows* is a list of lists.
         """
         self.rows = rows
         self.m = len(rows)
@@ -52,9 +49,9 @@
     def __init__(self, *args):
         """Initializates a matrix.
 
-        @param args: Either a number m and n counting rows and columns
-        of an all-zero matrix, or a list of lists representing the
-        rows of the matrix.
+        The arguments can be either a number *m* and *n* counting rows
+        and columns of an all-zero matrix, or a list of lists
+        representing the rows of the matrix.
         """
         if len(args) == 1:
             self._init_set(*args)
@@ -62,7 +59,7 @@
             self._init_zeros(*args)
 
     def __setitem__(self, (i, j), value):
-        """Allows matrix entry assignment using C{[,]}.
+        """Allows matrix entry assignment using ``[,]``.
 
         The assignment works as follows:
 
@@ -71,24 +68,17 @@
         >>> print M
         [[ 0 42]
          [ 0  0]]
-
-        param i: The entry row.
-        param j: The entry column.
-        param value: The value to store in the entry.
         """
         self.rows[i][j] = value
 
     def __getitem__(self, (i, j)):
-        """Allows matrix entry access using C{[, ]}.
+        """Allows matrix entry access using ``[, ]``.
 
         The access works as follows:
 
         >>> M = Matrix([[1, 2], [3, 4]])
         >>> print M[1,1]
         4
-
-        @param i: The entry row.
-        @param j: The entry column.
         """
         return self.rows[i][j]
 
@@ -108,9 +98,6 @@
         >>> print A + A
         [[0 2]
          [4 6]]
-
-        @param other: The matrix or element to add to this one.
-        @return: The sum.
         """
         # we should check that the two matrices have the same size
         result = Matrix(self.m, self.n)
@@ -133,9 +120,6 @@
         >>> print 10 + Matrix([[0, 1], [2, 3]])
         [[10 11]
          [12 13]]
-
-        @param other: The element to which the matrix will be added.
-        @return: The sum.
         """
         result = Matrix(self.m, self.n)
         for i in range(0, self.m):
@@ -166,9 +150,6 @@
         Traceback (most recent call last):
             ...
         ValueError: Matrix dimensions do not match for multiplication
-
-        @param other: The matrix or element to multiply with this one.
-        @return: The product.
         """
 
         if not isinstance(other, Matrix):
@@ -198,9 +179,6 @@
         >>> print 10 * Matrix([[0, 1], [2, 3]])
         [[ 0 10]
          [20 30]]
-
-        @param other: The element with which the matrix will be multiplied.
-        @return: The product.
         """
         result = Matrix(self.m, self.n)
         for i in range(0, self.m):
@@ -216,8 +194,6 @@
          [ 4  5  6  7]
          [ 8  9 10 11]
          [12 13 14 15]]
-
-        @return: A string representation of the matrix.
         """
         width = max([len(str(elem)) for row in self.rows for elem in row])
         output = [" ".join(["%*s" % (width, e) for e in r]) for r in self.rows]
@@ -236,8 +212,6 @@
         [[0 3 6]
          [1 4 7]
          [2 5 8]]
-
-        @return: The transpose of the matrix.
         """
         result = Matrix(self.n, self.m)
         for i in range(self.m):
@@ -247,11 +221,7 @@
         return result
 
     def determinant(mat):
-        """Calculates the determinant of a matrix.
-
-        @param mat: A square matrix.
-        @return: The determinant of the matrix.
-        """
+        """Calculates the determinant of a square matrix."""
         if mat.m == 1:
             return mat[0, 0]
         if mat.m == 2:
@@ -271,7 +241,8 @@
 
 
 def hyper(n, field):
-    """Makes a hyper-invertible square matrix.
+    """Makes an *n* times *n* hyper-invertible square matrix.
+    The matrix entries will belong to *field*.
 
     A hyper-invertible matrix is a matrix where every sub-matrix is
     invertible. A sub-matrix consists of an arbitrary subset of the
@@ -287,10 +258,6 @@
     [[ {1} {44}  {3}]
      [ {3} {39}  {6}]
      [ {6} {32} {10}]]
-
-    @param n: The dimension of the matrix (it will be n times n).
-    @param field: The field to use. Expected to be a Zp field.
-    @return: A hyper-invertible square matrix.
     """
     result = Matrix(n, n)
     for i in range(0, n):
--- a/viff/prss.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/viff/prss.py	Tue Apr 29 08:56:59 2008 +0200
@@ -1,4 +1,4 @@
-# Necessary because of the 'å' in 'Damgård': -*- coding: latin-1 -*-
+# -*- coding: utf-8 -*-
 #
 # Copyright 2007, 2008 VIFF Development Team.
 #
@@ -17,29 +17,32 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-"""Methods for pseudo-random secret sharing.
-
-Normal Shamir sharing (see the L{shamir} module) requires secure
-channels between the players for distributing shares. With
-pseudo-random secret sharing one can share a secret using a single
-broadcast instead.
+u"""Methods for pseudo-random secret sharing. Normal Shamir sharing
+(see the :mod:`viff.shamir` module) requires secure channels between
+the players for distributing shares. With pseudo-random secret sharing
+one can share a secret using a single broadcast instead.
 
 PRSS relies on each player having access to a set of previously
 distributed pseudo-random functions (PRFs) --- or rather the seeds for
-such functions. In VIFF, such seeds are generated by the
-L{config.generate_configs} function and the L{config.Player.prfs} and
-L{config.Player.dealer_prfs} methods give access to the PRFs.
+such functions. In VIFF, such seeds are generated by
+:func:`viff.config.generate_configs`. The
+:meth:`viff.config.Player.prfs` and
+:meth:`viff.config.Player.dealer_prfs` methods give access to the
+PRFs.
 
-In this module the function L{prss} is used to calculate shares for a
-pseudo-random number. The L{generate_subsets} is a general utility
-method for generating subsets of a specific size.
+In this module the function :func:`prss` is used to calculate shares
+for a pseudo-random number. The :func:`generate_subsets` function is a
+general utility for generating subsets of a specific size.
 
 The code is based on the paper "Share Conversion, Pseudorandom
 Secret-Sharing and Applications to Secure Computation" by Ronald
-Cramer, Ivan Damgård, and Yuval Ishai in Proc. of TCC 2005, LNCS 3378.
-U{Download <http://www.cs.technion.ac.il/~yuvali/pubs/CDI05.ps>}.
+Cramer, Ivan Damgård, and Yuval Ishai in Proc. of TCC 2005, LNCS 3378.
+`Download <http://www.cs.technion.ac.il/~yuvali/pubs/CDI05.ps>`__.
 """
 
+__docformat__ = "restructuredtext"
+
+
 import sha
 from math import ceil
 from struct import pack
@@ -53,8 +56,9 @@
 def prss(n, j, field, prfs, key):
     """Return a pseudo-random secret share for a random number.
 
-    The share is for player j based on the pseudo-random functions
-    given. The key is used when evaluating the PRFs.
+    The share is for player *j* based on the pseudo-random functions
+    given in *prfs* (a mapping from subsets of players to :class:`PRF`
+    instances). The *key* is used when evaluating the PRFs.
 
     An example with (n,t) = (3,1) and a modulus of 31:
 
@@ -71,12 +75,7 @@
     {18}
 
     We see that the sharing is consistent because each subset of two
-    players will recombine their shares to {29}.
-
-    @param n: number of players.
-    @param j: id of dealing player.
-    @param field: field to use.
-    @param prfs: mapping from subsets of players to L{PRF} instances.
+    players will recombine their shares to ``{29}``.
     """
     result = 0
     all = frozenset(range(1, n+1))
--- a/viff/runtime.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/viff/runtime.py	Tue Apr 29 08:56:59 2008 +0200
@@ -1,4 +1,5 @@
-# Necessary because of the 'å' in 'Damgård': -*- coding: latin-1 -*-
+# -*- coding: utf-8 -*-
+#
 # Copyright 2007, 2008 VIFF Development Team.
 #
 # This file is part of VIFF, the Virtual Ideal Functionality Framework.
@@ -16,22 +17,22 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-"""VIFF runtime.
-
-This is where the virtual ideal functionality is hiding! The runtime
-is responsible for sharing inputs, handling communication, and running
-the calculations.
+"""VIFF runtime. This is where the virtual ideal functionality is
+hiding! The runtime is responsible for sharing inputs, handling
+communication, and running the calculations.
 
 Each player participating in the protocol will instantiate a
-L{Runtime} object and use it for the calculations.
+:class:`Runtime` object and use it for the calculations.
 
-The Runtime returns L{Share} objects for most operations, and these
-can be added, subtracted, and multiplied as normal thanks to
+The Runtime returns :class:`Share` objects for most operations, and
+these can be added, subtracted, and multiplied as normal thanks to
 overloaded arithmetic operators. The runtime will take care of
 scheduling things correctly behind the scenes.
 """
 from __future__ import division
 
+__docformat__ = "restructuredtext"
+
 import marshal
 from optparse import OptionParser, OptionGroup
 from math import ceil
@@ -52,22 +53,22 @@
 class Share(Deferred):
     """A shared number.
 
-    The L{Runtime} operates on shares, represented by this class.
+    The :class:`Runtime` operates on shares, represented by this class.
     Shares are asynchronous in the sense that they promise to attain a
     value at some point in the future.
 
-    Shares overload the arithmetic operations so that C{x = a + b}
-    will create a new share C{x}, which will eventually contain the
-    sum of C{a} and C{b}. Each share is associated with a L{Runtime}
-    and the arithmetic operations simply call back to that runtime.
+    Shares overload the arithmetic operations so that ``x = a + b``
+    will create a new share *x*, which will eventually contain the
+    sum of *a* and *b*. Each share is associated with a
+    :class:`Runtime` and the arithmetic operations simply call back to
+    that runtime.
     """
 
     def __init__(self, runtime, field, value=None):
         """Initialize a share.
 
-        @param runtime: The L{Runtime} to use.
-        @param field: The field where the value lies.
-        @param value: The initial value of the share (if known).
+        If an initial value is given, it will be passed to
+        :meth:`callback` right away.
         """
         assert field is not None, "Cannot construct share without a field."
         assert callable(field), "The field is not callable, wrong argument?"
@@ -133,8 +134,8 @@
     def clone(self):
         """Clone a share.
 
-        Works like L{util.clone_deferred} except that it returns a new
-        Share instead of a Deferred.
+        Works like :meth:`util.clone_deferred` except that it returns a new
+        :class:`Share` instead of a :class:`Deferred`.
         """
 
         def split_result(result):
@@ -148,11 +149,12 @@
 class ShareList(Share):
     """Create a share that waits on a number of other shares.
 
-    Roughly modelled after the Twisted C{DeferredList} class. The
-    advantage of this class is that it is a L{Share} (not just a
-    C{Deferred}) and that it can be made to trigger when a certain
-    threshold of the shares are ready. This example shows how the
-    C{pprint} callback is triggered when C{a} and C{c} are ready:
+    Roughly modelled after the Twisted :class:`DeferredList`
+    class. The advantage of this class is that it is a :class:`Share`
+    (not just a :class:`Deferred`) and that it can be made to trigger
+    when a certain threshold of the shares are ready. This example
+    shows how the :meth:`pprint` callback is triggered when *a* and
+    *c* are ready:
 
     >>> from pprint import pprint
     >>> from viff.field import GF256
@@ -166,24 +168,22 @@
     >>> c.callback(20)
     [(True, 10), None, (True, 20)]
 
-    The C{pprint} function is called with a list of pairs. The first
+    The :meth:`pprint` function is called with a list of pairs. The first
     component of each pair is a boolean indicating if the callback or
-    errback method was called on the corresponding L{Share}, and the
-    second component is the value given to the callback/errback.
+    errback method was called on the corresponding :class:`Share`, and
+    the second component is the value given to the callback/errback.
 
     If a threshold less than the full number of shares is used, some
-    of the pairs may be missing and C{None} is used instead. In the
-    example above the C{b} Share arrived later than C{a} and C{c}, and
-    so the list contains a C{None} on its place.
+    of the pairs may be missing and :const:`None` is used instead. In
+    the example above the *b* share arrived later than *a* and *c*,
+    and so the list contains a :const:`None` on its place.
     """
-
     def __init__(self, shares, threshold=None):
         """Initialize a share list.
 
-        @param shares: non-empty list of L{Share} objects.
-        @param threshold: number of shares to wait for. This is either
-        a number such that C{0 < threshold <= len(shares)} or C{None}
-        if all shares should be waited for.
+        The list of shares must be non-empty and if a threshold is
+        given, it must hold that ``0 < threshold <= len(shares)``. The
+        default threshold is ``len(shares)``.
         """
         assert len(shares) > 0, "Cannot create empty ShareList"
         assert threshold is None or 0 < threshold <= len(shares), \
@@ -213,10 +213,10 @@
 def gather_shares(shares):
     """Gather shares.
 
-    Roughly modelled after the Twisted C{gatherResults} function. It
-    takes a list of shares and returns a new L{Share} which will be
-    triggered with a list of values, namely the values from the
-    initial shares:
+    Roughly modelled after the Twisted :meth:`gatherResults`
+    function. It takes a list of shares and returns a new
+    :class:`Share` which will be triggered with a list of values,
+    namely the values from the initial shares:
 
     >>> from pprint import pprint
     >>> from viff.field import GF256
@@ -228,9 +228,6 @@
     >>> a.callback(10)
     >>> b.callback(20)
     [10, 20]
-
-    @param shares: the shares.
-    @type shares: C{list} of L{Share} objects
     """
 
     def filter_results(results):
@@ -247,22 +244,14 @@
     Twisted protocol is one such connection. It is used to send and
     receive shares from one other player.
 
-    The C{marshal} module is used for converting the data to bytes for
-    the network and to convert back again to structured data.
+    The :mod:`marshal` module is used for converting the data to bytes
+    for the network and to convert back again to structured data.
     """
 
     def __init__(self):
         self.peer_id = None
 
         #: Data expected to be received in the future.
-        #:
-        #: Data from our peer is put here, either as an empty Deferred
-        #: if we are waiting on input from the player, or the data
-        #: itself if data is received from the other player before we
-        #: are ready to use it.
-        #:
-        #: @type: C{dict} from C{(program_counter, data_type)} to
-        #: deferred data.
         self.incoming_data = {}
 
     def connectionMade(self):
@@ -277,11 +266,7 @@
 
         The string received is unmarshalled into the program counter,
         and a data part. The data is passed the appropriate Deferred
-        in L{self.incoming_data}.
-
-        @param string: bytes from the network.
-        @type string: C{(program_counter, data)} in
-        marshalled form
+        in :class:`self.incoming_data`.
         """
         if self.peer_id is None:
             # TODO: Handle ValueError if the string cannot be decoded.
@@ -319,9 +304,6 @@
 
         The program counter and the share are marshalled and sent to
         the peer.
-
-        @param program_counter: the program counter associated with
-        the share.
         """
         self.sendData(program_counter, "share", share.value)
 
@@ -350,13 +332,11 @@
 
 
 def increment_pc(method):
-    """Make method automatically increment the program counter.
+    """Make *method* automatically increment the program counter.
 
-    Adding this decorator to a L{Runtime} method will ensure that the
-    program counter is incremented correctly when entering the method.
-
-    @param method: the method.
-    @type method: a method of L{Runtime}
+    Adding this decorator to a :class:`Runtime` method will ensure
+    that the program counter is incremented correctly when entering
+    the method.
     """
 
     @wrapper(method)
@@ -374,15 +354,14 @@
     """Track calls to this method.
 
     The decorated method will be replaced with a proxy method which
-    first tries to get the data needed from C{self._pool}, and if that
-    fails it falls back to the original method.
+    first tries to get the data needed from
+    :attr:`BasicRuntime._pool`, and if that fails it falls back to the
+    original method.
 
-    The C{generator} method is only used to record where the data
-    should be generated from, the method is not actually called.
-
-    @param generator: Use this method as the generator for
-    pre-processed data.
-    @type generator: C{str}
+    The *generator* method is only used to record where the data
+    should be generated from, the method is not actually called. This
+    must be the name of the method (a string) and not the method
+    itself.
     """
 
     def preprocess_decorator(method):
@@ -447,8 +426,8 @@
         Initialized a runtime owned by the given, the threshold, and
         optionally a set of options. The runtime has no network
         connections and knows of no other players -- the
-        L{create_runtime} function should be used instead to create a
-        usable runtime.
+        :func:`create_runtime` function should be used instead to
+        create a usable runtime.
         """
         assert threshold > 0, "Must use a positive threshold."
         #: ID of this player.
@@ -473,64 +452,23 @@
         self._needed_data = {}
 
         #: Current program counter.
-        #:
-        #: Whenever a share is sent over the network, it must be
-        #: uniquely identified so that the receiving player known what
-        #: operation the share is a result of. This is done by
-        #: associating a X{program counter} with each operation.
-        #:
-        #: Keeping the program counter synchronized between all
-        #: players ought to be easy, but because of the asynchronous
-        #: nature of network protocols, all players might not reach
-        #: the same parts of the program at the same time.
-        #:
-        #: Consider two players M{A} and M{B} who are both waiting on
-        #: the variables C{a} and C{b}. Callbacks have been added to
-        #: C{a} and C{b}, and the question is what program counter the
-        #: callbacks should use when sending data out over the
-        #: network.
-        #:
-        #: Let M{A} receive input for C{a} and then for C{b} a little
-        #: later, and let M{B} receive the inputs in reversed order so
-        #: that the input for C{b} arrives first. The goal is to keep
-        #: the program counters synchronized so that program counter
-        #: M{x} refers to the same operation on all players. Because
-        #: the inputs arrive in different order at different players,
-        #: incrementing a simple global counter is not enough.
-        #:
-        #: Instead, a I{tree} is made, which follows the tree of
-        #: execution. At the top level the program counter starts at
-        #: C{[0]}. At the next operation it becomes C{[1]}, and so on.
-        #: If a callback is scheduled (see L{schedule_callback}) at
-        #: program counter C{[x, y, z]}, any calls it makes will be
-        #: numbered C{[x, y, z, 1]}, then C{[x, y, z, 2]}, and so on.
-        #:
-        #: Maintaining such a tree of program counters ensures that
-        #: different parts of the program execution never reuses the
-        #: same program counter for different variables.
-        #:
-        #: The L{increment_pc} decorator is responsible for
-        #: dynamically building the tree as the execution unfolds and
-        #: L{schedule_callback} is responsible for scheduling
-        #: callbacks with the correct program counter.
-        #:
-        #: @type: C{list} of integers.
         self.program_counter = [0]
 
         #: Connections to the other players.
         #:
-        #: @type: C{dict} from Player ID to L{ShareExchanger} objects.
+        #: Mapping from from Player ID to :class:`ShareExchanger`
+        #: objects.
         self.protocols = {}
 
         #: Number of known players.
         #:
-        #: Equal to C{len(players)}, but storing it here is more
+        #: Equal to ``len(self.players)``, but storing it here is more
         #: direct.
         self.num_players = 0
 
         #: Information on players.
         #:
-        #: @type: C{dict} from player_id to L{Player} objects.
+        #: Mapping from Player ID to :class:`Player` objects.
         self.players = {}
         # Add ourselves, but with no protocol since we wont be
         # communicating with ourselves.
@@ -563,9 +501,6 @@
         """Make the runtime wait for the variables given.
 
         The runtime is shut down when all variables are calculated.
-
-        @param vars: variables to wait for.
-        @type  vars: list of L{Deferred}s
         """
         dl = DeferredList(vars)
         dl.addCallback(lambda _: self.shutdown())
@@ -581,12 +516,7 @@
         Deferred as usual.
 
         Any extra arguments are passed to the callback as with
-        addCallback.
-
-        @param deferred: the Deferred.
-        @param func: the callback.
-        @param args: extra arguments.
-        @param kwargs: extra keyword arguments.
+        :meth:`addCallback`.
         """
         # TODO, http://tracker.viff.dk/issue22: When several callbacks
         # are scheduled from the same method, they all save the same
@@ -657,25 +587,21 @@
     def preprocess(self, program):
         """Generate preprocess material.
 
-        The C{program} specifies which methods to call and with which
+        The *program* specifies which methods to call and with which
         arguments. The generator methods called must adhere to the
         following interface:
 
-          - They must return a C{(int, Deferred)} tuple where the
-            C{int} tells us how many items of pre-processed data the
-            Deferred will yield.
+        - They must return a ``(int, Deferred)`` tuple where the
+          ``int`` tells us how many items of pre-processed data the
+          :class:`Deferred` will yield.
 
-          - The Deferred must yield a C{list} of the promissed length.
+        - The Deferred must yield a list of the promissed length.
 
-          - The C{list} contains the actual data. This data can be
-            either a Deferred or a C{tuple} of Deferreds.
+        - The list contains the actual data. This data can be either a
+          Deferred or a tuple of Deferreds.
 
-        The L{ActiveRuntime.generate_triples} method is an example of
-        a method fulfilling this interface.
-
-        @param program: A description of the needed data.
-        @type program: C{dict} mapping C{(str, args)} tuples to
-        program counters
+        The :meth:`ActiveRuntime.generate_triples` method is an
+        example of a method fulfilling this interface.
         """
 
         def update(results, program_counters):
@@ -723,18 +649,20 @@
 class Runtime(BasicRuntime):
     """The VIFF runtime.
 
-    The runtime is used for sharing values (L{shamir_share} or
-    L{prss_share}) into L{Share} object and opening such shares
-    (L{open}) again. Calculations on shares is normally done through
-    overloaded arithmetic operations, but it is also possible to call
-    L{add}, L{mul}, etc. directly if one prefers.
+    The runtime is used for sharing values (:meth:`shamir_share` or
+    :meth:`prss_share`) into :class:`Share` object and opening such
+    shares (:meth:`open`) again. Calculations on shares is normally
+    done through overloaded arithmetic operations, but it is also
+    possible to call :meth:`add`, :meth:`mul`, etc. directly if one
+    prefers.
 
-    Each player in the protocol uses a Runtime object. To create an
-    instance and connect it correctly with the other players, please
-    use the L{create_runtime} function instead of instantiating a
-    Runtime directly. The L{create_runtime} function will take care of
-    setting up network connections and return a Deferred which
-    triggers with the Runtime object when it is ready.
+    Each player in the protocol uses a :class:`Runtime` object. To
+    create an instance and connect it correctly with the other
+    players, please use the :func:`create_runtime` function instead of
+    instantiating a Runtime directly. The :func:`create_runtime`
+    function will take care of setting up network connections and
+    return a :class:`Deferred` which triggers with the
+    :class:`Runtime` object when it is ready.
     """
 
     def __init__(self, player, threshold, options=None):
@@ -745,24 +673,13 @@
     def open(self, share, receivers=None, threshold=None):
         """Open a secret sharing.
 
+        The *receivers* are the players that will eventually obtain
+        the opened result. The default is to let everybody know the
+        result. By default the :attr:`threshold` + 1 shares are
+        reconstructed, but *threshold* can be used to override this.
+
         Communication cost: every player sends one share to each
         receiving player.
-
-        @param share: the player's private part of the sharing to open.
-        @type share: Share
-
-        @param receivers: the IDs of the players that will eventually
-            obtain the opened result or None if all players should
-            obtain the opened result.
-        @type receivers: None or a C{list} of integers
-
-        @param threshold: the threshold used to open the sharing or None
-            if the runtime default should be used.
-        @type threshold: integer or None
-
-        @return: the result of the opened sharing if the player's ID
-            is in C{receivers}, otherwise None.
-        @returntype: Share or None
         """
         assert isinstance(share, Share)
         # all players receive result by default
@@ -874,30 +791,20 @@
     @increment_pc
     def prss_share(self, inputters, field, element=None):
         """Creates pseudo-random secret sharings.
+        
+        This protocol creates a secret sharing for each player in the
+        subset of players specified in *inputters*. Each inputter
+        provides an integer. The result is a list of shares, one for
+        each inputter.
 
-        This protocol creates a secret sharing for each player in the
-        subset of players specified in C{inputters}. The protocol uses the
-        pseudo-random secret sharing technique described in the paper "Share
-        Conversion, Pseudorandom Secret-Sharing and Applications to Secure
-        Computation" by Ronald Cramer, Ivan Damgård, and Yuval Ishai in Proc.
-        of TCC 2005, LNCS 3378.
-        U{Download <http://www.cs.technion.ac.il/~yuvali/pubs/CDI05.ps>}.
+        The protocol uses the pseudo-random secret sharing technique
+        described in the paper "Share Conversion, Pseudorandom
+        Secret-Sharing and Applications to Secure Computation" by
+        Ronald Cramer, Ivan Damgård, and Yuval Ishai in Proc. of TCC
+        2005, LNCS 3378. `Download
+        <http://www.cs.technion.ac.il/~yuvali/pubs/CDI05.ps>`__
 
         Communication cost: Each inputter does one broadcast.
-
-        @param inputters: The IDs of the players that will share a secret.
-        @type inputters: C{list} of integers
-
-        @param field: The field over which to share all the secrets.
-        @type field: L{FieldElement}
-
-        @param element: The secret that this player shares or C{None} if this
-            player is not in C{inputters}.
-        @type element: int, long, or None
-
-        @return: A list of shares corresponding to the secrets submitted by
-            the players in C{inputters}.
-        @returntype: C{List} of C{Shares}
         """
         # Verifying parameters.
         if element is None:
@@ -1008,10 +915,10 @@
 
     @increment_pc
     def shamir_share(self, inputters, field, number=None, threshold=None):
-        """Secret share C{number} over C{field} using Shamir's method.
+        """Secret share *number* over *field* using Shamir's method.
 
-        The number is shared using polynomial of degree C{threshold}
-        (defaults to L{self.threshold}). Returns a list of shares
+        The number is shared using polynomial of degree *threshold*
+        (defaults to :attr:`threshold`). Returns a list of shares
         unless unless there is only one inputter in which case the
         share is returned directly.
 
@@ -1062,7 +969,7 @@
     """A runtime secure against active adversaries.
 
     This class currently inherits most of its functionality from the
-    normal L{Runtime} class and is thus I{not} yet secure.
+    normal :class:`Runtime` class and is thus **not** yet secure.
     """
 
     def __init__(self, player, threshold, options=None):
@@ -1070,9 +977,9 @@
 
         #: A hyper-invertible matrix.
         #:
-        #: It should be suitable for L{self.num_players} players, but
+        #: It should be suitable for :attr:`num_players` players, but
         #: since we don't know the total number of players yet, we set
-        #: it to C{None} here and update it as necessary.
+        #: it to :const:`None` here and update it as necessary.
         self._hyper = None
         Runtime.__init__(self, player, threshold, options)
 
@@ -1132,13 +1039,9 @@
         """Share a random secret.
 
         The guarantee is that a number of shares are made and out of
-        those, the T that are returned by this method will be correct
-        sharings of a random number using C{degree} as the polynomial
-        degree.
-
-        @param T: The number of shares output.
-        @param degree: The degree of the polynomial.
-        @param field: The field over which to share the secret.
+        those, the *T* that are returned by this method will be
+        correct sharings of a random number using *degree* as the
+        polynomial degree.
         """
         # TODO: Move common code between single_share and
         # double_share_random out to their own methods.
@@ -1219,14 +1122,9 @@
         """Double-share a random secret using two polynomials.
 
         The guarantee is that a number of shares are made and out of
-        those, the T that are returned by this method will be correct
-        double-sharings of a random number using d1 and d2 as the
+        those, the *T* that are returned by this method will be correct
+        double-sharings of a random number using *d1* and *d2* as the
         polynomial degrees.
-
-        @param T: The number of double-shares output.
-        @param d1: The degree of the first polynomial.
-        @param d2: The degree of the second polynomial.
-        @param field: The field over which to share the secret.
         """
         inputters = range(1, self.num_players + 1)
         if self._hyper is None:
@@ -1330,13 +1228,11 @@
     def generate_triples(self, field):
         """Generate multiplication triples.
 
-        These are random numbers M{a}, M{b}, and M{c} such that M{c =
-        ab}. This function can be used in pre-processing.
+        These are random numbers *a*, *b*, and *c* such that ``c =
+        ab``. This function can be used in pre-processing.
 
-        @return: Number of triples returned and a Deferred which will
-        yield a C{list} of 3-tuples.
-        @returntype: (C{int}, C{list} of Deferred C{(Share, Share,
-        Share)})
+        Returns a tuple with the number of triples generated and a
+        Deferred which will yield a list of 3-tuples.
         """
         n = self.num_players
         t = self.threshold
@@ -1374,9 +1270,6 @@
         the paper "An asynchronous [(n-1)/3]-resilient consensus
         protocol" by G. Bracha in Proc. 3rd ACM Symposium on
         Principles of Distributed Computing, 1984, pages 154-162.
-
-        @param sender: the sender of the broadcast message.
-        @param message: the broadcast message, used only by the sender.
         """
 
         result = Deferred()
@@ -1470,10 +1363,10 @@
     def broadcast(self, senders, message=None):
         """Perform one or more Bracha broadcast(s).
 
-        The list of senders given will determine the subset of players
+        The list of *senders* given will determine the subset of players
         who wish to broadcast a message. If this player wishes to
         broadcast, its ID must be in the list of senders and the
-        optional message parameter must be used.
+        optional *message* parameter must be used.
 
         If the list of senders consists only of a single sender, the
         result will be a single element, otherwise it will be a list.
@@ -1483,10 +1376,6 @@
         the paper "An asynchronous [(n-1)/3]-resilient consensus
         protocol" by G. Bracha in Proc. 3rd ACM Symposium on
         Principles of Distributed Computing, 1984, pages 154-162.
-
-        @param senders: the list of senders.
-        @param message: the broadcast message, used if this player is
-        a sender.
         """
         assert message is None or self.id in senders
 
@@ -1505,7 +1394,7 @@
 
 
 def create_runtime(id, players, threshold, options=None, runtime_class=Runtime):
-    """Create a L{Runtime} and connect to the other players.
+    """Create a :class:`Runtime` and connect to the other players.
 
     This function should be used in normal programs instead of
     instantiating the Runtime directly. This function makes sure that
--- a/viff/shamir.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/viff/shamir.py	Tue Apr 29 08:56:59 2008 +0200
@@ -15,11 +15,13 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-"""Shamir secret sharing and recombination.
+"""Shamir secret sharing and recombination. Based on the paper *How to
+share a secret* by Adi Shamir in *Communications of the ACM* **22**
+(11): 612-613.
+"""
 
-Based on the paper "How to share a secret" by Adi Shamir in
-I{Communications of the ACM} B{22} (11): 612-613.
-"""
+__docformat__ = "restructuredtext"
+
 
 import operator
 from viff.util import rand
@@ -28,6 +30,10 @@
 def share(secret, threshold, num_players):
     """Shamir share secret.
 
+    The *threshold* indicates the maximum number of shares that reveal
+    nothing about *secret*. The return value is a list of ``(player
+    id, share)`` pairs.
+
     It holds that sharing and recombination cancels each other:
 
     >>> from field import GF
@@ -41,25 +47,12 @@
     >>> share(Zp(10), 0, 5)
     [({1}, {10}), ({2}, {10}), ({3}, {10}), ({4}, {10}), ({5}, {10})]
 
-    up to but not including C{num_players}:
+    up to but not including *num_players*:
 
     >>> share(Zp(10), 5, 5)
     Traceback (most recent call last):
       ...
     AssertionError: Threshold out of range
-
-    @param secret: the secret to be shared.
-    @type secret: a field element
-
-    @param threshold: maximum number of shares that reveal nothing
-    about the secret.
-    @type threshold: integer
-
-    @param num_players: number of players.
-    @type num_players: integer
-
-    @return: shares, one for each player.
-    @returntype: C{list} of (player id, share) pairs
     """
     assert threshold >= 0 and threshold < num_players, "Threshold out of range"
 
@@ -93,19 +86,17 @@
 
 #: Cached recombination vectors.
 #:
-#: The recombination vector used by L{recombine} depends only on the
+#: The recombination vector used by `recombine` depends only on the
 #: recombination point and the player IDs of the shares, and so it can
 #: be cached for efficiency.
 _recombination_vectors = {}
 
 
 def recombine(shares, x_recomb=0):
-    """Recombines list of (xi, yi) pairs.
+    """Recombines list of ``(xi, yi)`` pairs.
 
-    Recombination is done in the optional point M{x}.
-
-    @param shares: M{threshold+1} shares.
-    @type shares: C{list} of (player id, share) pairs
+    Shares is a list of *threshold* + 1 ``(player id, share)`` pairs.
+    Recombination is done in the optional point *x_recomb*.
     """
     xs = [x_i for (x_i, _) in shares]
     ys = [y_i for (_, y_i) in shares]
@@ -137,11 +128,6 @@
     True
     >>> verify_sharing(shares, 1)
     False
-    >>>
-
-    @param shares: The shares to be checked.
-    @param degree: The maximum degree of the interpolating polynomial.
-    @return: C{True} if the sharing is correct, otherwise C{False}.
     """
     used_shares = shares[0:degree+1]
     for i in range(degree+1, len(shares)+1):
--- a/viff/util.py	Mon Apr 28 20:18:55 2008 +0200
+++ b/viff/util.py	Tue Apr 29 08:56:59 2008 +0200
@@ -15,14 +15,14 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-"""Miscellaneous utility functions.
+"""Miscellaneous utility functions. This module contains various
+utility functions used in all parts of the VIFF code. The most
+important is the :data:`rand` random generator which is seeded with a
+known seed each time. Using this generator for all random numbers
+ensures that a protocol run can be reproduced at a later time.
+"""
 
-This module contains various utility functions used in all parts of
-the VIFF code. The most important is the L{rand} random generator
-which is seeded with a known seed each time. Using this generator for
-all random numbers ensures that a protocol run can be reproduced at a
-later time.
-"""
+__docformat__ = "restructuredtext"
 
 import os
 import random
@@ -30,7 +30,7 @@
 from twisted.internet.defer import Deferred, succeed, gatherResults
 from gmpy import mpz
 
-#: Seed for L{rand}.
+#: Seed for :data:`rand`.
 _seed = os.environ.get('SEED')
 
 if _seed is None:
@@ -41,8 +41,8 @@
     #: Random number generator used by all VIFF code.
     #:
     #: The generator is by default initialized with a random seed,
-    #: unless the environment variable C{SEED} is set to a value, in
-    #: which case that value is used instead. If C{SEED} is defined,
+    #: unless the environment variable :envvar:`SEED` is set to a value, in
+    #: which case that value is used instead. If :envvar:`SEED` is defined,
     #: but empty, then no seed is used and a protocol cannot be
     #: reproduced exactly.
     rand = random.Random(_seed)
@@ -61,21 +61,19 @@
     """Decorator used for wrapper functions.
 
     It is important to use this decorator on any wrapper functions in
-    order to ensure that they end up with correct C{__name__} and
-    C{__doc__} attributes.
+    order to ensure that they end up with correct :attr:`__name__` and
+    :attr:`__doc__` attributes.
 
-    In addition, if the environment variable C{EPYDOC} is defined,
-    then the wrapper functions will be turned into functions that I{do
-    not} wrap -- instead they let their argument function through
-    unchanged. This is done so that epydoc can see the true function
-    arguments when generating documentation. Just remember that your
-    code will break if C{EPYDOC} is set, so it should only be used
-    when epydoc is being run.
-
-    @param func: the function that will be wrapped.
-    @type func: callable
+    In addition, if the environment variable :envvar:`VIFF_NO_WRAP` is
+    defined, then the wrapper functions will be turned into functions
+    that *do not* wrap -- instead they let their argument function
+    through unchanged. This is done so that epydoc and Sphinx can see
+    the true function arguments when generating documentation. Just
+    remember that your code will break if :envvar:`VIFF_NO_WRAP` is
+    set, so it should only be used when documentation is being
+    generated.
     """
-    if os.environ.get('EPYDOC'):
+    if os.environ.get('VIFF_NO_WRAP'):
         # Return a decorator which ignores the functions it is asked
         # to decorate and instead returns func:
         return lambda _: func
@@ -168,10 +166,11 @@
     """Clone a Deferred.
 
     The returned clone will fire with the same result as the original
-    Deferred, but will otherwise be independent.
+    :class:`Deferred`, but will otherwise be independent.
 
-    It is an error to call callback on the clone as it will result in
-    an AlreadyCalledError when the original Deferred is triggered.
+    It is an error to call :meth:`callback` on the clone as it will
+    result in an :exc:`AlreadyCalledError` when the original
+    :class:`Deferred` is triggered.
 
     >>> x = Deferred()
     >>> x.addCallback(lambda result: result * 10) # doctest: +ELLIPSIS