### The main library.
lib_LTLIBRARIES = libcatacomb.la
-libcatacomb_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO)
+libcatacomb_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO) \
+ -no-undefined
libcatacomb_la_LIBADD = $(MATHLIBS) $(mLib_LIBS)
libcatacomb_la_SOURCES =
EXTRA_DIST += debian/changelog
EXTRA_DIST += debian/copyright
EXTRA_DIST += debian/compat
+EXTRA_DIST += debian/source/format
## catacomb2
EXTRA_DIST += debian/catacomb2.install
#! /bin/sh -ex
for gen in symm/modes.am symm/stubs.am; do
- if [ ! -r $gen ]; then touch -t197001010000.00 $gen; fi
+ if [ ! -r $gen ]; then touch -t197101010000.00 $gen; fi
done
AC_INIT([catacomb], AUTO_VERSION, [mdw@distorted.org.uk])
AC_CONFIG_SRCDIR([catacomb.pc.in])
AC_CONFIG_AUX_DIR([config])
-AM_INIT_AUTOMAKE([foreign parallel-tests])
+AM_INIT_AUTOMAKE([foreign parallel-tests color-tests subdir-objects])
AC_CANONICAL_HOST
mdw_SILENT_RULES
AC_CHECK_FUNCS([mlock])
dnl Necessary support libraries.
-PKG_CHECK_MODULES([mLib], [mLib >= 2.2.1])
+PKG_CHECK_MODULES([mLib], [mLib >= 2.2.2.1])
AM_CFLAGS="$AM_CFLAGS $mLib_CFLAGS"
dnl--------------------------------------------------------------------------
+catacomb (2.2.1) experimental; urgency=low
+
+ * Some internal improvements.
+ * Debian packaging cleanups (fix build-depends, update mLib dependency).
+
+ -- Mark Wooding <mdw@distorted.org.uk> Thu, 18 Feb 2016 16:43:09 +0000
+
+catacomb (2.2.0) experimental; urgency=low
+
+ * catacomb2: Fix rsa_recover crash on even modulus.
+ * catacomb-bin: Report error taking factorial of negative input.
+ * catacomb2: Fix EC_FIND and EC_NEG on 2-torsion points of prime curves.
+ * catacomb-dev: Support multiple flavours of EC point compression.
+ * catacomb2: Fix theoretical rsa_recover crash if factoring loop runs
+ out of prime numbers.
+ * catacomb2: Overhaul crypto primitives used in true-random generator.
+ * catacomb-bin: Improve rspit: high-resolution timing, and 64-bit size
+ support.
+ * catacomb-dev: New conversions between MP integers and C integer types.
+ * catacomb2: Change gcipher for Seal incompatibly. The IV is now
+ big-endian bytes (rather than `uint32'), and the `block size' is 4.
+ * catacomb2: Mix a constant string into DSA nonce generation to improve
+ resistance to protocol interference.
+ * catacomb2: Fix the freewheel random source, which hasn't been enabled
+ for ages due to a configure-script bug.
+ * catacomb-bin: The key tool can now read and write multiple
+ presentations for key fingerprints.
+ * catacomb2, catacomb-dev: Support Daniel Bernstein's Salsa20 and ChaCha
+ stream ciphers.
+
+ -- Mark Wooding <mdw@distorted.org.uk> Mon, 20 Jul 2015 14:15:31 +0100
+
catacomb (2.1.7) experimental; urgency=low
* A number of entropy-source fixes.
Source: catacomb
Section: libs
Priority: extra
-Build-Depends: mlib-dev (>= 2.2.1), debhelper (>= 9)
+Build-Depends: debhelper (>= 9), python, pkg-config, mlib-dev (>= 2.2.2.1)
Maintainer: Mark Wooding <mdw@distorted.org.uk>
Standards-Version: 3.1.1
## Main user-visible multiprecision arithmetic.
pkginclude_HEADERS += mp.h
libmath_la_SOURCES += mp-arith.c
-TESTS += mp-arith.$t
+TESTS += mp-arith.t$(EXEEXT)
libmath_la_SOURCES += mp-const.c
libmath_la_SOURCES += mp-exp.c mp-exp.h
libmath_la_SOURCES += mp-gcd.c
-TESTS += mp-gcd.$t
+TESTS += mp-gcd.t$(EXEEXT)
libmath_la_SOURCES += mp-io.c
libmath_la_SOURCES += mp-jacobi.c
-TESTS += mp-jacobi.$t
+TESTS += mp-jacobi.t$(EXEEXT)
libmath_la_SOURCES += mp-mem.c
libmath_la_SOURCES += mp-misc.c
libmath_la_SOURCES += mp-modexp.c
-TESTS += mp-modexp.$t
+TESTS += mp-modexp.t$(EXEEXT)
libmath_la_SOURCES += mp-modsqrt.c
-TESTS += mp-modsqrt.$t
+TESTS += mp-modsqrt.t$(EXEEXT)
libmath_la_SOURCES += mp-sqrt.c
-TESTS += mp-sqrt.$t
+TESTS += mp-sqrt.t$(EXEEXT)
libmath_la_SOURCES += mp-test.c
EXTRA_DIST += t/mp
## Computing Fibonacci numbers.
pkginclude_HEADERS += mp-fibonacci.h
libmath_la_SOURCES += mp-fibonacci.c
-TESTS += mp-fibonacci.$t
+TESTS += mp-fibonacci.t$(EXEEXT)
## Special memory allocation for multiprecision integers.
pkginclude_HEADERS += mparena.h
## Barrett reduction, an efficient method for modular reduction.
pkginclude_HEADERS += mpbarrett.h
libmath_la_SOURCES += mpbarrett.c
-TESTS += mpbarrett.$t
+TESTS += mpbarrett.t$(EXEEXT)
libmath_la_SOURCES += mpbarrett-exp.c mpbarrett-mexp.c mpbarrett-exp.h
-TESTS += mpbarrett-exp.$t mpbarrett-mexp.$t
-TESTS += mpbarrett.$t
+TESTS += mpbarrett-exp.t$(EXEEXT) mpbarrett-mexp.t$(EXEEXT)
+TESTS += mpbarrett.t$(EXEEXT)
EXTRA_DIST += t/mpbarrett
## Solving congruences using the Chinese Remainder Theorem.
pkginclude_HEADERS += mpcrt.h
libmath_la_SOURCES += mpcrt.c
-TESTS += mpcrt.$t
+TESTS += mpcrt.t$(EXEEXT)
EXTRA_DIST += t/mpcrt
## Conversions between machine-native and multiprecision integers.
pkginclude_HEADERS += mpint.h
libmath_la_SOURCES += mpint.c
-TESTS += mpint.$t
+TESTS += mpint.t$(EXEEXT)
EXTRA_DIST += t/mpint
## Montgomery reduction, a clever method for modular arithmetic.
pkginclude_HEADERS += mpmont.h
libmath_la_SOURCES += mpmont.c
-TESTS += mpmont.$t
+TESTS += mpmont.t$(EXEEXT)
libmath_la_SOURCES += mpmont-exp.c mpmont-mexp.c mpmont-exp.h
-TESTS += mpmont-exp.$t mpmont-mexp.$t
+TESTS += mpmont-exp.t$(EXEEXT) mpmont-mexp.t$(EXEEXT)
EXTRA_DIST += t/mpmont
## Efficient multiplication of many small numbers.
pkginclude_HEADERS += mpmul.h
libmath_la_SOURCES += mpmul.c
-TESTS += mpmul.$t
+TESTS += mpmul.t$(EXEEXT)
## Generating random numbers.
pkginclude_HEADERS += mprand.h
## representations.
pkginclude_HEADERS += mpreduce.h
libmath_la_SOURCES += mpreduce.c mpreduce-exp.h
-TESTS += mpreduce.$t
+TESTS += mpreduce.t$(EXEEXT)
EXTRA_DIST += t/mpreduce
## Iteratiion over the bianry representation of multiprecision integers.
## representations.
pkginclude_HEADERS += mptext.h
libmath_la_SOURCES += mptext.c
-TESTS += mptext.$t
+TESTS += mptext.t$(EXEEXT)
libmath_la_SOURCES += mptext-dstr.c
libmath_la_SOURCES += mptext-file.c
libmath_la_SOURCES += mptext-len.c
## Low-level multiprecision arithmetic.
pkginclude_HEADERS += mpx.h bitops.h mpw.h
libmath_la_SOURCES += mpx.c
-TESTS += mpx.$t
+TESTS += mpx.t$(EXEEXT)
libmath_la_SOURCES += karatsuba.h mpx-kmul.c mpx-ksqr.c
-TESTS += mpx-kmul.$t mpx-ksqr.$t
+TESTS += mpx-kmul.t$(EXEEXT) mpx-ksqr.t$(EXEEXT)
noinst_PROGRAMS += bittest
TESTS += bittest
EXTRA_DIST += t/mpx
## Pollard's `rho' algorithm for determining discrete logarithms.
pkginclude_HEADERS += rho.h
libmath_la_SOURCES += rho.c
-TESTS += rho.$t
+TESTS += rho.t$(EXEEXT)
###--------------------------------------------------------------------------
### Prime number checking, searching, and related jobs.
libmath_la_SOURCES += limlee.c
## A table of small prime numbers.
-pkginclude_HEADERS += $(precomp)/primetab.h
-libmath_la_SOURCES += $(precomp)/primetab.c
-PRECOMPS += $(precomp)/primetab.h $(precomp)/primetab.c
+pkginclude_HEADERS += $(precomp)/math/primetab.h
+nodist_libmath_la_SOURCES += ../precomp/math/primetab.c
+PRECOMPS += $(precomp)/math/primetab.h \
+ $(precomp)/math/primetab.c
PRECOMP_PROGS += genprimes
genprimes_LDADD = $(mLib_LIBS)
if !CROSS_COMPILING
-$(precomp)/primetab.h: $(precomp)/primetab.c
-$(precomp)/primetab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) genprimes$e
+$(precomp)/math/primetab.h: $(precomp)/math/primetab.c
+$(precomp)/math/primetab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/math
+ $(AM_V_at)$(MAKE) genprimes$(EXEEXT)
$(AM_V_GEN)./genprimes -sCATACOMB_PRIMETAB_H \
- -h$(precomp)/primetab.h -c$(precomp)/primetab.c \
+ -h$(precomp)/math/primetab.h -c$(precomp)/math/primetab.c \
-n256 -t"unsigned short" -iprimetab
endif
libmath_la_SOURCES += pgen-gcd.c
libmath_la_SOURCES += pgen-simul.c
libmath_la_SOURCES += pgen-stdev.c
-TESTS += pgen.$t
+TESTS += pgen.t$(EXEEXT)
EXTRA_DIST += t/pgen
## Finding primitive elements in finite fields.
## Iterating over all prime numbers from a given starting point.
pkginclude_HEADERS += primeiter.h
libmath_la_SOURCES += primeiter.c
-TESTS += primeiter.$t
-primeiter.lo: $(precomp)/wheel.h
+TESTS += primeiter.t$(EXEEXT)
+primeiter.lo: $(precomp)/math/wheel.h
## The Miller--Rabin primality test.
pkginclude_HEADERS += rabin.h
libmath_la_SOURCES += strongprime.c
## A `wheel', used by the prime iteration machinery.
-pkginclude_HEADERS += $(precomp)/wheel.h
-libmath_la_SOURCES += $(precomp)/wheel.c
-PRECOMPS += $(precomp)/wheel.h $(precomp)/wheel.c
+pkginclude_HEADERS += $(precomp)/math/wheel.h
+nodist_libmath_la_SOURCES += ../precomp/math/wheel.c
+PRECOMPS += $(precomp)/math/wheel.h $(precomp)/math/wheel.c
PRECOMP_PROGS += genwheel
genwheel_LDADD = $(mLib_LIBS)
if !CROSS_COMPILING
-$(precomp)/wheel.h: $(precomp)/wheel.c
-$(precomp)/wheel.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) genwheel$e
+$(precomp)/math/wheel.h: $(precomp)/math/wheel.c
+$(precomp)/math/wheel.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/math
+ $(AM_V_at)$(MAKE) genwheel$(EXEEXT)
$(AM_V_GEN)./genwheel -sCATACOMB_WHEEL_H \
- -h$(precomp)/wheel.h -c$(precomp)/wheel.c \
+ -h$(precomp)/math/wheel.h -c$(precomp)/math/wheel.c \
-n5 -t"unsigned char" -iwheel
endif
## User-visible binary polynomial arithmetic.
pkginclude_HEADERS += gf.h
libmath_la_SOURCES += gf-arith.c
-TESTS += gf-arith.$t
+TESTS += gf-arith.t$(EXEEXT)
libmath_la_SOURCES += gf-exp.c gf-exp.h
libmath_la_SOURCES += gf-gcd.c
-TESTS += gf-gcd.$t
+TESTS += gf-gcd.t$(EXEEXT)
EXTRA_DIST += t/gf
## Low-level binary polynomial arithmetic.
pkginclude_HEADERS += gfx.h
libmath_la_SOURCES += gfx.c
-TESTS += gfx.$t
+TESTS += gfx.t$(EXEEXT)
libmath_la_SOURCES += gfx-kmul.c
-TESTS += gfx-kmul.$t
-libmath_la_SOURCES += gfx-sqr.c $(precomp)/gfx-sqrtab.c
-PRECOMPS += $(precomp)/gfx-sqrtab.c
+TESTS += gfx-kmul.t$(EXEEXT)
+libmath_la_SOURCES += gfx-sqr.c
+nodist_libmath_la_SOURCES += ../precomp/math/gfx-sqrtab.c
+PRECOMPS += $(precomp)/math/gfx-sqrtab.c
PRECOMP_PROGS += gfx-sqr-mktab
if !CROSS_COMPILING
-$(precomp)/gfx-sqrtab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) gfx-sqr-mktab$e
- $(AM_V_GEN)./gfx-sqr-mktab >$(precomp)/gfx-sqrtab.c.new && \
- mv $(precomp)/gfx-sqrtab.c.new $(precomp)/gfx-sqrtab.c
+$(precomp)/math/gfx-sqrtab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/math
+ $(AM_V_at)$(MAKE) gfx-sqr-mktab$(EXEEXT)
+ $(AM_V_GEN)./gfx-sqr-mktab >$(precomp)/math/gfx-sqrtab.c.new && \
+ mv $(precomp)/math/gfx-sqrtab.c.new \
+ $(precomp)/math/gfx-sqrtab.c
endif
-TESTS += gfx-sqr.$t
+TESTS += gfx-sqr.t$(EXEEXT)
EXTRA_DIST += t/gfx
## Conversions between normal and polynomial basis representations for binary
## fields.
pkginclude_HEADERS += gfn.h
libmath_la_SOURCES += gfn.c
-TESTS += gfn.$t
+TESTS += gfn.t$(EXEEXT)
EXTRA_DIST += t/gfn
## Efficient reduction modulo sparse polynomials.
pkginclude_HEADERS += gfreduce.h
libmath_la_SOURCES += gfreduce.c gfreduce-exp.h
-TESTS += gfreduce.$t
+TESTS += gfreduce.t$(EXEEXT)
EXTRA_DIST += t/gfreduce
###--------------------------------------------------------------------------
libmath_la_SOURCES += g-prime.c
libmath_la_SOURCES += g-ec.c
EXTRA_DIST += group-test.c
-TESTS += group-test.$t
+TESTS += group-test.t$(EXEEXT)
EXTRA_DIST += t/group
## Abstract finite fields.
libmath_la_SOURCES += ec.c
libmath_la_SOURCES += ec-exp.c ec-exp.h
libmath_la_SOURCES += ec-info.c
-TESTS += ec-info.$t
+TESTS += ec-info.t$(EXEEXT)
libmath_la_SOURCES += ec-bin.c
-TESTS += ec-bin.$t
+TESTS += ec-bin.t$(EXEEXT)
libmath_la_SOURCES += ec-prime.c
-TESTS += ec-prime.$t
+TESTS += ec-prime.t$(EXEEXT)
EXTRA_DIST += t/ec
## The standard `raw' encoding (`EC2OSP') of elliptic curve points.
## Test infrastructure for elliptic curves.
pkginclude_HEADERS += ec-test.h
libmath_la_SOURCES += ec-test.c
-TESTS += ec-test.$t
+TESTS += ec-test.t$(EXEEXT)
## Table of built-in elliptic-curve groups.
pkginclude_HEADERS += ectab.h
* %$F_{k-1} = F_{k+1} - F_k$%; in particular, %$F_{-1} = 1$% and
* %$F_{-2} = -1$%.) We say that %$F_k$% is the %$k$%th Fibonacci number.
*
- * We work in the ring %$\ZZ[t]/(t^2 - t -1)$%. Every residue class in this
+ * We work in the ring %$\ZZ[t]/(t^2 - t - 1)$%. Every residue class in this
* ring contains a unique representative with degree at most 1. I claim that
* %$t^k = F_k t + F_{k-1}$% for all %$k$%. Certainly %$t = F_1 t + F_0$%.
* Note that %$t (F_{-1} t + F_{-2}) = t (t - 1) = t^2 - t = 1$%, so the
#include <assert.h>
#include <string.h>
+#include <mLib/macros.h>
#include <mLib/sub.h>
#ifndef CATACOMB_MPW_H
extern mp *mp_copy(mp */*m*/);
-#define MP_COPY(m) ((m)->ref++, (m))
+#define MP_COPY(m) MUFFLE_WARNINGS_EXPR(GCC_WARNING("-Wunused-value"), \
+ ((m)->ref++, (m)))
/* --- @mp_drop@ --- *
*
#define DEPTH (CHAR_BIT * sizeof(size_t) + 10)
-/*----- Main code ---------------------------------------------------------*/
+/*----- Input -------------------------------------------------------------*/
/* --- @mp_read@ --- *
*
* bizarre syntax.
*/
-mp *mp_read(mp *m, int radix, const mptext_ops *ops, void *p)
+static int char_digit(int ch, int radix)
{
- int ch; /* Current char being considered */
- unsigned f = 0; /* Flags about the current number */
- int r; /* Radix to switch over to */
- mpw rd; /* Radix as an @mp@ digit */
- mp rr; /* The @mp@ for the radix */
- unsigned nf = m ? m->f & MP_BURN : 0; /* New @mp@ flags */
-
- /* --- Stacks --- */
-
- mp *pow[DEPTH]; /* List of powers */
- unsigned pows; /* Next index to fill */
- struct { unsigned i; mp *m; } s[DEPTH]; /* Main stack */
- unsigned sp; /* Current stack pointer */
-
- /* --- Flags --- */
-
-#define f_neg 1u
-#define f_ok 2u
-#define f_start 4u
-
- /* --- Initialize the stacks --- */
-
- mp_build(&rr, &rd, &rd + 1);
- pow[0] = &rr;
- pows = 1;
-
- sp = 0;
-
- /* --- Initialize the destination number --- */
-
- if (m)
- MP_DROP(m);
-
- /* --- Read an initial character --- */
-
- ch = ops->get(p);
- if (radix >= 0) {
- while (isspace(ch))
- ch = ops->get(p);
- }
-
- /* --- Handle an initial sign --- */
-
- if (radix >= 0 && (ch == '-' || ch == '+')) {
- if (ch == '-')
- f |= f_neg;
- do ch = ops->get(p); while isspace(ch);
- }
-
- /* --- If the radix is zero, look for leading zeros --- */
-
- if (radix > 0) {
- assert(((void)"ascii radix must be <= 62", radix <= 62));
- rd = radix;
- r = -1;
- } else if (radix < 0) {
- rd = -radix;
- assert(((void)"binary radix must fit in a byte", rd <= UCHAR_MAX));
- r = -1;
- } else if (ch != '0') {
- rd = 10;
- r = 0;
- } else {
- ch = ops->get(p);
- switch (ch) {
- case 'x':
- rd = 16;
- goto prefix;
- case 'o':
- rd = 8;
- goto prefix;
- case 'b':
- rd = 2;
- goto prefix;
- prefix:
- ch = ops->get(p);
- break;
- default:
- rd = 8;
- f |= f_ok;
- }
- r = -1;
- }
-
- /* --- Use fast algorithm for binary radix --- *
- *
- * This is the restart point after having parsed a radix number from the
- * input. We check whether the radix is binary, and if so use a fast
- * algorithm which just stacks the bits up in the right order.
- */
+ int r = radix < 0 ? -radix : radix;
+ int d;
+
+ if (ch < 0) return (-1);
+ if (radix < 0) d = ch;
+ else if ('0' <= ch && ch <= '9') d = ch - '0';
+ else if ('a' <= ch && ch <= 'z') d = ch - 'a' + 10;
+ else if ('A' <= ch && ch <= 'Z') d = ch - 'A' + (radix > 36 ? 36 : 10);
+ else return (-1);
+ if (d >= r) return (-1);
+ return (d);
+}
-restart:
- switch (rd) {
- unsigned bit;
-
- case 2: bit = 1; goto bin;
- case 4: bit = 2; goto bin;
- case 8: bit = 3; goto bin;
- case 16: bit = 4; goto bin;
- case 32: bit = 5; goto bin;
- case 64: bit = 6; goto bin;
- case 128: bit = 7; goto bin;
- default:
- break;
+static mp *read_binary(int radix, unsigned bit, unsigned nf,
+ const mptext_ops *ops, void *p)
+{
+ mpw a = 0;
+ unsigned b = MPW_BITS;
+ int any = 0, nz = 0;
+ int ch, d;
+ size_t len, n;
+ mpw *v;
+ mp *m;
/* --- The fast binary algorithm --- *
*
* bit-shift when we know where the end of the number is.
*/
- bin: {
- mpw a = 0;
- unsigned b = MPW_BITS;
- size_t len, n;
- mpw *v;
-
- m = mp_dest(MP_NEW, 1, nf);
- len = n = m->sz;
- n = len;
- v = m->v + n;
- for (;; ch = ops->get(p)) {
- unsigned x;
+ m = mp_dest(MP_NEW, 1, nf);
+ len = n = m->sz;
+ n = len;
+ v = m->v + n;
- if (ch < 0)
- break;
+ for (;;) {
+ ch = ops->get(p);
+ if ((d = char_digit(ch, radix)) < 0) break;
- /* --- Check that the character is a digit and in range --- */
+ /* --- Ignore leading zeroes, but notice that the number is valid --- */
- if (radix < 0)
- x = ch % rd;
- else {
- if (!isalnum(ch))
- break;
- if (ch >= '0' && ch <= '9')
- x = ch - '0';
- else {
- if (rd <= 36)
- ch = tolower(ch);
- if (ch >= 'a' && ch <= 'z') /* ASCII dependent! */
- x = ch - 'a' + 10;
- else if (ch >= 'A' && ch <= 'Z')
- x = ch - 'A' + 36;
- else
- break;
- }
- }
- if (x >= rd)
- break;
-
- /* --- Feed the digit into the accumulator --- */
-
- f |= f_ok;
- if (!x && !(f & f_start))
- continue;
- f |= f_start;
- if (b > bit) {
- b -= bit;
- a |= MPW(x) << b;
- } else {
- a |= MPW(x) >> (bit - b);
- b += MPW_BITS - bit;
- *--v = MPW(a);
- n--;
- if (!n) {
- n = len;
- len <<= 1;
- v = mpalloc(m->a, len);
- memcpy(v + n, m->v, MPWS(n));
- mpfree(m->a, m->v);
- m->v = v;
- v = m->v + n;
- }
- a = (b < MPW_BITS) ? MPW(x) << b : 0;
- }
- }
+ any = 1;
+ if (!d && !nz) continue;
+ nz = 1;
- /* --- Finish up --- */
+ /* --- Feed the digit into the accumulator --- */
- if (!(f & f_ok)) {
- mp_drop(m);
- m = 0;
+ if (b > bit) {
+ b -= bit;
+ a |= MPW(d) << b;
} else {
- *--v = MPW(a);
- n--;
- m->sz = len;
- m->vl = m->v + len;
- m->f &= ~MP_UNDEF;
- m = mp_lsr(m, m, (unsigned long)n * MPW_BITS + b);
+ a |= MPW(d) >> (bit - b);
+ b += MPW_BITS - bit;
+ *--v = MPW(a); n--;
+ if (!n) {
+ n = len; len <<= 1;
+ v = mpalloc(m->a, len);
+ memcpy(v + n, m->v, MPWS(n));
+ mpfree(m->a, m->v);
+ m->v = v; v = m->v + n;
+ }
+ a = (b < MPW_BITS) ? MPW(d) << b : 0;
}
- ops->unget(ch, p);
- goto done;
- }}
+ }
- /* --- Time to start --- */
+ /* --- Finish up --- */
- for (;; ch = ops->get(p)) {
- unsigned x;
+ ops->unget(ch, p);
+ if (!any) { mp_drop(m); return (0); }
- if (ch < 0)
- break;
+ *--v = MPW(a); n--;
+ m->sz = len;
+ m->vl = m->v + len;
+ m->f &= ~MP_UNDEF;
+ m = mp_lsr(m, m, (unsigned long)n * MPW_BITS + b);
- /* --- An underscore indicates a numbered base --- */
+ return (m);
+}
- if (ch == '_' && r > 0 && r <= 62) {
- unsigned i;
+struct readstate {
- /* --- Clear out the stacks --- */
+ /* --- State for the general-base reader --- *
+ *
+ * There are two arrays. The @pow@ array is set so that @pow[i]@ contains
+ * %$R^{2^i}$% for @i < pows@. The stack @s@ contains partial results:
+ * each entry contains a value @m@ corresponding to %$2^i$% digits.
+ * Inductively, an empty stack represents zero; if a stack represents %$x$%
+ * then pushing a new entry on the top causes the stack to represent
+ * %$R^{2^i} x + m$%.
+ *
+ * It is an invariant that each entry has a strictly smaller @i@ than the
+ * items beneath it. This is achieved by coaslescing entries at the top if
+ * they have equal %$i$% values: if the top items are %$(m, i)$%, and
+ * %$(M', i)$%, and the rest of the stack represents the integer %$x$%,
+ * then %$R^{2^i} (R^{2^i} x + M) + m = R^{2^{i+1}} x + (R^{2^i} M + m)$%,
+ * so we replace the top two items by %$((R^{2^i} M + m), i + 1)$%, and
+ * repeat if necessary.
+ */
- for (i = 1; i < pows; i++)
- MP_DROP(pow[i]);
- pows = 1;
- for (i = 0; i < sp; i++)
- MP_DROP(s[i].m);
- sp = 0;
+ unsigned pows, sp;
+ struct { unsigned i; mp *m; } s[DEPTH];
+ mp *pow[DEPTH];
+};
- /* --- Restart the search --- */
+static void ensure_power(struct readstate *rs)
+{
+ /* --- Make sure we have the necessary %$R^{2^i}$% computed --- */
- rd = r;
- r = -1;
- f &= ~f_ok;
- ch = ops->get(p);
- goto restart;
- }
+ if (rs->s[rs->sp].i >= rs->pows) {
+ assert(rs->pows < DEPTH);
+ rs->pow[rs->pows] = mp_sqr(MP_NEW, rs->pow[rs->pows - 1]);
+ rs->pows++;
+ }
+}
- /* --- Check that the character is a digit and in range --- */
+static void read_digit(struct readstate *rs, unsigned nf, int d)
+{
+ mp *m = mp_new(1, nf);
+ m->v[0] = d;
- if (radix < 0)
- x = ch % rd;
- else {
- if (!isalnum(ch))
- break;
- if (ch >= '0' && ch <= '9')
- x = ch - '0';
- else {
- if (rd <= 36)
- ch = tolower(ch);
- if (ch >= 'a' && ch <= 'z') /* ASCII dependent! */
- x = ch - 'a' + 10;
- else if (ch >= 'A' && ch <= 'Z')
- x = ch - 'A' + 36;
- else
- break;
- }
- }
+ /* --- Put the new digit on top --- */
- /* --- Sort out what to do with the character --- */
+ assert(rs->sp < DEPTH);
+ rs->s[rs->sp].m = m;
+ rs->s[rs->sp].i = 0;
- if (x >= 10 && r >= 0)
- r = -1;
- if (x >= rd)
- break;
+ /* --- Restore the stack invariant --- */
- if (r >= 0)
- r = r * 10 + x;
+ while (rs->sp && rs->s[rs->sp - 1].i <= rs->s[rs->sp].i) {
+ assert(rs->sp > 0);
+ ensure_power(rs);
+ rs->sp--;
- /* --- Stick the character on the end of my integer --- */
+ m = rs->s[rs->sp].m;
+ m = mp_mul(m, m, rs->pow[rs->s[rs->sp + 1].i]);
+ m = mp_add(m, m, rs->s[rs->sp + 1].m);
+ MP_DROP(rs->s[rs->sp + 1].m);
+ rs->s[rs->sp].m = m;
+ rs->s[rs->sp].i++;
+ }
- assert(((void)"Number is too unimaginably huge", sp < DEPTH));
- s[sp].m = m = mp_new(1, nf);
- m->v[0] = x;
- s[sp].i = 0;
+ /* --- Leave the stack pointer at an empty item --- */
- /* --- Now grind through the stack --- */
+ rs->sp++;
+}
- while (sp > 0 && s[sp - 1].i == s[sp].i) {
+static mp *read_general(int radix, unsigned t, unsigned nf,
+ const mptext_ops *ops, void *p)
+{
+ struct readstate rs;
+ unsigned char v[4];
+ unsigned i;
+ mpw r;
+ int any = 0;
+ int ch, d;
+ mp rr;
+ mp *m, *z, *n;
+
+ /* --- Prepare the stack --- */
+
+ r = radix < 0 ? -radix : radix;
+ mp_build(&rr, &r, &r + 1);
+ rs.pow[0] = &rr;
+ rs.pows = 1;
+ rs.sp = 0;
+
+ /* --- If we've partially parsed some input then feed it in --- *
+ *
+ * Unfortunately, what we've got is backwards. Fortunately there's a
+ * fairly tight upper bound on how many digits @t@ might be, since we
+ * aborted that loop once it got too large.
+ */
- /* --- Combine the top two items --- */
+ if (t) {
+ i = 0;
+ while (t) { assert(i < sizeof(v)); v[i++] = t%r; t /= r; }
+ while (i) read_digit(&rs, nf, v[--i]);
+ any = 1;
+ }
- sp--;
- m = s[sp].m;
- m = mp_mul(m, m, pow[s[sp].i]);
- m = mp_add(m, m, s[sp + 1].m);
- s[sp].m = m;
- MP_DROP(s[sp + 1].m);
- s[sp].i++;
+ /* --- Read more stuff --- */
- /* --- Make a new radix power if necessary --- */
+ for (;;) {
+ ch = ops->get(p);
+ if ((d = char_digit(ch, radix)) < 0) break;
+ read_digit(&rs, nf, d); any = 1;
+ }
+ ops->unget(ch, p);
- if (s[sp].i >= pows) {
- assert(((void)"Number is too unimaginably huge", pows < DEPTH));
- pow[pows] = mp_sqr(MP_NEW, pow[pows - 1]);
- pows++;
- }
- }
- f |= f_ok;
- sp++;
+ /* --- Stitch all of the numbers together --- *
+ *
+ * This is not the same code as @read_digit@. In particular, here we must
+ * cope with the partial result being some inconvenient power of %$R$%,
+ * rather than %$R^{2^i}$%.
+ */
+
+ if (!any) return (0);
+ m = MP_ZERO; z = MP_ONE;
+ while (rs.sp) {
+ rs.sp--;
+ ensure_power(&rs);
+ n = rs.s[rs.sp].m;
+ n = mp_mul(n, n, z);
+ m = mp_add(m, m, n);
+ z = mp_mul(z, z, rs.pow[rs.s[rs.sp].i]);
+ MP_DROP(n);
}
+ for (i = 0; i < rs.pows; i++) MP_DROP(rs.pow[i]);
+ MP_DROP(z);
+ return (m);
+}
- ops->unget(ch, p);
+mp *mp_read(mp *m, int radix, const mptext_ops *ops, void *p)
+{
+ unsigned t = 0;
+ unsigned nf = 0;
+ int ch, d, rd;
+
+ unsigned f = 0;
+#define f_neg 1u
+#define f_ok 2u
+
+ /* --- We don't actually need a destination so throw it away --- *
+ *
+ * But note the flags before we lose it entirely.
+ */
- /* --- If we're done, compute the rest of the number --- */
+ if (m) {
+ nf = m->f & MP_BURN;
+ MP_DROP(m);
+ }
- if (f & f_ok) {
- if (!sp)
- return (MP_ZERO);
- else {
- mp *z = MP_ONE;
- sp--;
+ /* --- Maintain a lookahead character --- */
- while (sp > 0) {
+ ch = ops->get(p);
- /* --- Combine the top two items --- */
+ /* --- If we're reading text, skip leading space, and maybe a sign --- */
- sp--;
- m = s[sp].m;
- z = mp_mul(z, z, pow[s[sp + 1].i]);
- m = mp_mul(m, m, z);
- m = mp_add(m, m, s[sp + 1].m);
- s[sp].m = m;
- MP_DROP(s[sp + 1].m);
+ if (radix >= 0) {
+ while (isspace(ch)) ch = ops->get(p);
+ switch (ch) {
+ case '-': f |= f_neg; /* and on */
+ case '+': do ch = ops->get(p); while (isspace(ch));
+ }
+ }
- /* --- Make a new radix power if necessary --- */
+ /* --- If we don't have a fixed radix, then parse one from the input --- *
+ *
+ * This is moderately easy if the input starts with `0x' or similar. If it
+ * starts with `0' and something else, then it might be octal, or just a
+ * plain old zero. Finally, it might start with a leading `NN_', in which
+ * case we carefully collect the decimal number until we're sure it's
+ * either a radix prefix (in which case we accept it and start over) or it
+ * isn't (in which case it's actually the start of a large number we need
+ * to read).
+ */
- if (s[sp].i >= pows) {
- assert(((void)"Number is too unimaginably huge", pows < DEPTH));
- pow[pows] = mp_sqr(MP_NEW, pow[pows - 1]);
- pows++;
- }
+ if (radix == 0) {
+ if (ch == '0') {
+ ch = ops->get(p);
+ switch (ch) {
+ case 'x': case 'X': radix = 16; goto fetch;
+ case 'o': case 'O': radix = 8; goto fetch;
+ case 'b': case 'B': radix = 2; goto fetch;
+ fetch: ch = ops->get(p); break;
+ default: radix = 8; f |= f_ok; break;
+ }
+ } else {
+ if ((d = char_digit(ch, 10)) < 0) { ops->unget(ch, p); return (0); }
+ for (;;) {
+ t = 10*t + d;
+ ch = ops->get(p);
+ if (t > 52) break;
+ if ((d = char_digit(ch, 10)) < 0) break;
+ }
+ if (ch != '_' || t > 52) radix = 10;
+ else {
+ radix = t; t = 0;
+ ch = ops->get(p);
}
- MP_DROP(z);
- m = s[0].m;
}
- } else {
- unsigned i;
- for (i = 0; i < sp; i++)
- MP_DROP(s[i].m);
}
- /* --- Clear the radix power list --- */
+ /* --- We're now ready to dispatch to the correct handler --- */
- {
- unsigned i;
- for (i = 1; i < pows; i++)
- MP_DROP(pow[i]);
+ rd = radix < 0 ? -radix : radix;
+ ops->unget(ch, p);
+ switch (rd) {
+ case 2: m = read_binary(radix, 1, nf, ops, p); break;
+ case 4: m = read_binary(radix, 2, nf, ops, p); break;
+ case 8: m = read_binary(radix, 3, nf, ops, p); break;
+ case 16: m = read_binary(radix, 4, nf, ops, p); break;
+ case 32: m = read_binary(radix, 5, nf, ops, p); break;
+ case 64: m = read_binary(radix, 6, nf, ops, p); break;
+ case 128: m = read_binary(radix, 7, nf, ops, p); break;
+ default: m = read_general(radix, t, nf, ops, p); break;
}
- /* --- Bail out if the number was bad --- */
+ /* --- That didn't work --- *
+ *
+ * If we've already read something then return that. Otherwise it's an
+ * error.
+ */
-done:
- if (!(f & f_ok))
- return (0);
+ if (!m) {
+ if (f & f_ok) return (MP_ZERO);
+ else return (0);
+ }
- /* --- Set the sign and return --- */
+ /* --- Negate the result if we should do that --- */
+
+ if (f & f_neg) m = mp_neg(m, m);
+
+ /* --- And we're all done --- */
- if (f & f_neg)
- m->f |= MP_NEG;
- MP_SHRINK(m);
return (m);
-#undef f_start
#undef f_neg
#undef f_ok
}
+/*----- Output ------------------------------------------------------------*/
+
/* --- @mp_write@ --- *
*
* Arguments: @mp *m@ = pointer to a multi-precision integer
* Use: Writes a large integer in textual form.
*/
+static int digit_char(int d, int radix)
+{
+ if (radix < 0) return (d);
+ else if (d < 10) return (d + '0');
+ else if (d < 26) return (d - 10 + 'a');
+ else return (d - 36 + 'A');
+}
+
/* --- Simple case --- *
*
* Use a fixed-sized buffer and single-precision arithmetic to pick off
* enough real digits.
*/
-static int simple(mpw n, int radix, unsigned z,
- const mptext_ops *ops, void *p)
+static int write_simple(mpw n, int radix, unsigned z,
+ const mptext_ops *ops, void *p)
{
int rc = 0;
char buf[64];
unsigned i = sizeof(buf);
int rd = radix > 0 ? radix : -radix;
+ mpw x;
do {
- int ch;
- mpw x;
-
- x = n % rd;
- n /= rd;
- if (radix < 0)
- ch = x;
- else if (x < 10)
- ch = '0' + x;
- else if (x < 36) /* Ascii specific */
- ch = 'a' + x - 10;
- else
- ch = 'A' + x - 36;
- buf[--i] = ch;
- if (z)
- z--;
+ x = n % rd; n /= rd;
+ buf[--i] = digit_char(x, radix);
+ if (z) z--;
} while (i && n);
if (n)
- rc = simple(n, radix, z, ops, p);
+ rc = write_simple(n, radix, z, ops, p);
else {
char zbuf[32];
memset(zbuf, (radix < 0) ? 0 : '0', sizeof(zbuf));
rc = ops->put(zbuf, sizeof(zbuf), p);
z -= sizeof(zbuf);
}
- if (!rc && z)
- rc = ops->put(zbuf, z, p);
+ if (!rc && z) rc = ops->put(zbuf, z, p);
}
- if (!rc)
- rc = ops->put(buf + i, sizeof(buf) - i, p);
+ if (!rc) rc = ops->put(buf + i, sizeof(buf) - i, p);
BURN(buf);
return (rc);
}
* leading zeroes on the remainder part, because they're deeply significant.
*/
-static int complicated(mp *m, int radix, mp **pr, unsigned i, unsigned z,
- const mptext_ops *ops, void *p)
+static int write_complicated(mp *m, int radix, mp **pr,
+ unsigned i, unsigned z,
+ const mptext_ops *ops, void *p)
{
int rc = 0;
mp *q = MP_NEW;
unsigned d = 1 << i;
if (MP_LEN(m) < 2)
- return (simple(MP_LEN(m) ? m->v[0] : 0, radix, z, ops, p));
+ return (write_simple(MP_LEN(m) ? m->v[0] : 0, radix, z, ops, p));
assert(i);
mp_div(&q, &m, m, pr[i]);
- if (MP_ZEROP(q))
- d = z;
+ if (MP_ZEROP(q)) d = z;
else {
- if (z > d)
- z -= d;
- else
- z = 0;
- rc = complicated(q, radix, pr, i - 1, z, ops, p);
+ if (z > d) z -= d;
+ else z = 0;
+ rc = write_complicated(q, radix, pr, i - 1, z, ops, p);
}
- if (!rc)
- rc = complicated(m, radix, pr, i - 1, d, ops, p);
+ if (!rc) rc = write_complicated(m, radix, pr, i - 1, d, ops, p);
mp_drop(q);
return (rc);
}
* Special case for binary output. Goes much faster.
*/
-static int binary(mp *m, int bit, int radix, const mptext_ops *ops, void *p)
+static int write_binary(mp *m, int bit, int radix,
+ const mptext_ops *ops, void *p)
{
mpw *v;
mpw a;
unsigned f = 0;
char buf[8], *q;
unsigned x;
- int ch;
#define f_out 1u
/* --- Work out where to start --- */
n = mp_bits(m);
- if (n % bit)
- n += bit - (n % bit);
+ if (n % bit) n += bit - (n % bit);
b = n % MPW_BITS;
n /= MPW_BITS;
} else {
x = a << (bit - b);
b += MPW_BITS - bit;
- if (v == m->v)
- break;
+ if (v == m->v) break;
a = *--v;
- if (b < MPW_BITS)
- x |= a >> b;
+ if (b < MPW_BITS) x |= a >> b;
}
x &= mask;
- if (!x && !(f & f_out))
- continue;
-
- if (radix < 0)
- ch = x;
- else if (x < 10)
- ch = '0' + x;
- else if (x < 36)
- ch = 'a' + x - 10; /* Ascii specific */
- else
- ch = 'A' + x - 36;
- *q++ = ch;
+ if (!x && !(f & f_out)) continue;
+
+ *q++ = digit_char(x, radix);
if (q >= buf + sizeof(buf)) {
- if ((rc = ops->put(buf, sizeof(buf), p)) != 0)
- goto done;
+ if ((rc = ops->put(buf, sizeof(buf), p)) != 0) goto done;
q = buf;
}
f |= f_out;
}
x &= mask;
- if (radix < 0)
- ch = x;
- else if (x < 10)
- ch = '0' + x;
- else if (x < 36)
- ch = 'a' + x - 10; /* Ascii specific */
- else
- ch = 'A' + x - 36;
- *q++ = ch;
+ *q++ = digit_char(x, radix);
rc = ops->put(buf, q - buf, p);
done:
int mp_write(mp *m, int radix, const mptext_ops *ops, void *p)
{
int rc;
+ mp *pr[DEPTH];
+ size_t target;
+ unsigned i = 0;
+ mp *z;
if (MP_EQ(m, MP_ZERO))
return (ops->put(radix > 0 ? "0" : "\0", 1, p));
if (MP_NEGP(m)) {
assert(radix > 0);
- if (ops->put("-", 1, p))
- return (EOF);
+ if (ops->put("-", 1, p)) return (EOF);
m->f &= ~MP_NEG;
}
/* --- Handle binary radix --- */
switch (radix) {
- case 2: case -2: return (binary(m, 1, radix, ops, p));
- case 4: case -4: return (binary(m, 2, radix, ops, p));
- case 8: case -8: return (binary(m, 3, radix, ops, p));
- case 16: case -16: return (binary(m, 4, radix, ops, p));
- case 32: case -32: return (binary(m, 5, radix, ops, p));
- case -64: return (binary(m, 6, radix, ops, p));
- case -128: return (binary(m, 7, radix, ops, p));
+ case 2: case -2: return (write_binary(m, 1, radix, ops, p));
+ case 4: case -4: return (write_binary(m, 2, radix, ops, p));
+ case 8: case -8: return (write_binary(m, 3, radix, ops, p));
+ case 16: case -16: return (write_binary(m, 4, radix, ops, p));
+ case 32: case -32: return (write_binary(m, 5, radix, ops, p));
+ case -64: return (write_binary(m, 6, radix, ops, p));
+ case -128: return (write_binary(m, 7, radix, ops, p));
}
/* --- If the number is small, do it the easy way --- */
if (MP_LEN(m) < 2)
- rc = simple(MP_LEN(m) ? m->v[0] : 0, radix, 0, ops, p);
+ rc = write_simple(MP_LEN(m) ? m->v[0] : 0, radix, 0, ops, p);
/* --- Use a clever algorithm --- *
*
*/
else {
- mp *pr[DEPTH];
- size_t target = (MP_LEN(m) + 1) / 2;
- unsigned i = 0;
- mp *z = mp_new(1, 0);
+ target = (MP_LEN(m) + 1) / 2;
+ z = mp_new(1, 0);
/* --- Set up the exponent table --- */
for (;;) {
assert(((void)"Number is too unimaginably huge", i < DEPTH));
pr[i++] = z;
- if (MP_LEN(z) > target)
- break;
+ if (MP_LEN(z) > target) break;
z = mp_sqr(MP_NEW, z);
}
/* --- Write out the answer --- */
- rc = complicated(m, radix, pr, i - 1, 0, ops, p);
+ rc = write_complicated(m, radix, pr, i - 1, 0, ops, p);
/* --- Tidy away the array --- */
- while (i > 0)
- mp_drop(pr[--i]);
+ while (i > 0) mp_drop(pr[--i]);
}
/* --- Tidying up code --- */
+++ /dev/null
-/* -*-c-*-
- *
- * Generate `mptypes.h' header file for current architecture
- *
- * (c) 1999 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of Catacomb.
- *
- * Catacomb is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * Catacomb is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with Catacomb; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-/*----- Header files ------------------------------------------------------*/
-
-#define _GNU_SOURCE
-#include "config.h"
-
-#include <stdio.h>
-#include <limits.h>
-#if __STDC_VERSION__ >= 199900l
-# include <stdint.h>
-# include <inttypes.h>
-#endif
-
-/*----- Data types --------------------------------------------------------*/
-
-/* --- Hack for GCC --- *
- *
- * WG14 in their infinite wisdom decided not to use the GCC constant name.
- */
-
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
-# define EXT __extension__
-#else
-# define EXT
-#endif
-
-#if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX)
-# define ULLONG_MAX ULONG_LONG_MAX
-#endif
-
-/* --- Choose the largest integer type --- */
-
-#if defined(UINTMAX_MAX) && defined(PRIuMAX)
- typedef uintmax_t umax;
-# define P_UMAX PRIuMAX
-#elif defined(ULLONG_MAX)
- EXT typedef unsigned long long umax;
-# define P_UMAX "llu"
-#else
- typedef unsigned long umax;
-# define P_UMAX "lu"
-#endif
-
-/* --- Table of interesting types --- *
- *
- * These are in preference order.
- */
-
-enum {
- f_stdint = 1u,
- f_ext = 2u
-};
-
-struct itype {
- const char *name;
- const char *suff;
- umax max;
- unsigned flags;
- unsigned bits;
-} tytab[] = {
- { "unsigned int", "u", UINT_MAX, 0 },
- { "unsigned short", "u", USHRT_MAX, 0 },
- { "unsigned long", "ul", ULONG_MAX, 0 },
-#ifdef ULLONG_MAX
- { "unsigned long long", "ull", EXT ULLONG_MAX, f_ext },
-#endif
-#ifdef UINTMAX_MAX
- { "uintmax_t", "u", UINTMAX_MAX, f_stdint },
-#endif
- { 0, 0 },
-};
-
-typedef struct itype itype;
-
-/*----- Main code ---------------------------------------------------------*/
-
-int main(int argc, char *argv[])
-{
- itype *i;
- itype *largest, *mpw, *mpd;
- const static char *extstr = "CATACOMB_MPTYPES_EXTENSION ";
- unsigned p2;
-
- /* --- Find the bitcounts --- */
-
- for (i = tytab; i->name; i++) {
- unsigned bits;
- umax u = i->max;
- for (bits = 0; u; bits++)
- u >>= 1;
- i->bits = bits;
- }
-
- /* --- Now try to find the interesting types --- *
- *
- * The first thing to do is to find the largest type. Then I find the
- * `best' type which is less than half that size, and then the `best' type
- * which is twice as big as that one.
- */
-
-#if defined(FORCE_MPW_CUSSID)
- largest = mpd = &tytab[3];
- mpw = &tytab[2];
- mpw->bits = 19; mpw->max = 0x7ffff;
- mpd->bits = 38; mpd->max = 0x3fffffffffll;
-#elif defined(FORCE_MPW_SHORT)
- largest = mpd = &tytab[2];
- mpw = &tytab[1];
- mpw->bits = 16; mpw->max = 0xffff;
- mpd->bits = 32; mpd->max = 0xffffffff;
-#else
- largest = tytab;
- for (i = tytab; i->name; i++) {
- if (i->bits > largest->bits)
- largest = i;
- }
- for (mpw = 0, i = tytab; i->name; i++) {
- if (i->bits * 2 <= largest->bits && (!mpw || i->bits > mpw->bits))
- mpw = i;
- }
- if (!mpw)
- mpw = tytab;
- for (mpd = 0, i = tytab; i->name; i++) {
- if (i->bits >= mpw->bits * 2 && (!mpd || i->bits < mpd->bits))
- mpd = i;
- }
- if (!mpd) {
- static itype w, d;
- d = w = *mpw;
- w.bits /= 2; w.max = ~(~((umax)0) << w.bits);
- d.bits = w.bits * 2; d.max = ~(~((umax)0) << d.bits);
- mpw = &w; mpd = &d;
- }
-#endif
- for (p2 = 1; (p2 << 1) < mpw->bits; p2 <<= 1);
-
- /* --- Output time --- */
-
- puts("\
-/* -*-c-*-\n\
- *\n\
- * mptypes.h [generated]\n\
- */\n\
-\n\
-#ifndef CATACOMB_MPTYPES_H\n\
-#define CATACOMB_MPTYPES_H\n\
-");
- if ((mpd->flags | mpw->flags) & f_stdint) {
- puts("\
-#if __STDC_VERSION__ >= 199900l\n\
-# include <stdint.h>\n\
-#endif\n\
-");
- }
- if ((mpd->flags | mpw->flags) & f_ext) {
- printf("\
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)\n\
-# define %s __extension__\n\
-#else\n\
-# define %s\n\
-#endif\n\
-", extstr, extstr);
- }
- printf("\
-%stypedef %s mpw;\n\
-#define MPW_BITS %u\n\
-#define MPW_P2 %u\n\
-#define MPW_MAX %s%" P_UMAX "%s\n\
-\n\
-%stypedef %s mpd;\n\
-#define MPD_BITS %u\n\
-#define MPD_MAX %s%" P_UMAX "%s\n\
-\n\
-#endif\n\
-",
- mpw->flags & f_ext ? extstr : "", mpw->name,
- mpw->bits, p2,
- mpw->flags & f_ext ? extstr : "", mpw->max, mpw->suff,
- mpd->flags & f_ext ? extstr : "", mpd->name,
- mpd->bits,
- mpd->flags & f_ext ? extstr : "", mpd->max, mpd->suff);
-
- return (0);
-}
-
-/*----- That's all, folks -------------------------------------------------*/
noinst_LTLIBRARIES = libmisc.la
libmisc_la_SOURCES =
+nodist_libmisc_la_SOURCES =
TEST_LIBS = libmisc.la
## Efficient sharing over GF(2^8).
pkginclude_HEADERS += gfshare.h
libmisc_la_SOURCES += gfshare.c
-libmisc_la_SOURCES += $(precomp)/gfshare-tab.c
-PRECOMPS += $(precomp)/gfshare-tab.c
+nodist_libmisc_la_SOURCES += ../precomp/misc/gfshare-tab.c
+PRECOMPS += $(precomp)/misc/gfshare-tab.c
PRECOMP_PROGS += gfshare-mktab
if !CROSS_COMPILING
-$(precomp)/gfshare-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) gfshare-mktab$e
- $(AM_V_GEN)./gfshare-mktab >$(precomp)/gfshare-tab.c.new && \
- mv $(precomp)/gfshare-tab.c.new $(precomp)/gfshare-tab.c
+$(precomp)/misc/gfshare-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/misc
+ $(AM_V_at)$(MAKE) gfshare-mktab$(EXEEXT)
+ $(AM_V_GEN)./gfshare-mktab >$(precomp)/misc/gfshare-tab.c.new && \
+ mv $(precomp)/misc/gfshare-tab.c.new \
+ $(precomp)/misc/gfshare-tab.c
endif
-TESTS += gfshare.$t
+TESTS += gfshare.t$(EXEEXT)
## Number-theoretic sharing over GF(p).
pkginclude_HEADERS += share.h
libmisc_la_SOURCES += share.c
-TESTS += share.$t
+TESTS += share.t$(EXEEXT)
###----- That's all, folks --------------------------------------------------
libpub_la_SOURCES += bbs-fetch.c
libpub_la_SOURCES += bbs-gen.c
libpub_la_SOURCES += bbs-jump.c
-TESTS += bbs-jump.$t
+TESTS += bbs-jump.t$(EXEEXT)
libpub_la_SOURCES += bbs-rand.c
-TESTS += bbs-rand.$t
+TESTS += bbs-rand.t$(EXEEXT)
EXTRA_DIST += t/bbs
## Plain Diffie--Hellman, in Schorr groups.
libpub_la_SOURCES += dh-kcdsa.c
libpub_la_SOURCES += dh-limlee.c
libpub_la_SOURCES += dh-param.c
-TESTS += dh-param.$t
+TESTS += dh-param.t$(EXEEXT)
## The National Security Agency's Digital Signature Algorithm.
pkginclude_HEADERS += dsa.h
libpub_la_SOURCES += dsa-gen.c
-TESTS += dsa-gen.$t
+TESTS += dsa-gen.t$(EXEEXT)
libpub_la_SOURCES += dsa-misc.c
libpub_la_SOURCES += dsa-sign.c
-TESTS += dsa-sign.$t
+TESTS += dsa-sign.t$(EXEEXT)
libpub_la_SOURCES += dsa-verify.c
-TESTS += dsa-verify.$t
+TESTS += dsa-verify.t$(EXEEXT)
libpub_la_SOURCES += dsa-check.c
EXTRA_DIST += t/dsa
## Generalization of DSA to arbitrary cyclic groups.
pkginclude_HEADERS += gdsa.h
libpub_la_SOURCES += gdsa.c
-TESTS += gdsa.$t
+TESTS += gdsa.t$(EXEEXT)
EXTRA_DIST += t/gdsa
## KISA `KCDSA', generalized to arbitrary cyclic groups.
pkginclude_HEADERS += gkcdsa.h
libpub_la_SOURCES += gkcdsa.c
-TESTS += gkcdsa.$t
+TESTS += gkcdsa.t$(EXEEXT)
EXTRA_DIST += t/gkcdsa
## General key validity checking machinery.
libpub_la_SOURCES += pkcs1.c
libpub_la_SOURCES += pss.c
EXTRA_DIST += rsa-test.c
-TESTS += rsa-test.$t
+TESTS += rsa-test.t$(EXEEXT)
EXTRA_DIST += t/rsa
###----- That's all, folks --------------------------------------------------
"bbs",
GRAND_CRYPTO, 0,
gmisc, gdestroy,
- gword, gbyte, gword, grand_range, grand_fill
+ gword, gbyte, gword, grand_defaultrange, grand_defaultfill
};
/* --- @bbs_rand@ --- *
## A simple linear-congruential generator.
pkginclude_HEADERS += lcrand.h
librand_la_SOURCES += lcrand.c
-TESTS += lcrand.$t
+TESTS += lcrand.t$(EXEEXT)
EXTRA_DIST += t/lcrand
## Maurer's universal statistical test.
## The SSL v3 pseudorandom function.
pkginclude_HEADERS += sslprf.h
librand_la_SOURCES += sslprf.c
-TESTS += sslprf.$t
+TESTS += sslprf.t$(EXEEXT)
EXTRA_DIST += t/sslprf
## The TLS v1 pseudorandom function.
pkginclude_HEADERS += tlsprf.h
librand_la_SOURCES += tlsprf.c
-TESTS += tlsprf.$t
+TESTS += tlsprf.t$(EXEEXT)
EXTRA_DIST += t/tlsprf
###----- That's all, folks --------------------------------------------------
"dsarand",
0, 0,
gmisc, gdestroy,
- grand_word, grand_byte, grand_word, grand_range, gfill
+ grand_defaultword, grand_defaultbyte, grand_defaultword,
+ grand_defaultrange, gfill
};
/* --- @dsarand_create@ --- *
#include "grand.h"
+/*----- Default operations ------------------------------------------------*/
+
+/* --- @grand_defaultbyte@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ *
+ * Returns: A uniformly-distributed pseudorandom integer in the interval
+ * %$[0, 256)$%.
+ *
+ * Use: Default @byte@ output method. This calls the @range@ method
+ * to return a uniform random value between 0 and 255.
+ */
+
+octet grand_defaultbyte(grand *r)
+ { return (r->ops->range(r, 256)); }
+
+/* --- @grand_defaultword@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ *
+ * Returns: A uniformly-distributed pseudorandom integer in the interval
+ * %$[0, 2^{32})$%.
+ *
+ * Use: Default @word@ output method. This calls the @fill@ method
+ * to fill a 4-octet buffer with uniform random bytes, and then
+ * converts them to an integer.
+ */
+
+uint32 grand_defaultword(grand *r)
+ { octet buf[4]; r->ops->fill(r, buf, sizeof(buf)); return (LOAD32(buf)); }
+
+/* --- @grand_defaultrange@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ * @uint32 l@ = limit for acceptable results
+ *
+ * Returns: A uniformly-distributed pseudorandom integer in the interval
+ * %$[0, l)$%.
+ *
+ * Use: Default @range@ output method. This falls back to either
+ * @word@ (if the generator's @max@ is zero, or if @max < l@) or
+ * @raw@ (otherwise). This might recurse via @fill@ and @byte@,
+ * but this is safe because of the constraint on the @raw@
+ * method.
+ */
+
+uint32 grand_defaultrange(grand *r, uint32 l)
+{
+ uint32 m, z;
+ uint32 (*w)(grand */*r*/);
+ uint32 x;
+
+ /* --- Decide where to get data from --- *
+ *
+ * The choice of %$2^{32} - 1$% as a limit when using @grand_word@ isn't
+ * wonderful, but working with %$2^{32}$% is awkward and the loss of a few
+ * return values isn't significant. The algorithm below still successfully
+ * returns uniformly distributed results.
+ *
+ * If there's a raw generator, and it can cope with the limit, then use it;
+ * otherwise use the @word@ generator, which may recurse via @fill@ and
+ * @byte@, but by that point it must be able to satisfy us.
+ */
+
+ if (r->ops->max && r->ops->max >= l) {
+ w = r->ops->raw;
+ m = r->ops->max;
+ } else {
+ assert(!r->ops->max || r->ops->max >= 256);
+ w = grand_word;
+ m = 0xffffffff;
+ }
+
+ /* --- Work out maximum acceptable return value --- *
+ *
+ * This will be the highest multiple of @l@ less than @m@.
+ */
+
+ z = m - m%l;
+
+ /* --- Generate numbers until something acceptable is found --- *
+ *
+ * This will require an expected number of attempts less than 2.
+ */
+
+ do x = w(r); while (x >= z);
+ return (x%l);
+}
+
+/* --- @grand_defaultfill@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ * @void *p@ = pointer to a buffer
+ * @size_t sz@ = size of the buffer
+ *
+ * Returns: ---
+ *
+ * Use: Fills a buffer with uniformly distributed pseudorandom bytes.
+ * This calls the @byte@ method repeatedly to fill in the output
+ * buffer.
+ */
+
+void grand_defaultfill(grand *r, void *p, size_t sz)
+ { octet *q = p; while (sz--) *q++ = r->ops->byte(r); }
+
/*----- Main code ---------------------------------------------------------*/
/* --- @grand_byte@ --- *
octet grand_byte(grand *r)
{
- if (r->ops->byte != grand_byte)
- return (r->ops->byte(r));
- else if (r->ops->word != grand_word)
- return (r->ops->word(r) & 0xff);
- else if (r->ops->fill != grand_fill) {
- octet o;
- r->ops->fill(r, &o, 1);
- return (o);
- } else
- return (grand_range(r, 256));
+ if (r->ops->byte == grand_byte) return (grand_defaultbyte(r));
+ else return (r->ops->byte(r));
}
/* --- @grand_word@ --- *
uint32 grand_word(grand *r)
{
- if (r->ops->word != grand_word)
- return (r->ops->word(r));
- else {
- octet b[4];
- grand_fill(r, b, sizeof(b));
- return (LOAD32(b));
- }
+ if (r->ops->word == grand_word) return (grand_defaultword(r));
+ else return (r->ops->word(r));
}
/* --- @grand_range@ --- *
uint32 grand_range(grand *r, uint32 l)
{
- if (r->ops->range != grand_range)
- return (r->ops->range(r, l));
- else {
- uint32 m, z;
- uint32 (*w)(grand */*r*/);
- uint32 x;
-
- /* --- Decide where to get data from --- *
- *
- * The choice of %$2^{32} - 1$% as a limit when using @grand_word@ isn't
- * wonderful, but working with %$2^{32}$% is awkward and the loss of a
- * few return values isn't significant. The algorithm below still
- * successfully returns uniformly distributed results.
- */
-
- if (r->ops->max) {
- w = r->ops->raw;
- m = r->ops->max;
- } else {
- w = grand_word;
- m = 0xffffffff;
- }
-
- /* --- Work out maximum acceptable return value --- *
- *
- * This will be the highest multiple of @l@ less than @m@.
- */
-
- z = m - (m % l);
-
- /* --- Generate numbers until something acceptable is found --- *
- *
- * This will require an expected number of attempts less than 2.
- */
-
- do x = w(r); while (x >= z);
- return (x % l);
- }
+ if (r->ops->range == grand_range) return (grand_defaultrange(r, l));
+ else return (r->ops->range(r, l));
}
/* --- @grand_fill@ --- *
void grand_fill(grand *r, void *p, size_t sz)
{
- if (r->ops->fill != grand_fill)
- r->ops->fill(r, p, sz);
- else {
- octet *q = p;
- while (sz) {
- *q++ = r->ops->byte(r);
- sz--;
- }
- }
+ if (r->ops->fill == grand_fill) grand_defaultfill(r, p, sz);
+ else r->ops->fill(r, p, sz);
}
/*----- That's all, folks -------------------------------------------------*/
const char *name; /* Generator's name */
unsigned f; /* Various flags */
- uint32 max; /* Maximum raw output */
+ uint32 max; /* Maximum raw output, if nonzero;
+ * must be either zero or at least
+ * 256
+ */
/* --- Maintenance methods --- */
/* --- Output methods --- *
*
- * Only one of these operations need actually be implemented. All the
- * other operations may be synthesized. Of course, performance is improved
- * if more are provided.
+ * Of these, only @raw@ need be implemented directly by the generator: the
+ * others can point to provided @grand_default...@ functions, which will
+ * synthesize the necessary behaviour. Of course, this comes at an
+ * efficiency penalty.
*/
uint32 (*raw)(grand */*r*/); /* Uniform over %$[0, max)$% */
#define GRAND_BADOP assert(((void)"bad grand_misc op", 0))
+/*----- Default operations ------------------------------------------------*/
+
+/* --- @grand_defaultbyte@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ *
+ * Returns: A uniformly-distributed pseudorandom integer in the interval
+ * %$[0, 256)$%.
+ *
+ * Use: Default @byte@ output method. This calls the @range@ method
+ * to return a uniform random value between 0 and 255.
+ */
+
+extern octet grand_defaultbyte(grand */*r*/);
+
+/* --- @grand_defaultword@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ *
+ * Returns: A uniformly-distributed pseudorandom integer in the interval
+ * %$[0, 2^{32})$%.
+ *
+ * Use: Default @word@ output method. This calls the @fill@ method
+ * to fill a 4-octet buffer with uniform random bytes, and then
+ * converts them to an integer.
+ */
+
+extern uint32 grand_defaultword(grand */*r*/);
+
+/* --- @grand_defaultrange@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ * @uint32 l@ = limit for acceptable results
+ *
+ * Returns: A uniformly-distributed pseudorandom integer in the interval
+ * %$[0, l)$%.
+ *
+ * Use: Default @range@ output method. This falls back to either
+ * @word@ (if the generator's @max@ is zero, or if @max < l@) or
+ * @raw@ (otherwise). This might recurse via @fill@ and @byte@,
+ * but this is safe because of the constraint on the @raw@
+ * method.
+ */
+
+extern uint32 grand_defaultrange(grand */*r*/, uint32 /*l*/);
+
+/* --- @grand_defaultfill@ --- *
+ *
+ * Arguments: @grand *r@ = pointet to generic generator
+ * @void *p@ = pointer to a buffer
+ * @size_t sz@ = size of the buffer
+ *
+ * Returns: ---
+ *
+ * Use: Fills a buffer with uniformly distributed pseudorandom bytes.
+ * This calls the @byte@ method repeatedly to fill in the output
+ * buffer.
+ */
+
+extern void grand_defaultfill(grand */*r*/, void */*p*/, size_t /*sz*/);
+
/*----- Functions provided ------------------------------------------------*/
/* --- @grand_byte@ --- *
"lcrand",
LCRAND_P, 0,
gmisc, gdestroy,
- graw, gbyte, grand_word, grange, grand_fill
+ graw, gbyte, grand_defaultword, grange, grand_defaultfill
};
/* --- @lcrand_create@ --- *
#ifdef USE_FREEWHEEL
-static jmp_buf fwjmp;
+static sigjmp_buf fwjmp;
static void fwalarm(int sig)
{
"rand",
GRAND_CRYPTO, 0,
gmisc, gdestroy,
- gword, gbyte, gword, grand_range, gfill
+ gword, gbyte, gword, grand_defaultrange, gfill
};
/* --- @rand_create@ --- *
"<sslprf-dummy>",
GRAND_CRYPTO, 0,
grmisc, grdestroy,
- grword, grbyte, grword, grand_range, grfill
+ grword, grbyte, grword, grand_defaultrange, grfill
};
/* ---@sslprf_rand@ --- *
"<tlsdx-dummy>",
GRAND_CRYPTO, 0,
dx_grmisc, dx_grdestroy,
- dx_grword, dx_grbyte, dx_grword, grand_range, dx_grfill
+ dx_grword, dx_grbyte, dx_grword, grand_defaultrange, dx_grfill
};
/* ---@tlsdx_rand@ --- *
"<tlsprf-dummy>",
GRAND_CRYPTO, 0,
prf_grmisc, prf_grdestroy,
- prf_grword, prf_grbyte, prf_grword, grand_range, prf_grfill
+ prf_grword, prf_grbyte, prf_grword, grand_defaultrange, prf_grfill
};
/* ---@tlsprf_rand@ --- *
## Schneier's `Blowfish' block cipher.
BLKCS += blowfish
-libsymm_la_SOURCES += $(precomp)/blowfish-tab.c
-PRECOMPS += $(precomp)/blowfish-tab.c
+nodist_libsymm_la_SOURCES += ../precomp/symm/blowfish-tab.c
+PRECOMPS += $(precomp)/symm/blowfish-tab.c
PRECOMP_PROGS += blowfish-mktab
blowfish_mktab_CPPFLAGS = $(AM_CPPFLAGS) -DQUIET
if !CROSS_COMPILING
-$(precomp)/blowfish-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) blowfish-mktab$e
- $(AM_V_GEN)./blowfish-mktab >$(precomp)/blowfish-tab.c.new && \
- mv $(precomp)/blowfish-tab.c.new $(precomp)/blowfish-tab.c
+$(precomp)/symm/blowfish-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) blowfish-mktab$(EXEEXT)
+ $(AM_V_GEN)./blowfish-mktab >$(precomp)/symm/blowfish-tab.c.new && \
+ mv $(precomp)/symm/blowfish-tab.c.new \
+ $(precomp)/symm/blowfish-tab.c
endif
## Adams and Tavares' `CAST' block ciphers.
BLKCS += cast128 cast256
libsymm_la_SOURCES += cast-s.c cast-sk.c cast-base.h
-cast256.$t: t/cast256
+cast256.t$(EXEEXT): t/cast256
EXTRA_DIST += t/cast256.aes
MAINTAINERCLEANFILES += $(srcdir)/t/cast256
t/cast256: t/cast256.aes
## IBM's `DES' block cipher, by Feistel, Coppersmith, and others.
BLKCS += des des3
-libsymm_la_SOURCES += des-base.h $(precomp)/des-tab.c
-PRECOMPS += $(precomp)/des-tab.c
+libsymm_la_SOURCES += des-base.h
+nodist_libsymm_la_SOURCES += ../precomp/symm/des-tab.c
+PRECOMPS += $(precomp)/symm/des-tab.c
PRECOMP_PROGS += des-mktab
if !CROSS_COMPILING
-$(precomp)/des-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) des-mktab$e
- $(AM_V_GEN)./des-mktab >$(precomp)/des-tab.c.new && \
- mv $(precomp)/des-tab.c.new $(precomp)/des-tab.c
+$(precomp)/symm/des-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) des-mktab$(EXEEXT)
+ $(AM_V_GEN)./des-mktab >$(precomp)/symm/des-tab.c.new && \
+ mv $(precomp)/symm/des-tab.c.new $(precomp)/symm/des-tab.c
endif
## Rivest's `DESX' variant, with pre- and post-whitening.
## IBM's `MARS' block cipher.
BLKCS += mars
-libsymm_la_SOURCES += $(precomp)/mars-tab.c
-PRECOMPS += $(precomp)/mars-tab.c
+nodist_libsymm_la_SOURCES += ../precomp/symm/mars-tab.c
+PRECOMPS += $(precomp)/symm/mars-tab.c
PRECOMP_PROGS += mars-mktab
if !CROSS_COMPILING
-$(precomp)/mars-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) mars-mktab$e
- $(AM_V_GEN)./mars-mktab >$(precomp)/mars-tab.c.new && \
- mv $(precomp)/mars-tab.c.new $(precomp)/mars-tab.c
+$(precomp)/symm/mars-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) mars-mktab$(EXEEXT)
+ $(AM_V_GEN)./mars-mktab >$(precomp)/symm/mars-tab.c.new && \
+ mv $(precomp)/symm/mars-tab.c.new $(precomp)/symm/mars-tab.c
endif
-mars.$t: t/mars
+mars.t$(EXEEXT): t/mars
EXTRA_DIST += t/mars.aes
MAINTAINERCLEANFILES += $(srcdir)/t/mars
t/mars: t/mars.aes
if CPUFAM_AMD64
libsymm_la_SOURCES += rijndael-x86ish-aesni.S
endif
-libsymm_la_SOURCES += $(precomp)/rijndael-tab.c
-PRECOMPS += $(precomp)/rijndael-tab.c
+nodist_libsymm_la_SOURCES += ../precomp/symm/rijndael-tab.c
+PRECOMPS += $(precomp)/symm/rijndael-tab.c
PRECOMP_PROGS += rijndael-mktab
if !CROSS_COMPILING
-$(precomp)/rijndael-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) rijndael-mktab$e
- $(AM_V_GEN)./rijndael-mktab >$(precomp)/rijndael-tab.c.new && \
- mv $(precomp)/rijndael-tab.c.new $(precomp)/rijndael-tab.c
+$(precomp)/symm/rijndael-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) rijndael-mktab$(EXEEXT)
+ $(AM_V_GEN)./rijndael-mktab >$(precomp)/symm/rijndael-tab.c.new && \
+ mv $(precomp)/symm/rijndael-tab.c.new \
+ $(precomp)/symm/rijndael-tab.c
endif
-rijndael.$t: t/rijndael
+rijndael.t$(EXEEXT): t/rijndael
EXTRA_DIST += t/rijndael.aes
MAINTAINERCLEANFILES += $(srcdir)/t/rijndael
t/rijndael: t/rijndael.aes
## Massey's `SAFER' block ciphers.
BLKCS += safer safersk
-libsymm_la_SOURCES += $(precomp)/safer-tab.c
-PRECOMPS += $(precomp)/safer-tab.c
+nodist_libsymm_la_SOURCES += ../precomp/symm/safer-tab.c
+PRECOMPS += $(precomp)/symm/safer-tab.c
PRECOMP_PROGS += safer-mktab
STUBS_HDR += SAFER-SK,safersk,safer
if !CROSS_COMPILING
-$(precomp)/safer-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) safer-mktab$e
- $(AM_V_GEN)./safer-mktab >$(precomp)/safer-tab.c.new && \
- mv $(precomp)/safer-tab.c.new $(precomp)/safer-tab.c
+$(precomp)/symm/safer-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) safer-mktab$(EXEEXT)
+ $(AM_V_GEN)./safer-mktab >$(precomp)/symm/safer-tab.c.new && \
+ mv $(precomp)/symm/safer-tab.c.new \
+ $(precomp)/symm/safer-tab.c
endif
## Anderson, Biham and Knudsen's `Serpent' block cipher.
libsymm_la_SOURCES += serpent-sbox.h
check_PROGRAMS += serpent-check
TESTS += serpent-check
-serpent.$t: t/serpent
+serpent.t$(EXEEXT): t/serpent
EXTRA_DIST += t/serpent.aes
MAINTAINERCLEANFILES += $(srcdir)/t/serpent
t/serpent: t/serpent.aes
## Daemen and Rijmen's `Square' block cipher.
BLKCS += square
-libsymm_la_SOURCES += $(precomp)/square-tab.c
-PRECOMPS += $(precomp)/square-tab.c
+nodist_libsymm_la_SOURCES += ../precomp/symm/square-tab.c
+PRECOMPS += $(precomp)/symm/square-tab.c
PRECOMP_PROGS += square-mktab
if !CROSS_COMPILING
-$(precomp)/square-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) square-mktab$e
- $(AM_V_GEN)./square-mktab >$(precomp)/square-tab.c.new && \
- mv $(precomp)/square-tab.c.new $(precomp)/square-tab.c
+$(precomp)/symm/square-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) square-mktab$(EXEEXT)
+ $(AM_V_GEN)./square-mktab >$(precomp)/symm/square-tab.c.new && \
+ mv $(precomp)/symm/square-tab.c.new \
+ $(precomp)/symm/square-tab.c
endif
## Wheeler and Needham's `TEA' and `XTEA' block ciphers.
## Schneier, Kelsey, Whiting, Wagner, Hall and Ferguson's `Twofish' block
## cipher.
BLKCS += twofish
-libsymm_la_SOURCES += $(precomp)/twofish-tab.c
-PRECOMPS += $(precomp)/twofish-tab.c
+nodist_libsymm_la_SOURCES += ../precomp/symm/twofish-tab.c
+PRECOMPS += $(precomp)/symm/twofish-tab.c
PRECOMP_PROGS += twofish-mktab
if !CROSS_COMPILING
-$(precomp)/twofish-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) twofish-mktab$e
- $(AM_V_GEN)./twofish-mktab >$(precomp)/twofish-tab.c.new && \
- mv $(precomp)/twofish-tab.c.new $(precomp)/twofish-tab.c
+$(precomp)/symm/twofish-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) twofish-mktab$(EXEEXT)
+ $(AM_V_GEN)./twofish-mktab >$(precomp)/symm/twofish-tab.c.new && \
+ mv $(precomp)/symm/twofish-tab.c.new \
+ $(precomp)/symm/twofish-tab.c
endif
-twofish.$t: t/twofish
+twofish.t$(EXEEXT): t/twofish
EXTRA_DIST += t/twofish.aes
MAINTAINERCLEANFILES += $(srcdir)/t/twofish
t/twofish: t/twofish.aes
## Anderson and Biham's `Tiger' hash function.
HASHES += tiger
-libsymm_la_SOURCES += tiger-base.h $(precomp)/tiger-tab.c
-PRECOMPS += $(precomp)/tiger-tab.c
+libsymm_la_SOURCES += tiger-base.h
+nodist_libsymm_la_SOURCES += ../precomp/symm/tiger-tab.c
+PRECOMPS += $(precomp)/symm/tiger-tab.c
PRECOMP_PROGS += tiger-mktab
if !CROSS_COMPILING
-$(precomp)/tiger-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) tiger-mktab$e
- $(AM_V_GEN)./tiger-mktab >$(precomp)/tiger-tab.c.new && \
- mv $(precomp)/tiger-tab.c.new $(precomp)/tiger-tab.c
+$(precomp)/symm/tiger-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) tiger-mktab$(EXEEXT)
+ $(AM_V_GEN)./tiger-mktab >$(precomp)/symm/tiger-tab.c.new && \
+ mv $(precomp)/symm/tiger-tab.c.new \
+ $(precomp)/symm/tiger-tab.c
endif
## Barreto and Rijmen's `Whirlpool' hash function.
HASHES += whirlpool whirlpool256
-libsymm_la_SOURCES += $(precomp)/whirlpool-tab.c
-PRECOMPS += $(precomp)/whirlpool-tab.c
+nodist_libsymm_la_SOURCES += ../precomp/symm/whirlpool-tab.c
+PRECOMPS += $(precomp)/symm/whirlpool-tab.c
PRECOMP_PROGS += whirlpool-mktab
STUBS_HDR += Whirlpool-256,whirlpool256,whirlpool
if !CROSS_COMPILING
-$(precomp)/whirlpool-tab.c:
- $(AM_V_at)$(MKDIR_P) $(precomp)
- $(AM_V_at)$(MAKE) whirlpool-mktab$e
- $(AM_V_GEN)./whirlpool-mktab >$(precomp)/whirlpool-tab.c.new && \
- mv $(precomp)/whirlpool-tab.c.new $(precomp)/whirlpool-tab.c
+$(precomp)/symm/whirlpool-tab.c:
+ $(AM_V_at)$(MKDIR_P) $(precomp)/symm
+ $(AM_V_at)$(MAKE) whirlpool-mktab$(EXEEXT)
+ $(AM_V_GEN)./whirlpool-mktab \
+ >$(precomp)/symm/whirlpool-tab.c.new && \
+ mv $(precomp)/symm/whirlpool-tab.c.new \
+ $(precomp)/symm/whirlpool-tab.c
endif
## Bellare, Canetti and Krawczyk's `HMAC' mode for message authentication.
## Rivest's `RC4' stream cipher.
pkginclude_HEADERS += rc4.h
libsymm_la_SOURCES += rc4.c
-TESTS += rc4.$t
+TESTS += rc4.t$(EXEEXT)
EXTRA_DIST += t/rc4
ALL_CIPHERS += rc4
## Coppersmith and Rogaway's `SEAL' pseudorandom function.
pkginclude_HEADERS += seal.h
libsymm_la_SOURCES += seal.c
-TESTS += seal.$t
+TESTS += seal.t$(EXEEXT)
EXTRA_DIST += t/seal
ALL_CIPHERS += seal
if CPUFAM_AMD64
libsymm_la_SOURCES += salsa20-x86ish-sse2.S
endif
-TESTS += salsa20.$t
+TESTS += salsa20.t$(EXEEXT)
ALL_CIPHERS += salsa20 salsa2012 salsa208
ALL_CIPHERS += xsalsa20 xsalsa2012 xsalsa208
STUBS_HDR += Salsa20/12,salsa2012,salsa20
STUBS_HDR += XSalsa20/8,xsalsa208,salsa20
EXTRA_DIST += t/salsa20
MAINTAINERCLEANFILES += t/salsa20
-salsa20.$t: t/salsa20
+salsa20.t$(EXEEXT): t/salsa20
SALSA20_ESTREAM_TV = t/salsa20.estream
SALSA20_ESTREAM_TV += t/salsa2012.estream
SALSA20_ESTREAM_TV += t/salsa208.estream
if CPUFAM_AMD64
libsymm_la_SOURCES += chacha-x86ish-sse2.S
endif
-TESTS += chacha.$t
+TESTS += chacha.t$(EXEEXT)
EXTRA_DIST += t/chacha
ALL_CIPHERS += chacha20 chacha12 chacha8
ALL_CIPHERS += xchacha20 xchacha12 xchacha8
EXTRA_DIST += daftstory.h
## Clean the debris from the `modes' subdirectory.
-CLEANFILES += modes/*.to modes/*.$t
+CLEANFILES += modes/*.to modes/*.t$(EXEEXT)
###----- That's all, folks --------------------------------------------------
static octet ct[sizeof(text)]; \
static octet pt[sizeof(text)]; \
\
-static void hexdump(const octet *p, size_t sz) \
+static void hexdump(const octet *p, size_t sz, size_t off) \
{ \
const octet *q = p + sz; \
for (sz = 0; p < q; p++, sz++) { \
printf("%02x", *p); \
- if ((sz + 1) % PRE##_BLKSZ == 0) \
+ if ((off + sz + 1) % PRE##_BLKSZ == 0) \
putchar(':'); \
} \
} \
} else { \
printf("\nError (sz = %lu)\n", (unsigned long)sz); \
status = 1; \
- printf("\tplaintext = "); hexdump(text, sz); \
- printf(", "); hexdump(text + sz, rest); \
+ printf("\tplaintext = "); hexdump(text, sz, 0); \
+ printf(", "); hexdump(text + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\tciphertext = "); hexdump(ct, sz); \
- printf(", "); hexdump(ct + sz, rest); \
+ printf("\tciphertext = "); hexdump(ct, sz, 0); \
+ printf(", "); hexdump(ct + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\trecovered text = "); hexdump(pt, sz); \
- printf(", "); hexdump(pt + sz, rest); \
+ printf("\trecovered text = "); hexdump(pt, sz, 0); \
+ printf(", "); hexdump(pt + sz, rest, sz); \
fputc('\n', stdout); \
fputc('\n', stdout); \
} \
static octet ct[sizeof(text)]; \
static octet pt[sizeof(text)]; \
\
-static void hexdump(const octet *p, size_t sz) \
+static void hexdump(const octet *p, size_t sz, size_t off) \
{ \
const octet *q = p + sz; \
for (sz = 0; p < q; p++, sz++) { \
printf("%02x", *p); \
- if ((sz + 1) % PRE##_BLKSZ == 0) \
+ if ((off + sz + 1) % PRE##_BLKSZ == 0) \
putchar(':'); \
} \
} \
} else { \
printf("\nError (sz = %lu)\n", (unsigned long)sz); \
status = 1; \
- printf("\tplaintext = "); hexdump(text, sz); \
- printf(", "); hexdump(text + sz, rest); \
+ printf("\tplaintext = "); hexdump(text, sz, 0); \
+ printf(", "); hexdump(text + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\tciphertext = "); hexdump(ct, sz); \
- printf(", "); hexdump(ct + sz, rest); \
+ printf("\tciphertext = "); hexdump(ct, sz, 0); \
+ printf(", "); hexdump(ct + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\trecovered text = "); hexdump(pt, sz); \
- printf(", "); hexdump(pt + sz, rest); \
+ printf("\trecovered text = "); hexdump(pt, sz, 0); \
+ printf(", "); hexdump(pt + sz, rest, sz); \
fputc('\n', stdout); \
fputc('\n', stdout); \
} \
static const grand_ops grops_rand_##rr = { \
"chacha" #rr, GRAND_CRYPTO, 0, \
grmisc, grdestroy, grword, \
- grbyte, grword, grand_range, grfill \
+ grbyte, grword, grand_defaultrange, grfill \
}; \
\
grand *chacha##rr##_rand(const void *k, size_t ksz, const void *n) \
static const grand_ops grxops_rand_##rr = { \
"xchacha" #rr, GRAND_CRYPTO, 0, \
grmisc, grxdestroy_##rr, grword, \
- grbyte, grword, grand_range, grfill \
+ grbyte, grword, grand_defaultrange, grfill \
}; \
\
grand *xchacha##rr##_rand(const void *k, size_t ksz, const void *n) \
#pre "-counter", \
GRAND_CRYPTO, 0, \
grmisc, grdestroy, \
- grword, grbyte, grword, grand_range, grfill \
+ grword, grbyte, grword, grand_defaultrange, grfill \
}; \
\
/* --- @pre_counterrand@ --- * \
static octet ct[sizeof(text)]; \
static octet pt[sizeof(text)]; \
\
-static void hexdump(const octet *p, size_t sz) \
+static void hexdump(const octet *p, size_t sz, size_t off) \
{ \
const octet *q = p + sz; \
for (sz = 0; p < q; p++, sz++) { \
printf("%02x", *p); \
- if ((sz + 1) % PRE##_BLKSZ == 0) \
+ if ((off + sz + 1) % PRE##_BLKSZ == 0) \
putchar(':'); \
} \
} \
} else { \
printf("\nError (sz = %lu)\n", (unsigned long)sz); \
status = 1; \
- printf("\tplaintext = "); hexdump(text, sz); \
- printf(", "); hexdump(text + sz, rest); \
+ printf("\tplaintext = "); hexdump(text, sz, 0); \
+ printf(", "); hexdump(text + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\tciphertext = "); hexdump(ct, sz); \
- printf(", "); hexdump(ct + sz, rest); \
+ printf("\tciphertext = "); hexdump(ct, sz, 0); \
+ printf(", "); hexdump(ct + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\trecovered text = "); hexdump(pt, sz); \
- printf(", "); hexdump(pt + sz, rest); \
+ printf("\trecovered text = "); hexdump(pt, sz, 0); \
+ printf(", "); hexdump(pt + sz, rest, sz); \
fputc('\n', stdout); \
fputc('\n', stdout); \
} \
static octet ct[sizeof(text)]; \
static octet pt[sizeof(text)]; \
\
-static void hexdump(const octet *p, size_t sz) \
+static void hexdump(const octet *p, size_t sz, size_t off) \
{ \
const octet *q = p + sz; \
for (sz = 0; p < q; p++, sz++) { \
printf("%02x", *p); \
- if ((sz + 1) % PRE##_BLKSZ == 0) \
+ if ((off + sz + 1) % PRE##_BLKSZ == 0) \
putchar(':'); \
} \
} \
} else { \
printf("\nError (sz = %lu)\n", (unsigned long)sz); \
status = 1; \
- printf("\tplaintext = "); hexdump(text, sz); \
- printf(", "); hexdump(text + sz, rest); \
+ printf("\tplaintext = "); hexdump(text, sz, 0); \
+ printf(", "); hexdump(text + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\tciphertext = "); hexdump(ct, sz); \
- printf(", "); hexdump(ct + sz, rest); \
+ printf("\tciphertext = "); hexdump(ct, sz, 0); \
+ printf(", "); hexdump(ct + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\trecovered text = "); hexdump(pt, sz); \
- printf(", "); hexdump(pt + sz, rest); \
+ printf("\trecovered text = "); hexdump(pt, sz, 0); \
+ printf(", "); hexdump(pt + sz, rest, sz); \
fputc('\n', stdout); \
fputc('\n', stdout); \
} \
#pre "-mgf", \
GRAND_CRYPTO, 0, \
grmisc, grdestroy, \
- grword, grbyte, grword, grand_range, grfill \
+ grword, grbyte, grword, grand_defaultrange, grfill \
}; \
\
/* --- @pre_mgfrand@ --- * \
%repeat
GENMODES_C += modes/@blkc-@blkcmode.c
GENMODES_H += modes/@blkc-@blkcmode.h
-SYMM_TESTS += @blkc-@blkcmode.$t
+SYMM_TESTS += modes/@blkc-@blkcmode.t$(EXEEXT)
%end
## Hash function modes.
%repeat
GENMODES_C += modes/@hash-@hashmode.c
GENMODES_H += modes/@hash-@hashmode.h
-SYMM_TESTS += @hash-@hashmode.$t
+SYMM_TESTS += modes/@hash-@hashmode.t$(EXEEXT)
%end
## Interface and implementation headers for the various modes.
%repeat
BLKC_C += @blkc.c
BLKC_H += @blkc.h
-SYMM_TESTS += @blkc.$t
+SYMM_TESTS += @blkc.t$(EXEEXT)
%end
## Hash function interfaces and implementations.
%repeat
HASH_C += @hash.c
HASH_H += @hash.h
-SYMM_TESTS += @hash.$t
+SYMM_TESTS += @hash.t$(EXEEXT)
%end
## Modes for symmetric encryption.
#pre "-ofb", \
GRAND_CRYPTO, 0, \
grmisc, grdestroy, \
- grword, grbyte, grword, grand_range, grfill \
+ grword, grbyte, grword, grand_defaultrange, grfill \
}; \
\
/* --- @pre_ofbrand@ --- * \
static octet ct[sizeof(text)]; \
static octet pt[sizeof(text)]; \
\
-static void hexdump(const octet *p, size_t sz) \
+static void hexdump(const octet *p, size_t sz, size_t off) \
{ \
const octet *q = p + sz; \
for (sz = 0; p < q; p++, sz++) { \
printf("%02x", *p); \
- if ((sz + 1) % PRE##_BLKSZ == 0) \
+ if ((off + sz + 1) % PRE##_BLKSZ == 0) \
putchar(':'); \
} \
} \
} else { \
printf("\nError (sz = %lu)\n", (unsigned long)sz); \
status = 1; \
- printf("\tplaintext = "); hexdump(text, sz); \
- printf(", "); hexdump(text + sz, rest); \
+ printf("\tplaintext = "); hexdump(text, sz, 0); \
+ printf(", "); hexdump(text + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\tciphertext = "); hexdump(ct, sz); \
- printf(", "); hexdump(ct + sz, rest); \
+ printf("\tciphertext = "); hexdump(ct, sz, 0); \
+ printf(", "); hexdump(ct + sz, rest, sz); \
fputc('\n', stdout); \
- printf("\trecovered text = "); hexdump(pt, sz); \
- printf(", "); hexdump(pt + sz, rest); \
+ printf("\trecovered text = "); hexdump(pt, sz, 0); \
+ printf(", "); hexdump(pt + sz, rest, sz); \
fputc('\n', stdout); \
fputc('\n', stdout); \
} \
"rc4",
GRAND_CRYPTO, 0,
grmisc, grdestroy,
- grword, grbyte, grword, grand_range, grfill
+ grword, grbyte, grword, grand_defaultrange, grfill
};
/* --- @rc4_rand@ --- *
static const grand_ops grops_rand_##rr = { \
SALSA20_NAME_##rr, GRAND_CRYPTO, 0, \
grmisc, grdestroy, grword, \
- grbyte, grword, grand_range, grfill \
+ grbyte, grword, grand_defaultrange, grfill \
}; \
\
grand *SALSA20_DECOR(salsa20, rr, _rand) \
static const grand_ops grxops_rand_##rr = { \
"x" SALSA20_NAME_##rr, GRAND_CRYPTO, 0, \
grmisc, grxdestroy_##rr, grword, \
- grbyte, grword, grand_range, grfill \
+ grbyte, grword, grand_defaultrange, grfill \
}; \
\
grand *SALSA20_DECOR(xsalsa20, rr, _rand) \
"seal",
GRAND_CRYPTO, 0,
grmisc, grdestroy,
- grword, grbyte, grword, grand_range, grfill
+ grword, grbyte, grword, grand_defaultrange, grfill
};
/* --- @seal_rand@ --- *
###--------------------------------------------------------------------------
### Miscellaneous useful definitions.
-## Some convenient abbreviations for file suffixes.
-e = $(EXEEXT)
-o = $(OBJEXT)
-t = t$e
-
## Installation directories.
archincludedir = $(pkglibdir)/include
CATACOMB_INCLUDES = \
-I$(top_srcdir) \
- -I$(precomp) \
+ -I$(precomp)/math \
+ -I$(precomp)/misc \
+ -I$(precomp)/symm \
-I$(top_srcdir)/base \
-I$(top_srcdir)/key \
-I$(top_srcdir)/math \
###--------------------------------------------------------------------------
### Testing.
-SUFFIXES += .c .$t .to
+SUFFIXES += .c .t$(EXEEXT) .to
.c.to:
$(AM_V_CC)$(COMPILE) -c -DTEST_RIG -DSRCDIR=\"$(srcdir)\" $< -o $@
-.to.$t:
+.to.t$(EXEEXT):
$(AM_V_CCLD)$(LINK) $< $(TEST_LIBS) $(top_builddir)/libcatacomb.la \
$(mLib_LIBS) $(CATACOMB_LIBS) $(LIBS)
.PRECIOUS: %.to
-CLEANFILES += *.to *.$t
+CLEANFILES += *.to *.t$(EXEEXT)
###----- That's all, folks --------------------------------------------------