+++ /dev/null
-/*
- * qfarith.h: utilities for quick field arithmetic
- */
-/*
- * This file is Free Software. It has been modified to as part of its
- * incorporation into secnet.
- *
- * Copyright 2017 Mark Wooding
- *
- * You may redistribute this file and/or modify it under the terms of
- * the permissive licence shown below.
- *
- * You may redistribute secnet as a whole and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3, or (at your option) any
- * later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see
- * https://www.gnu.org/licenses/gpl.html.
- */
-/*
- * Imported from Catacomb, and modified for Secnet (2017-04-30):
- *
- * * Use `fake-mLib-bits.h' in place of the real <mLib/bits.h>.
- *
- * * Use C99 signed integer types instead of our own local probing.
- *
- * * Remove the support for non-two's-complement targets.
- *
- * The file's original comment headers are preserved below.
- */
-/* -*-c-*-
- *
- * Utilities for quick field arithmetic
- *
- * (c) 2017 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.
- */
-
-#ifndef CATACOMB_QFARITH_H
-#define CATACOMB_QFARITH_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*----- Header files ------------------------------------------------------*/
-
-#include <limits.h>
-#include <stdint.h>
-
-#include "fake-mLib-bits.h"
-
-/*----- Signed integer types ----------------------------------------------*/
-
-typedef int_fast32_t int32;
-typedef int_fast64_t int64;
-#define HAVE_INT64 1
-
-/*----- General bit-hacking utilities -------------------------------------*/
-
-/* Individual bits, and masks for low bits. */
-#define BIT(n) (1ul << (n))
-#define MASK(n) (BIT(n) - 1)
-
-/* Arithmetic right shift. If X is a value of type TY, and N is a
- * nonnegative integer, then return the value of X shifted right by N bits;
- * alternatively, this is floor(X/2^N).
- *
- * GCC manages to compile this into a simple shift operation if one is
- * available, but it's correct for all C targets.
- */
-#define ASR(ty, x, n) (((x) - (ty)((u##ty)(x)&MASK(n)))/(ty)BIT(n))
-
-/*----- Constant-time utilities -------------------------------------------*/
-
-/* The following have better implementations on a two's complement target. */
-#ifdef NEG_TWOC
-
- /* If we have two's complement arithmetic then masks are signed; this
- * avoids a switch to unsigned representation, with the consequent problem
- * of overflow when we convert back.
- */
- typedef int32 mask32;
-
- /* Convert an unsigned mask M into a `mask32'. This is a hairy-looking
- * no-op on many targets, but, given that we have two's complement
- * integers, it is free of arithmetic overflow.
- */
-# define FIX_MASK32(m) \
- ((mask32)((m)&0x7fffffffu) + (-(mask32)0x7fffffff - 1)*(((m) >> 31)&1u))
-
- /* If Z is zero and M has its low 32 bits set, then copy (at least) the low
- * 32 bits of X to Z; if M is zero, do nothing. Otherwise, scramble Z
- * unhelpfully.
- */
-# define CONDPICK(z, x, m) do { (z) |= (x)&(m); } while (0)
-
- /* If M has its low 32 bits set, then return (at least) the low 32 bits of
- * X in Z; if M is zero, then return (at least) the low 32 bits of Y in Z.
- * Otherwise, return an unhelful result.
- */
-# define PICK2(x, y, m) (((x)&(m)) | ((y)&~(m)))
-
- /* If M has its low 32 bits set then swap (at least) the low 32 bits of X
- * and Y; if M is zero, then do nothing. Otherwise, scramble X and Y
- * unhelpfully.
- */
-# define CONDSWAP(x, y, m) \
- do { mask32 t_ = ((x) ^ (y))&(m); (x) ^= t_; (y) ^= t_; } while (0)
-#else
-# error "Targets without two's complement arithmetic aren't supported"
-#endif
-
-/* Return zero if bit 31 of X is clear, or a mask with (at least) the low 32
- * bits set if bit 31 of X is set.
- */
-#define SIGN(x) (-(mask32)(((uint32)(x) >> 31)&1))
-
-/* Return zero if X is zero, or a mask with (at least) the low 32 bits set if
- * X is nonzero.
- */
-#define NONZEROP(x) SIGN((U32(x) >> 1) - U32(x))
-
-/*----- Debugging utilities -----------------------------------------------*/
-
-/* Define a debugging function DUMPFN, which will dump an integer represented
- * modulo M. The integer is represented as a vector of NPIECE pieces of type
- * PIECETY. The pieces are assembled at possibly irregular offsets: piece i
- * logically has width PIECEWD(i), but may overhang the next piece. The
- * pieces may be signed. GETMOD is an expression which calculates and
- * returns the value of M, as an `mp *'.
- *
- * The generated function writes the value of such an integer X to the stream
- * FP, labelled with the string WHAT.
- *
- * The definition assumes that <stdio.h>, <catacomb/mp.h>, and
- * <catacomb/mptext.h> have been included.
- */
-#define DEF_FDUMP(dumpfn, piecety, piecewd, npiece, noctet, getmod) \
- static void dumpfn(FILE *fp, const char *what, const piecety *x) \
- { \
- mpw w; \
- mp m, *y = MP_ZERO, *t = MP_NEW, *p; \
- octet b[noctet]; \
- unsigned i, o; \
- \
- p = getmod; \
- mp_build(&m, &w, &w + 1); \
- for (i = o = 0; i < npiece; i++) { \
- if (x[i] >= 0) { w = x[i]; m.f &= ~MP_NEG; } \
- else { w = -x[i]; m.f |= MP_NEG; } \
- t = mp_lsl(t, &m, o); \
- y = mp_add(y, y, t); \
- o += piecewd(i); \
- } \
- \
- fprintf(fp, "%s = <", what); \
- for (i = 0; i < npiece; i++) { \
- if (i) fputs(", ", fp); \
- fprintf(fp, "%ld", (long)x[i]); \
- } \
- fputs(">\n\t= ", fp); \
- mp_writefile(y, fp, 10); \
- fputs("\n\t== ", fp); \
- mp_div(0, &y, y, p); \
- mp_writefile(y, fp, 10); \
- fputs("\n\t= 0x", fp); \
- mp_writefile(y, fp, 16); \
- fputs(" (mod 2^255 - 19)\n\t= [", fp); \
- mp_storel(y, b, sizeof(b)); \
- for (i = 0; i < 32; i++) { \
- if (i && !(i%4)) fputc(':', fp); \
- fprintf(fp, "%02x", b[i]); \
- } \
- fputs("]\n", fp); \
- mp_drop(y); mp_drop(p); mp_drop(t); \
- }
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif