changeset 0:a0207c736c67

Imported VIFF homepage. The homepage has been converted to reStructureText format. To build the page simply run update_news.py followed by buildhtml.py. The latter is taken from the Docutils project (public domain code).
author Martin Geisler <mg@daimi.au.dk>
date Wed, 13 Feb 2008 22:14:04 +0100
parents
children b1238323e4bc
files buildhtml.py docutils.conf images/viff-dog.png index.txt news.xml update_news.py viff.css
diffstat 7 files changed, 699 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildhtml.py	Wed Feb 13 22:14:04 2008 +0100
@@ -0,0 +1,239 @@
+#!/usr/bin/env python
+
+# $Id: buildhtml.py 5019 2007-03-12 21:48:30Z wiemann $
+# Author: David Goodger <goodger@python.org>
+# Copyright: This module has been placed in the public domain.
+
+"""
+Generates .html from all the .txt files in a directory.
+
+Ordinary .txt files are understood to be standalone reStructuredText.
+Files named ``pep-*.txt`` are interpreted as reStructuredText PEPs.
+"""
+# Once PySource is here, build .html from .py as well.
+
+__docformat__ = 'reStructuredText'
+
+
+try:
+    import locale
+    locale.setlocale(locale.LC_ALL, '')
+except:
+    pass
+
+import sys
+import os
+import os.path
+import copy
+from fnmatch import fnmatch
+import docutils
+from docutils import ApplicationError
+from docutils import core, frontend, utils
+from docutils.parsers import rst
+from docutils.readers import standalone, pep
+from docutils.writers import html4css1, pep_html
+
+
+usage = '%prog [options] [<directory> ...]'
+description = ('Generates .html from all the reStructuredText .txt files '
+               '(including PEPs) in each <directory> '
+               '(default is the current directory).')
+
+
+class SettingsSpec(docutils.SettingsSpec):
+
+    """
+    Runtime settings & command-line options for the front end.
+    """
+
+    # Can't be included in OptionParser below because we don't want to
+    # override the base class.
+    settings_spec = (
+        'Build-HTML Options',
+        None,
+        (('Recursively scan subdirectories for files to process.  This is '
+          'the default.',
+          ['--recurse'],
+          {'action': 'store_true', 'default': 1,
+           'validator': frontend.validate_boolean}),
+         ('Do not scan subdirectories for files to process.',
+          ['--local'], {'dest': 'recurse', 'action': 'store_false'}),
+         ('Do not process files in <directory>.  This option may be used '
+          'more than once to specify multiple directories.',
+          ['--prune'],
+          {'metavar': '<directory>', 'action': 'append',
+           'validator': frontend.validate_colon_separated_string_list}),
+         ('Recursively ignore files or directories matching any of the given '
+          'wildcard (shell globbing) patterns (separated by colons).  '
+          'Default: ".svn:CVS"',
+          ['--ignore'],
+          {'metavar': '<patterns>', 'action': 'append',
+           'default': ['.svn', 'CVS'],
+           'validator': frontend.validate_colon_separated_string_list}),
+         ('Work silently (no progress messages).  Independent of "--quiet".',
+          ['--silent'],
+          {'action': 'store_true', 'validator': frontend.validate_boolean}),))
+
+    relative_path_settings = ('prune',)
+    config_section = 'buildhtml application'
+    config_section_dependencies = ('applications',)
+
+
+class OptionParser(frontend.OptionParser):
+
+    """
+    Command-line option processing for the ``buildhtml.py`` front end.
+    """
+
+    def check_values(self, values, args):
+        frontend.OptionParser.check_values(self, values, args)
+        values._source = None
+        return values
+
+    def check_args(self, args):
+        source = destination = None
+        if args:
+            self.values._directories = args
+        else:
+            self.values._directories = [os.getcwd()]
+        return source, destination
+
+
+class Struct:
+
+    """Stores data attributes for dotted-attribute access."""
+
+    def __init__(self, **keywordargs):
+        self.__dict__.update(keywordargs)
+
+
+class Builder:
+
+    def __init__(self):
+        self.publishers = {
+            '': Struct(components=(pep.Reader, rst.Parser, pep_html.Writer,
+                                   SettingsSpec)),
+            '.txt': Struct(components=(rst.Parser, standalone.Reader,
+                                       html4css1.Writer, SettingsSpec),
+                           reader_name='standalone',
+                           writer_name='html'),
+            'PEPs': Struct(components=(rst.Parser, pep.Reader,
+                                       pep_html.Writer, SettingsSpec),
+                           reader_name='pep',
+                           writer_name='pep_html')}
+        """Publisher-specific settings.  Key '' is for the front-end script
+        itself.  ``self.publishers[''].components`` must contain a superset of
+        all components used by individual publishers."""
+
+        self.setup_publishers()
+
+    def setup_publishers(self):
+        """
+        Manage configurations for individual publishers.
+
+        Each publisher (combination of parser, reader, and writer) may have
+        its own configuration defaults, which must be kept separate from those
+        of the other publishers.  Setting defaults are combined with the
+        config file settings and command-line options by
+        `self.get_settings()`.
+        """
+        for name, publisher in self.publishers.items():
+            option_parser = OptionParser(
+                components=publisher.components, read_config_files=1,
+                usage=usage, description=description)
+            publisher.option_parser = option_parser
+            publisher.setting_defaults = option_parser.get_default_values()
+            frontend.make_paths_absolute(publisher.setting_defaults.__dict__,
+                                         option_parser.relative_path_settings)
+            publisher.config_settings = (
+                option_parser.get_standard_config_settings())
+        self.settings_spec = self.publishers[''].option_parser.parse_args(
+            values=frontend.Values())   # no defaults; just the cmdline opts
+        self.initial_settings = self.get_settings('')
+
+    def get_settings(self, publisher_name, directory=None):
+        """
+        Return a settings object, from multiple sources.
+
+        Copy the setting defaults, overlay the startup config file settings,
+        then the local config file settings, then the command-line options.
+        Assumes the current directory has been set.
+        """
+        publisher = self.publishers[publisher_name]
+        settings = frontend.Values(publisher.setting_defaults.__dict__)
+        settings.update(publisher.config_settings, publisher.option_parser)
+        if directory:
+            local_config = publisher.option_parser.get_config_file_settings(
+                os.path.join(directory, 'docutils.conf'))
+            frontend.make_paths_absolute(
+                local_config, publisher.option_parser.relative_path_settings,
+                directory)
+            settings.update(local_config, publisher.option_parser)
+        settings.update(self.settings_spec.__dict__, publisher.option_parser)
+        return settings
+
+    def run(self, directory=None, recurse=1):
+        recurse = recurse and self.initial_settings.recurse
+        if directory:
+            self.directories = [directory]
+        elif self.settings_spec._directories:
+            self.directories = self.settings_spec._directories
+        else:
+            self.directories = [os.getcwd()]
+        for directory in self.directories:
+            os.path.walk(directory, self.visit, recurse)
+
+    def visit(self, recurse, directory, names):
+        settings = self.get_settings('', directory)
+        if settings.prune and (os.path.abspath(directory) in settings.prune):
+            print >>sys.stderr, '/// ...Skipping directory (pruned):', directory
+            sys.stderr.flush()
+            names[:] = []
+            return
+        if not self.initial_settings.silent:
+            print >>sys.stderr, '/// Processing directory:', directory
+            sys.stderr.flush()
+        # settings.ignore grows many duplicate entries as we recurse
+        # if we add patterns in config files or on the command line.
+        for pattern in utils.uniq(settings.ignore):
+            for i in range(len(names) - 1, -1, -1):
+                if fnmatch(names[i], pattern):
+                    # Modify in place!
+                    del names[i]
+        prune = 0
+        for name in names:
+            if name.endswith('.txt'):
+                prune = self.process_txt(directory, name)
+                if prune:
+                    break
+        if not recurse:
+            del names[:]
+
+    def process_txt(self, directory, name):
+        if name.startswith('pep-'):
+            publisher = 'PEPs'
+        else:
+            publisher = '.txt'
+        settings = self.get_settings(publisher, directory)
+        pub_struct = self.publishers[publisher]
+        if settings.prune and (directory in settings.prune):
+            return 1
+        settings._source = os.path.normpath(os.path.join(directory, name))
+        settings._destination = settings._source[:-4]+'.html'
+        if not self.initial_settings.silent:
+            print >>sys.stderr, '    ::: Processing:', name
+            sys.stderr.flush()
+        try:
+            core.publish_file(source_path=settings._source,
+                              destination_path=settings._destination,
+                              reader_name=pub_struct.reader_name,
+                              parser_name='restructuredtext',
+                              writer_name=pub_struct.writer_name,
+                              settings=settings)
+        except ApplicationError, error:
+            print >>sys.stderr, ('        Error (%s): %s'
+                                 % (error.__class__.__name__, error))
+
+
+if __name__ == "__main__":
+    Builder().run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docutils.conf	Wed Feb 13 22:14:04 2008 +0100
@@ -0,0 +1,12 @@
+
+[general]
+source-link: yes
+ignore: .hg:images:.feed-cache
+
+
+[html4css1 writer]
+stylesheet-path: viff.css
+embed-stylesheet: no
+initial-header-level: 2
+datestamp: %Y-%m-%d %H:%M UTC
+halt_level: 1
Binary file images/viff-dog.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/index.txt	Wed Feb 13 22:14:04 2008 +0100
@@ -0,0 +1,182 @@
+.. -*- coding: utf-8 -*-
+
+
+=============================================================
+ Welcome to VIFF, the Virtual Ideal Functionality Framework!
+=============================================================
+
+.. raw:: html
+
+  <div id="links">
+    <a class="green" href="#releases">Download VIFF 0.3</a>
+    <a class="blue"
+        href="http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk">Join
+    the mailing list</a>
+    <a class="red" href="/api/">API docs</a>
+  </div>
+
+.. raw:: html
+   :file: news.html
+
+.. image:: images/viff-dog.png
+   :align: right
+   :alt: The VIFF dog
+
+.. |Zp| replace:: **Z**\ *p*
+.. |GF256| replace:: **GF**\ (2\ :sup:`8`)
+
+VIFF is a framework which allows you to specify secure multi-party
+computations in a clean and easy way. Current features include:
+
+* arithmetic with shares from |Zp| or |GF256|.
+
+* secret sharing based on Shamir and pseudo-random secret sharing
+  (PRSS).
+
+* addition, multiplication, exclusive-or of shares.
+
+* comparison of secret shared |Zp| inputs, with secret |Zp| or |GF256|
+  output.
+
+* automatic parallel (asynchronous) execution.
+
+* secure communication using TLS (the successor to SSL).
+
+* cute mascot :-)
+
+VIFF is implemented in Python_ using Twisted_ and should run on any
+platform where Python runs (succesfully tested on Linux and Windows).
+Please see the INSTALL_ file for details on the requirements.
+
+VIFF is Free Software, licensed under the `GNU GPL`_. This means that
+you can download and use it for free and modify it to suit your needs.
+You are free to redistribute your modifications as long as you do it
+together with the modified source.
+
+.. _Python: http://python.org/
+.. _Twisted: http://twistedmatrix.com/
+.. _INSTALL: http://hg.viff.dk/viff/raw-file/tip/INSTALL
+.. _GNU GPL: http://hg.viff.dk/viff/raw-file/tip/COPYING
+
+Use Cases
+~~~~~~~~~
+
+VIFF allows you to do secure multi-party computations, in which a
+number of parties (three or more at the moment) execute a
+cryptographic protocol to do some joint computation. The computation
+could be anything, but elections and auctions are good examples of
+what you would want to do with secure multi-party computations (SMPC
+or simply MPC if it is implied that the protocol is secure).
+
+Using VIFF your protocol is run without the players revealing anything
+about their inputs. So three millionaires can determine among
+themselves who has, say, the most money *without revealing how much
+they are worth* to one another. So they all learn who is richest, but
+nothing else.
+
+The techniques for doing this involves computations on secret shared
+values, but the programmer can mostly ignore this when using VIFF.
+Please see the example programs included in the distribution below.
+
+Releases
+~~~~~~~~
+
+The latest version VIFF source code can be obtained using Mercurial_ by
+the command::
+
+  hg clone http://hg.viff.dk/viff/
+
+or by `browsing the repository online`__. There you can also subscribe to
+a RSS_ or Atom_ feed with updates.
+
+.. __: http://hg.viff.dk/viff/
+.. _Mercurial: http://www.selenic.com/mercurial/
+.. _RSS: http://hg.viff.dk/viff/rss-log
+.. _Atom: http://hg.viff.dk/viff/atom-log
+
+The repository should be mostly stable and a snapshot can be
+downloaded here:
+
+* **viff-tip**: tar.bz2__, tar.gz__, zip__.
+
+.. __: http://hg.viff.dk/viff/archive/tip.tar.bz2
+.. __: http://hg.viff.dk/viff/archive/tip.tar.gz
+.. __: http://hg.viff.dk/viff/archive/tip.zip
+
+You can also download a release below:
+
+* **viff-0.3**: tar.bz2__, tar.gz__, zip__, released on December 27th 2007.
+
+  .. __: http://viff.dk/release/viff-0.3.tar.bz2
+  .. __: http://viff.dk/release/viff-0.3.tar.gz
+  .. __: http://viff.dk/release/viff-0.3.zip
+
+  Changes since 0.2: Secure communication between the players were
+  implemented using TLS_ (the successor to SSL). An included Makefile
+  can generate the needed certificates. The network layer was
+  completely reimplemented, this breaks compatibility with programs
+  written for VIFF version 0.2 or earlier.
+
+  .. _TLS: http://en.wikipedia.org/wiki/Transport_Layer_Security
+
+* **viff-0.2**: tar.bz2__, tar.gz__, zip__, released on November 14th 2007.
+
+  .. __: http://viff.dk/release/viff-0.2.tar.bz2
+  .. __: http://viff.dk/release/viff-0.2.tar.gz
+  .. __: http://viff.dk/release/viff-0.2.zip
+
+  Changes since 0.1.1: Implemented overloaded arithmetic operators, so
+  ``w = x + y * z`` now adds and multiplies the three shares as expected.
+  Updated API documentation. Released using a Distutils setup.py
+  script.
+
+* **viff-0.1.1**: tar.bz2__, tar.gz__, zip__, released on October 23rd 2007.
+
+  .. __: http://viff.dk/release/viff-0.1.1.tar.bz2
+  .. __: http://viff.dk/release/viff-0.1.1.tar.gz
+  .. __: http://viff.dk/release/viff-0.1.1.zip
+
+  Changes since 0.1: Added API documentation and updated the
+  installation instructions.
+
+* **viff-0.1**: tar.bz2__, tar.gz__, zip__, released on October 16th 2007.
+
+  .. __: http://viff.dk/release/viff-0.1.tar.bz2
+  .. __: http://viff.dk/release/viff-0.1.tar.gz
+  .. __: http://viff.dk/release/viff-0.1.zip
+
+  First public release. Implements basic functionality including
+  addition, multiplication, exclusive-or, and comparison of shares.
+  Shares can be made using Shamir sharing or PRSS. Includes a suite of
+  unit tests and example programs.
+
+Please see the `VIFF API documentation`__ in addition to the documentation
+included in the files above.
+
+.. __: http://viff.dk/api/
+
+Contact
+~~~~~~~
+
+Please post your questions and comments on VIFF to the `VIFF-devel
+mailing list`_. Any question can be sent there — VIFF is still a
+little rough around the edges, so please ask for help if you cannot
+get VIFF working! The list is archived locally_, at Gmane_ (where you
+can read/post over `NNTP using a newsreader`__) and at `The Mail
+Archive`__.
+
+VIFF is developed by `Martin Geisler`_, `Mikkel Krøigård`_, and `Tomas
+Toft`_. Other contributors are very welcome! Please come to the
+`mailing list`_ and talk to us if you want to help in any way.
+
+
+.. _mailing list:
+.. _VIFF-devel mailing list: http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
+.. _locally: http://lists.viff.dk/pipermail/viff-devel-viff.dk/
+.. _Gmane: http://dir.gmane.org/gmane.comp.cryptography.viff.devel
+.. __: nntp://news.gmane.org/gmane.comp.cryptography.viff.devel
+.. __: http://www.mail-archive.com/viff-devel@viff.dk/
+
+.. _Martin Geisler: http://www.daimi.au.dk/~mg/
+.. _Mikkel Krøigård: http://www.daimi.au.dk/~mk/
+.. _Tomas Toft: http://dinapigen.dk/TOMAS/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/news.xml	Wed Feb 13 22:14:04 2008 +0100
@@ -0,0 +1,24 @@
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:py="http://genshi.edgewall.org/" class="news">
+  <div class="left">
+    <p><b>News from the <a href="http://hg.viff.dk/viff/log/">changelog</a>:</b></p>
+    <ul>
+      <li py:for="entry in repository">
+        <a href="${entry.link}">${entry.title}</a>
+        <em>${entry.age} ago by
+        ${entry.author_detail['name']}</em>
+      </li>
+    </ul>
+  </div>
+
+  <div class="right">
+    <p><b>News from the <a
+    href="http://news.gmane.org/gmane.comp.cryptography.viff.devel">mailing list</a>:</b></p>
+    <ul>
+      <li py:for="entry in viff_devel">
+        <a href="${entry.link}">${entry.title}</a>
+        <em>${entry.age} ago by ${entry.author}</em>
+      </li>
+    </ul>
+  </div>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/update_news.py	Wed Feb 13 22:14:04 2008 +0100
@@ -0,0 +1,123 @@
+#!/usr/bin/python2.4
+
+import os.path
+import re, logging
+from time import time, gmtime, asctime, strftime
+from calendar import timegm
+from cPickle import dump, load
+from optparse import OptionParser
+
+import feedparser
+feedparser.USER_AGENT = "VIFF Homepage Generator +http://viff.dk/"
+
+from genshi.template import TemplateLoader
+
+
+def fetch_and_cache(url, directory=None, file=None):
+    if directory is None:
+        directory = ".feed-cache"
+
+    if not os.path.isdir(directory):
+        logging.info("Creating directory %s" % directory)
+        os.mkdir(directory)
+
+    if file is None:
+        parts = re.split('[^a-z0-9.]+', url)
+        file = "-".join(parts)
+        logging.debug("Cache built from URL: '%s'" % file)
+
+    file = os.path.join(directory, file)
+
+    try:
+        mtime = gmtime(os.path.getmtime(file))
+    except OSError:
+        mtime = gmtime(0)
+    logging.debug("Last modification time: %s" % asctime(mtime))
+
+    data = feedparser.parse(url, modified=mtime)
+    logging.debug("Feed status: %d" % data.status)
+
+    if data.status == 304:
+        fp = None
+        try:
+            fp = open(file, 'r')
+            data = load(fp)
+        finally:
+            if fp is not None:
+                fp.close()
+    else:
+        fp = None
+        try:
+            fp = open(file, 'w')
+            dump(data, fp)
+        finally:
+            if fp is not None:
+                fp.close()
+
+    logging.debug("Returning feed with %d entries" % len(data.entries))
+    return data
+
+def age(time_tuple):
+    deltas = [(60*60*24*7*365, 'years'),
+              (60*60*24*7*30, 'months'),
+              (60*60*24*7, 'weeks'),
+              (60*60*24, 'days'),
+              (60*60, 'hours'),
+              (60, 'minutes'),
+              (1, 'seconds')]
+
+    difference = time() - timegm(time_tuple)
+    for delta, text in deltas:
+        if difference > 2*delta:
+            break
+
+    return "%d %s" % (round(difference / delta), text)
+
+if __name__ == "__main__":
+    parser = OptionParser()
+    parser.add_option("-v", "--verbose",
+                      help="verbose output.",
+                      action="store_true",
+                      dest="verbose")
+    parser.add_option("-q", "--quiet",
+                      help="quiet output.",
+                      action="store_false",
+                      dest="verbose")
+
+    parser.set_defaults(verbose=False)
+
+    (options, args) = parser.parse_args()
+
+    if options.verbose:
+        level = logging.DEBUG
+    else:
+        level = logging.WARN
+
+    logging.getLogger().setLevel(level)
+
+    logging.info("Fetching data")
+    repository_data = fetch_and_cache("http://hg.viff.dk/viff/atom-log")
+    viff_devel_data = fetch_and_cache("http://rss.gmane.org/messages/excerpts/"
+                                      "gmane.comp.cryptography.viff.devel")
+
+    logging.info("Calculating ages")
+    for entry in repository_data.entries:
+        entry.age = age(entry.updated_parsed)
+    for entry in viff_devel_data.entries:
+        entry.age = age(entry.updated_parsed)
+
+    #tip_age = age(repository_data.entries[0].updated_parsed)
+    #now = strftime("%Y-%m-%d %H:%M UTC", gmtime())
+
+    logging.info("Rendering news.html")
+    loader = TemplateLoader(['.'])
+    tmpl = loader.load('news.xml')
+    stream = tmpl.generate(repository=repository_data.entries[:4],
+                           viff_devel=viff_devel_data.entries[:4])
+
+    out = open('_news.html', 'w')
+    out.write(stream.render('html'))
+    out.close()
+    os.rename('_news.html', 'news.html')
+
+    logging.info("Finished")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/viff.css	Wed Feb 13 22:14:04 2008 +0100
@@ -0,0 +1,119 @@
+
+html {
+  font-family: sans-serif;
+  margin: 1em 2em;
+}
+
+p {
+  margin-top: 0.25em;
+  margin-bottom: 0.25em;
+}
+
+li {
+  text-align: left;
+  margin-bottom: 0.5em;
+}
+
+img {
+  border: 0px;
+}
+
+h1 {
+  text-align: center;
+  color: #A00;
+}
+
+h2 {
+  color: #0A0;
+  border-bottom: medium solid #0A0;
+}
+
+div.news {
+  font-size: 85%;
+  background-color: #EEE;
+  border: medium solid #DDD;
+  overflow: auto;
+  margin: 1em 0em;
+  padding: 0.5em;
+}
+
+div.left {
+  float: left;
+  width: 50%;
+}
+
+div.right {
+  float: left;
+  width: 49%;
+}
+
+
+div.news ul {
+  padding: 0px;
+  margin: 0em 2em;
+}
+
+div.news ul em {
+  font-size: 85%;
+  white-space: nowrap;
+}
+
+div.news ul a {
+  margin-right: 0.5em;
+}
+
+div.news li {
+  padding: 0px;
+  margin: 0.5em 0em;
+}
+
+#links {
+  text-align: center;
+  font-size: 115%;
+  font-weight: bold;
+  line-height: 3em;
+}
+
+#links a {
+  white-space: nowrap;
+  border-width: medium;
+  border-style: solid;
+  padding: 0.5em 1em;
+  text-decoration: none;
+  color: inherit;
+  margin: 0em 0.5em;
+}
+
+#links a:hover {
+  text-decoration: underline;
+}
+
+.green {
+  border-color: #6F6;
+  background-color: #AFA;
+}
+
+.green:hover {
+  border-color: #8F8;
+  background-color: #CFC;
+}
+
+.blue {
+  border-color: #66F;
+  background-color: #AAF;
+}
+
+.blue:hover {
+  border-color: #88F;
+  background-color: #CCF;
+}
+
+.red {
+  border-color: #F66;
+  background-color: #FAA;
+}
+
+.red:hover {
+  border-color: #F88;
+  background-color: #FCC;
+}