More code!
authorfluffymormegil <mpread@chiark.greenend.org.uk>
Sat, 9 Oct 2010 12:50:46 +0000 (13:50 +0100)
committerfluffymormegil <mpread@chiark.greenend.org.uk>
Sat, 9 Oct 2010 12:50:46 +0000 (13:50 +0100)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
README
include/libmormegil/Coord.hh
include/libmormegil/S20prng.hh [new file with mode: 0644]
include/libmormegil/abs.hh
include/libmormegil/dice.h [new file with mode: 0644]
lib/placeholder.txt [new file with mode: 0644]
obj/placeholder.txt [new file with mode: 0644]
src/dice.cc [new file with mode: 0644]
version.mk [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..23d8c8e
--- /dev/null
@@ -0,0 +1,5 @@
+*.o
+*.so
+*.tar
+*.gz
+*.tgz
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..31d00a4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,28 @@
+#! /usr/bin/make -f
+# Makefile - makefile for building libmormegil.so
+
+include version.mk
+LIBDIR=$(DESTDIR)lib
+OBJDIR=$(DESTDIR)obj
+
+LIBTARGET=$(LIBDIR)/libmormegil-$(MAJOR_VER).$(MINOR_VER).$(COMPAT_DEPTH).so
+LIBOBJS=$(OBJDIR)/dice.o
+
+# GCC flags
+COMMON_FLAGS=-fPIC -I./include
+CXXFLAGS=$(COMMON_FLAGS)
+LINKSTEP_FLAGS=-shared -fPIC
+
+$(OBJDIR)/%.o: src/%.c
+       $(CC) $(CFLAGS) -c $< -o $@
+
+$(OBJDIR)/%.o: src/%.cc
+       $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
+
+$(LIBTARGET): $(LIBOBJS)
+       gcc $(LINKSTEP_FLAGS) $< -o $@
+
+clean:
+       -rm -f $(LIBTARGET) $(OBJDIR)/*.o
+
+# vim:noexpandtab:format=cq
diff --git a/README b/README
index e69de29..34c0b23 100644 (file)
--- a/README
+++ b/README
@@ -0,0 +1,15 @@
+libmormegil is a collection of library functions and C++ classes intended for
+use in various projects that I host on github under the name fluffymormegil.
+
+INSTALLATION
+============
+Some elements of libmormegil are self-contained single-header C++ classes
+which you can safely copy directly into your own projects if you want. Others
+are intended to be installed as system-wide shared libraries.
+
+ACKNOWLEDGEMENTS
+================
+The Salsa20 stream cipher was invented by Daniel J. Bernstein; the
+implementation used in the libmormegil::S20prng C++ class is based on DJB's
+public domain reference implementation.
+
index d5b72d5..f0c66f9 100644 (file)
@@ -92,4 +92,4 @@ namespace libmormegil
 }
 #endif // libmormegil_Coord_hh
 
-// vim:ts=8:sw=4:expandtab
+// vim:ts=8:sw=4:expandtab:fo=c
diff --git a/include/libmormegil/S20prng.hh b/include/libmormegil/S20prng.hh
new file mode 100644 (file)
index 0000000..de5a64b
--- /dev/null
@@ -0,0 +1,127 @@
+// libmormegil/s20prng.cc - PRNG using Salsa20 stream cipher
+// 
+// Copyright 2010 Martin Read. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the author nor the names of any other contributors
+//    may be used to endorse or promote products derived from this software
+//    without their specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#ifndef libmormegil_S20prng_hh
+#define libmormegil_S20prng_hh
+
+#include <stdint.h>
+
+namespace libmormegil
+{
+    /* An S20prng object holds the state of a Salsa20 stream cipher
+     * implementation. */
+#define rotl(x, dist) (((x) << (dist)) | ((x) >> (32 - (dist))))
+    struct S20prng
+    {
+        enum {
+            Fixed1 = 0x4a409382,
+            Fixed2 = 0x2299f31d,
+            Fixed3 = 0x0082efa9,
+            Fixed4 = 0x8ec4e6c8
+        };
+        uint32_t state[16];
+        uint64_t counter;
+        uint32_t key[8];
+        uint32_t nonce[2];
+        int subcounter;
+        void doubleround()
+        {
+            state[ 4] ^= rotl(state[ 0]+state[12], 7);
+            state[ 8] ^= rotl(state[ 4]+state[ 0], 9);
+            state[12] ^= rotl(state[ 8]+state[ 4], 13);
+            state[ 0] ^= rotl(state[12]+state[ 8], 18);
+            state[ 9] ^= rotl(state[ 5]+state[ 1], 7);
+            state[13] ^= rotl(state[ 9]+state[ 5], 9);
+            state[ 1] ^= rotl(state[13]+state[ 9], 13);
+            state[ 5] ^= rotl(state[ 1]+state[13], 18);
+            state[14] ^= rotl(state[10]+state[ 6], 7);
+            state[ 2] ^= rotl(state[14]+state[10], 9);
+            state[ 6] ^= rotl(state[ 2]+state[14], 13);
+            state[10] ^= rotl(state[ 6]+state[ 2], 18);
+            state[ 3] ^= rotl(state[15]+state[11], 7);
+            state[ 7] ^= rotl(state[ 3]+state[15], 9);
+            state[11] ^= rotl(state[ 7]+state[ 3], 13);
+            state[15] ^= rotl(state[11]+state[ 7], 18);
+
+            state[ 1] ^= rotl(state[ 0]+state[ 3], 7);
+            state[ 2] ^= rotl(state[ 1]+state[ 0], 9);
+            state[ 3] ^= rotl(state[ 2]+state[ 1], 13);
+            state[ 0] ^= rotl(state[ 3]+state[ 2], 18);
+            state[ 6] ^= rotl(state[ 5]+state[ 3], 7);
+            state[ 7] ^= rotl(state[ 6]+state[ 5], 9);
+            state[ 4] ^= rotl(state[ 7]+state[ 6], 13);
+            state[ 5] ^= rotl(state[ 4]+state[ 7], 18);
+            state[11] ^= rotl(state[10]+state[ 9], 7);
+            state[ 8] ^= rotl(state[11]+state[10], 9);
+            state[ 9] ^= rotl(state[ 8]+state[11], 13);
+            state[10] ^= rotl(state[ 9]+state[ 8], 18);
+            state[12] ^= rotl(state[15]+state[14], 7);
+            state[13] ^= rotl(state[12]+state[15], 9);
+            state[14] ^= rotl(state[13]+state[12], 13);
+            state[15] ^= rotl(state[14]+state[13], 18);
+        }
+        void slash(int n)
+        {
+            for (int i = 0; i < (n >> 1); ++i)
+            {
+                doubleround();
+            }
+        }
+        uint32_t generate()
+        {
+            if (!subcounter)
+            {
+                state[0] = Fixed1;
+                state[1] = key[0];
+                state[2] = key[1];
+                state[3] = key[2];
+                state[4] = key[3];
+                state[5] = Fixed2;
+                state[6] = nonce[0];
+                state[7] = nonce[1];
+                state[8] = counter;
+                state[9] = counter >> 32;
+                state[10] = Fixed3;
+                state[11] = key[4];
+                state[12] = key[5];
+                state[13] = key[6];
+                state[14] = key[7];
+                state[15] = Fixed4;
+                ++counter;
+                slash(12);
+            }
+            ++subcounter;
+            subcounter &= 15;
+        }
+    };
+}
+#endif
+
+// vim:ts=8:sw=4:expandtab:fo=c
+// libmormegil/S20prng.hh
index 9200e55..0875769 100644 (file)
@@ -37,5 +37,4 @@ namespace libmormegil
 }
 #endif // libmormegil_abs_hh
 
-// vim:ts=8:sw=4:expandtab
-
+// vim:ts=8:sw=4:expandtab:fo=c
diff --git a/include/libmormegil/dice.h b/include/libmormegil/dice.h
new file mode 100644 (file)
index 0000000..2c77528
--- /dev/null
@@ -0,0 +1,46 @@
+// libmormegil/dice.h
+//
+// Copyright 2010 Martin Read. All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the author nor the names of any other contributors
+//    may be used to endorse or promote products derived from this software
+//    without their specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#ifndef libmormegil_dice_h
+#define libmormegil_dice_h
+
+#include <stdint.h>
+// this function is pitched at C99 users.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int dice(int count, int sides);
+extern void dice_setstate(const uint32_t *key, const uint32_t *nonce, const uint64_t *counter, const int *subcounter);
+extern void dice_getstate(uint32_t *key, uint32_t *nonce, uint64_t *counter, int *subcounter);
+#ifdef __cplusplus
+};
+#endif
+#endif // libmormegil_dice_h
+
+// vim:ts=8:sw=4:expandtab:fo=c
diff --git a/lib/placeholder.txt b/lib/placeholder.txt
new file mode 100644 (file)
index 0000000..773a8f9
--- /dev/null
@@ -0,0 +1 @@
+This is a placeholder
diff --git a/obj/placeholder.txt b/obj/placeholder.txt
new file mode 100644 (file)
index 0000000..773a8f9
--- /dev/null
@@ -0,0 +1 @@
+This is a placeholder
diff --git a/src/dice.cc b/src/dice.cc
new file mode 100644 (file)
index 0000000..b4b6c31
--- /dev/null
@@ -0,0 +1,73 @@
+// dice.cc
+//
+// Copyright 2010 Martin Read. All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the author nor the names of any other contributors
+//    may be used to endorse or promote products derived from this software
+//    without their specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#include <stdint.h>
+#include <string.h>
+#include <libmormegil/dice.h>
+#include <libmormegil/S20prng.hh>
+
+libmormegil::S20prng dice_generator;
+
+extern "C" int dice(int count, int sides)
+{
+    int value = 0;
+    unsigned divisor;
+    unsigned limit;
+    uint32_t genned;
+    value = count;
+    divisor = 0xffffffffu / unsigned(sides);
+    limit = divisor * sides;
+    for ( ; count; --count)
+    {
+        do
+        {
+            genned = dice_generator.generate();
+        } while (genned >= limit);
+        value += genned / divisor;
+    }
+    return value;
+}
+
+extern "C" void dice_setstate(const uint32_t *key, const uint32_t *nonce, const uint64_t *counter, const int *subcounter)
+{
+    dice_generator.counter = *counter;
+    memcpy(dice_generator.key, key, 8 * sizeof(uint32_t));
+    memcpy(dice_generator.nonce, nonce, 2 * sizeof(uint32_t));
+    dice_generator.subcounter = *subcounter;
+}
+
+extern "C" void dice_getstate(uint32_t *key, uint32_t *nonce, uint64_t *counter, int *subcounter)
+{
+    memcpy(key, dice_generator.key, 8 * sizeof(uint32_t));
+    memcpy(dice_generator.nonce, nonce, 2 * sizeof(uint32_t));
+    *subcounter = dice_generator.subcounter;
+    *counter = dice_generator.counter;
+}
+
+// vim:ts=8:sw=4:expandtab:fo=cq
+
diff --git a/version.mk b/version.mk
new file mode 100644 (file)
index 0000000..910efd0
--- /dev/null
@@ -0,0 +1,3 @@
+MAJOR_VER=1
+MINOR_VER=0
+COMPAT_DEPTH=0