From ae8cd973b817f81c075ab20e84d3239125146f24 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 25 Sep 2019 20:16:24 +0100 Subject: [PATCH] @@@ delete old catcomb import --- f25519.c | 915 -------------------------------------------------------- f25519.h | 329 -------------------- fgoldi.c | 606 ------------------------------------- fgoldi.h | 237 --------------- montladder.h | 173 ----------- qfarith.h | 211 ------------- x25519-tests.in | 655 ---------------------------------------- x25519.c | 222 -------------- x25519.h | 125 -------- x448-tests.in | 669 ----------------------------------------- x448.c | 201 ------------- x448.h | 117 -------- 12 files changed, 4460 deletions(-) delete mode 100644 f25519.c delete mode 100644 f25519.h delete mode 100644 fgoldi.c delete mode 100644 fgoldi.h delete mode 100644 montladder.h delete mode 100644 qfarith.h delete mode 100644 x25519-tests.in delete mode 100644 x25519.c delete mode 100644 x25519.h delete mode 100644 x448-tests.in delete mode 100644 x448.c delete mode 100644 x448.h diff --git a/f25519.c b/f25519.c deleted file mode 100644 index 4e0d1cc..0000000 --- a/f25519.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * f25519.c: arithmetic modulo 2^255 - 19 - */ -/* - * 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 . - * - * * Remove the 16/32-bit implementation, since C99 always has 64-bit - * arithmetic. - * - * * Remove the test rig code: a replacement is in a separate source file. - * - * * Disable some of the operations which aren't needed for X25519. - * (They're used for Ed25519, which we don't need.) - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * Arithmetic modulo 2^255 - 19 - * - * (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. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "f25519.h" - -/*----- Basic setup -------------------------------------------------------*/ - -/* Elements x of GF(2^255 - 19) are represented by ten signed integers x_i: x - * = SUM_{0<=i<10} x_i 2^ceil(51i/2), mostly following Bernstein's original - * paper. - */ - -typedef int32 piece; typedef int64 dblpiece; -typedef uint32 upiece; typedef uint64 udblpiece; -#define P p26 -#define PIECEWD(i) ((i)%2 ? 25 : 26) -#define NPIECE 10 - -#define M26 0x03ffffffu -#define M25 0x01ffffffu -#define B26 0x04000000u -#define B25 0x02000000u -#define B24 0x01000000u - -#define PIECES(v) v##0, v##1, v##2, v##3, v##4, v##5, v##6, v##7, v##8, v##9 -#define FETCH(v, w) do { \ - v##0 = (w)->P[0]; v##1 = (w)->P[1]; \ - v##2 = (w)->P[2]; v##3 = (w)->P[3]; \ - v##4 = (w)->P[4]; v##5 = (w)->P[5]; \ - v##6 = (w)->P[6]; v##7 = (w)->P[7]; \ - v##8 = (w)->P[8]; v##9 = (w)->P[9]; \ -} while (0) -#define STASH(w, v) do { \ - (w)->P[0] = v##0; (w)->P[1] = v##1; \ - (w)->P[2] = v##2; (w)->P[3] = v##3; \ - (w)->P[4] = v##4; (w)->P[5] = v##5; \ - (w)->P[6] = v##6; (w)->P[7] = v##7; \ - (w)->P[8] = v##8; (w)->P[9] = v##9; \ -} while (0) - -/*----- Debugging machinery -----------------------------------------------*/ - -#if defined(F25519_DEBUG) - -#include - -#include "mp.h" -#include "mptext.h" - -static mp *get_2p255m91(void) -{ - mpw w19 = 19; - mp *p = MP_NEW, m19; - - p = mp_setbit(p, MP_ZERO, 255); - mp_build(&m19, &w19, &w19 + 1); - p = mp_sub(p, p, &m19); - return (p); -} - -DEF_FDUMP(fdump, piece, PIECEWD, NPIECE, 32, get_2p255m91()) - -#endif - -/*----- Loading and storing -----------------------------------------------*/ - -/* --- @f25519_load@ --- * - * - * Arguments: @f25519 *z@ = where to store the result - * @const octet xv[32]@ = source to read - * - * Returns: --- - * - * Use: Reads an element of %$\gf{2^{255} - 19}$% in external - * representation from @xv@ and stores it in @z@. - * - * External representation is little-endian base-256. Some - * elements have multiple encodings, which are not produced by - * correct software; use of noncanonical encodings is not an - * error, and toleration of them is considered a performance - * feature. - */ - -void f25519_load(f25519 *z, const octet xv[32]) -{ - uint32 xw0 = LOAD32_L(xv + 0), xw1 = LOAD32_L(xv + 4), - xw2 = LOAD32_L(xv + 8), xw3 = LOAD32_L(xv + 12), - xw4 = LOAD32_L(xv + 16), xw5 = LOAD32_L(xv + 20), - xw6 = LOAD32_L(xv + 24), xw7 = LOAD32_L(xv + 28); - piece PIECES(x), b, c; - - /* First, split the 32-bit words into the irregularly-sized pieces we need - * for the field representation. These pieces are all positive. We'll do - * the sign correction afterwards. - * - * It may be that the top bit of the input is set. Avoid trouble by - * folding that back round into the bottom piece of the representation. - * - * Here, we briefly have 0 <= x_0 < 2^26 + 19, but will resolve this later. - * Otherwise, we have 0 <= x_{2i} < 2^26, and 0 <= x_{2i+1} < 2^25. - */ - x0 = ((xw0 << 0)&0x03ffffff) + 19*((xw7 >> 31)&0x00000001); - x1 = ((xw1 << 6)&0x01ffffc0) | ((xw0 >> 26)&0x0000003f); - x2 = ((xw2 << 13)&0x03ffe000) | ((xw1 >> 19)&0x00001fff); - x3 = ((xw3 << 19)&0x01f80000) | ((xw2 >> 13)&0x0007ffff); - x4 = ((xw3 >> 6)&0x03ffffff); - x5 = (xw4 << 0)&0x01ffffff; - x6 = ((xw5 << 7)&0x03ffff80) | ((xw4 >> 25)&0x0000007f); - x7 = ((xw6 << 13)&0x01ffe000) | ((xw5 >> 19)&0x00001fff); - x8 = ((xw7 << 20)&0x03f00000) | ((xw6 >> 12)&0x000fffff); - x9 = ((xw7 >> 6)&0x01ffffff); - - /* Next, we convert these pieces into a roughly balanced signed - * representation. For each piece, check to see if its top bit is set. If - * it is, then lend a bit to the next piece over. For x_9, this needs to - * be carried around, which is a little fiddly. In particular, we delay - * the carry until after all of the pieces have been balanced. If we don't - * do this, then we have to do a more expensive test for nonzeroness to - * decide whether to lend a bit leftwards rather than just testing a single - * bit. - * - * This fixes up the anomalous size of x_0: the loan of a bit becomes an - * actual carry if x_0 >= 2^26. By the end, then, we have: - * - * { 2^25 if i even - * |x_i| <= { - * { 2^24 if i odd - * - * Note that we don't try for a canonical representation here: both upper - * and lower bounds are achievable. - * - * All of the x_i at this point are positive, so we don't need to do - * anything wierd when masking them. - */ - b = x9&B24; c = 19&((b >> 19) - (b >> 24)); x9 -= b << 1; - b = x8&B25; x9 += b >> 25; x8 -= b << 1; - b = x7&B24; x8 += b >> 24; x7 -= b << 1; - b = x6&B25; x7 += b >> 25; x6 -= b << 1; - b = x5&B24; x6 += b >> 24; x5 -= b << 1; - b = x4&B25; x5 += b >> 25; x4 -= b << 1; - b = x3&B24; x4 += b >> 24; x3 -= b << 1; - b = x2&B25; x3 += b >> 25; x2 -= b << 1; - b = x1&B24; x2 += b >> 24; x1 -= b << 1; - b = x0&B25; x1 += (b >> 25) + (x0 >> 26); x0 = (x0&M26) - (b << 1); - x0 += c; - - /* And with that, we're done. */ - STASH(z, x); -} - -/* --- @f25519_store@ --- * - * - * Arguments: @octet zv[32]@ = where to write the result - * @const f25519 *x@ = the field element to write - * - * Returns: --- - * - * Use: Stores a field element in the given octet vector in external - * representation. A canonical encoding is always stored, so, - * in particular, the top bit of @xv[31]@ is always left clear. - */ - -void f25519_store(octet zv[32], const f25519 *x) -{ - piece PIECES(x), PIECES(y), c, d; - uint32 zw0, zw1, zw2, zw3, zw4, zw5, zw6, zw7; - mask32 m; - - FETCH(x, x); - - /* First, propagate the carries throughout the pieces. By the end of this, - * we'll have all of the pieces canonically sized and positive, and maybe - * there'll be (signed) carry out. The carry c is in { -1, 0, +1 }, and - * the remaining value will be in the half-open interval [0, 2^255). The - * whole represented value is then x + 2^255 c. - * - * It's worth paying careful attention to the bounds. We assume that we - * start out with |x_i| <= 2^30. We start by cutting off and reducing the - * carry c_9 from the topmost piece, x_9. This leaves 0 <= x_9 < 2^25; and - * we'll have |c_9| <= 2^5. We multiply this by 19 and we'll add it onto - * x_0 and propagate the carries: but what bounds can we calculate on x - * before this? - * - * Let o_i = floor(51 i/2). We have X_i = SUM_{0<=j= 2^255 - 19, then we should subtract 2^255 - 19 from the whole - * value; if c = -1 then we should add 2^255 - 19; and otherwise we should - * do nothing. - * - * But conditional behaviour is bad, m'kay. So here's what we do instead. - * - * The first job is to sort out what we wanted to do. If c = -1 then we - * want to (a) invert the constant addend and (b) feed in a carry-in; - * otherwise, we don't. - */ - m = SIGN(c); - d = m&1; - - /* Now do the addition/subtraction. Remember that all of the x_i are - * nonnegative, so shifting and masking are safe and easy. - */ - d += x0 + (19 ^ (M26&m)); y0 = d&M26; d >>= 26; - d += x1 + (M25&m); y1 = d&M25; d >>= 25; - d += x2 + (M26&m); y2 = d&M26; d >>= 26; - d += x3 + (M25&m); y3 = d&M25; d >>= 25; - d += x4 + (M26&m); y4 = d&M26; d >>= 26; - d += x5 + (M25&m); y5 = d&M25; d >>= 25; - d += x6 + (M26&m); y6 = d&M26; d >>= 26; - d += x7 + (M25&m); y7 = d&M25; d >>= 25; - d += x8 + (M26&m); y8 = d&M26; d >>= 26; - d += x9 + (M25&m); y9 = d&M25; d >>= 25; - - /* The final carry-out is in d; since we only did addition, and the x_i are - * nonnegative, then d is in { 0, 1 }. We want to keep y, rather than x, - * if (a) c /= 0 (in which case we know that the old value was - * unsatisfactory), or (b) if d = 1 (in which case, if c = 0, we know that - * the subtraction didn't cause a borrow, so we must be in the case where - * 2^255 - 19 <= x < 2^255). - */ - m = NONZEROP(c) | ~NONZEROP(d - 1); - x0 = (y0&m) | (x0&~m); x1 = (y1&m) | (x1&~m); - x2 = (y2&m) | (x2&~m); x3 = (y3&m) | (x3&~m); - x4 = (y4&m) | (x4&~m); x5 = (y5&m) | (x5&~m); - x6 = (y6&m) | (x6&~m); x7 = (y7&m) | (x7&~m); - x8 = (y8&m) | (x8&~m); x9 = (y9&m) | (x9&~m); - - /* Extract 32-bit words from the value. */ - zw0 = ((x0 >> 0)&0x03ffffff) | (((uint32)x1 << 26)&0xfc000000); - zw1 = ((x1 >> 6)&0x0007ffff) | (((uint32)x2 << 19)&0xfff80000); - zw2 = ((x2 >> 13)&0x00001fff) | (((uint32)x3 << 13)&0xffffe000); - zw3 = ((x3 >> 19)&0x0000003f) | (((uint32)x4 << 6)&0xffffffc0); - zw4 = ((x5 >> 0)&0x01ffffff) | (((uint32)x6 << 25)&0xfe000000); - zw5 = ((x6 >> 7)&0x0007ffff) | (((uint32)x7 << 19)&0xfff80000); - zw6 = ((x7 >> 13)&0x00000fff) | (((uint32)x8 << 12)&0xfffff000); - zw7 = ((x8 >> 20)&0x0000003f) | (((uint32)x9 << 6)&0x7fffffc0); - - /* Store the result as an octet string. */ - STORE32_L(zv + 0, zw0); STORE32_L(zv + 4, zw1); - STORE32_L(zv + 8, zw2); STORE32_L(zv + 12, zw3); - STORE32_L(zv + 16, zw4); STORE32_L(zv + 20, zw5); - STORE32_L(zv + 24, zw6); STORE32_L(zv + 28, zw7); -} - -/* --- @f25519_set@ --- * - * - * Arguments: @f25519 *z@ = where to write the result - * @int a@ = a small-ish constant - * - * Returns: --- - * - * Use: Sets @z@ to equal @a@. - */ - -void f25519_set(f25519 *x, int a) -{ - unsigned i; - - x->P[0] = a; - for (i = 1; i < NPIECE; i++) x->P[i] = 0; -} - -/*----- Basic arithmetic --------------------------------------------------*/ - -/* --- @f25519_add@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the sum %$x + y$%. - */ - -void f25519_add(f25519 *z, const f25519 *x, const f25519 *y) -{ - z->P[0] = x->P[0] + y->P[0]; z->P[1] = x->P[1] + y->P[1]; - z->P[2] = x->P[2] + y->P[2]; z->P[3] = x->P[3] + y->P[3]; - z->P[4] = x->P[4] + y->P[4]; z->P[5] = x->P[5] + y->P[5]; - z->P[6] = x->P[6] + y->P[6]; z->P[7] = x->P[7] + y->P[7]; - z->P[8] = x->P[8] + y->P[8]; z->P[9] = x->P[9] + y->P[9]; -} - -/* --- @f25519_sub@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the difference %$x - y$%. - */ - -void f25519_sub(f25519 *z, const f25519 *x, const f25519 *y) -{ - z->P[0] = x->P[0] - y->P[0]; z->P[1] = x->P[1] - y->P[1]; - z->P[2] = x->P[2] - y->P[2]; z->P[3] = x->P[3] - y->P[3]; - z->P[4] = x->P[4] - y->P[4]; z->P[5] = x->P[5] - y->P[5]; - z->P[6] = x->P[6] - y->P[6]; z->P[7] = x->P[7] - y->P[7]; - z->P[8] = x->P[8] - y->P[8]; z->P[9] = x->P[9] - y->P[9]; -} - -#ifndef F25519_TRIM_X25519 - -/* --- @f25519_neg@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * - * Returns: --- - * - * Use: Set @z = -x@. - */ - -void f25519_neg(f25519 *z, const f25519 *x) -{ - z->P[0] = -x->P[0]; z->P[1] = -x->P[1]; - z->P[2] = -x->P[2]; z->P[3] = -x->P[3]; - z->P[4] = -x->P[4]; z->P[5] = -x->P[5]; - z->P[6] = -x->P[6]; z->P[7] = -x->P[7]; - z->P[8] = -x->P[8]; z->P[9] = -x->P[9]; -} - -#endif - -/*----- Constant-time utilities -------------------------------------------*/ - -#ifndef F25519_TRIM_X25519 - -/* --- @f25519_pick2@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, set @z = y@; if @m@ is all-bits-set, then set - * @z = x@. If @m@ has some other value, then scramble @z@ in - * an unhelpful way. - */ - -void f25519_pick2(f25519 *z, const f25519 *x, const f25519 *y, uint32 m) -{ - mask32 mm = FIX_MASK32(m); - - z->P[0] = PICK2(x->P[0], y->P[0], mm); - z->P[1] = PICK2(x->P[1], y->P[1], mm); - z->P[2] = PICK2(x->P[2], y->P[2], mm); - z->P[3] = PICK2(x->P[3], y->P[3], mm); - z->P[4] = PICK2(x->P[4], y->P[4], mm); - z->P[5] = PICK2(x->P[5], y->P[5], mm); - z->P[6] = PICK2(x->P[6], y->P[6], mm); - z->P[7] = PICK2(x->P[7], y->P[7], mm); - z->P[8] = PICK2(x->P[8], y->P[8], mm); - z->P[9] = PICK2(x->P[9], y->P[9], mm); -} - -/* --- @f25519_pickn@ --- * - * - * Arguments: @f25519 *z@ = where to put the result - * @const f25519 *v@ = a table of entries - * @size_t n@ = the number of entries in @v@ - * @size_t i@ = an index - * - * Returns: --- - * - * Use: If @0 <= i < n < 32@ then set @z = v[i]@. If @n >= 32@ then - * do something unhelpful; otherwise, if @i >= n@ then set @z@ - * to zero. - */ - -void f25519_pickn(f25519 *z, const f25519 *v, size_t n, size_t i) -{ - uint32 b = (uint32)1 << (31 - i); - mask32 m; - - z->P[0] = z->P[1] = z->P[2] = z->P[3] = z->P[4] = - z->P[5] = z->P[6] = z->P[7] = z->P[8] = z->P[9] = 0; - while (n--) { - m = SIGN(b); - CONDPICK(z->P[0], v->P[0], m); - CONDPICK(z->P[1], v->P[1], m); - CONDPICK(z->P[2], v->P[2], m); - CONDPICK(z->P[3], v->P[3], m); - CONDPICK(z->P[4], v->P[4], m); - CONDPICK(z->P[5], v->P[5], m); - CONDPICK(z->P[6], v->P[6], m); - CONDPICK(z->P[7], v->P[7], m); - CONDPICK(z->P[8], v->P[8], m); - CONDPICK(z->P[9], v->P[9], m); - v++; b <<= 1; - } -} - -#endif - -/* --- @f25519_condswap@ --- * - * - * Arguments: @f25519 *x, *y@ = two operands - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, do nothing; if @m@ is all-bits-set, then - * exchange @x@ and @y@. If @m@ has some other value, then - * scramble @x@ and @y@ in an unhelpful way. - */ - -void f25519_condswap(f25519 *x, f25519 *y, uint32 m) -{ - mask32 mm = FIX_MASK32(m); - - CONDSWAP(x->P[0], y->P[0], mm); - CONDSWAP(x->P[1], y->P[1], mm); - CONDSWAP(x->P[2], y->P[2], mm); - CONDSWAP(x->P[3], y->P[3], mm); - CONDSWAP(x->P[4], y->P[4], mm); - CONDSWAP(x->P[5], y->P[5], mm); - CONDSWAP(x->P[6], y->P[6], mm); - CONDSWAP(x->P[7], y->P[7], mm); - CONDSWAP(x->P[8], y->P[8], mm); - CONDSWAP(x->P[9], y->P[9], mm); -} - -#ifndef F25519_TRIM_X25519 - -/* --- @f25519_condneg@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, set @z = x@; if @m@ is all-bits-set, then set - * @z = -x@. If @m@ has some other value then scramble @z@ in - * an unhelpful way. - */ - -void f25519_condneg(f25519 *z, const f25519 *x, uint32 m) -{ - mask32 m_xor = FIX_MASK32(m); - piece m_add = m&1; -# define CONDNEG(x) (((x) ^ m_xor) + m_add) - - z->P[0] = CONDNEG(x->P[0]); - z->P[1] = CONDNEG(x->P[1]); - z->P[2] = CONDNEG(x->P[2]); - z->P[3] = CONDNEG(x->P[3]); - z->P[4] = CONDNEG(x->P[4]); - z->P[5] = CONDNEG(x->P[5]); - z->P[6] = CONDNEG(x->P[6]); - z->P[7] = CONDNEG(x->P[7]); - z->P[8] = CONDNEG(x->P[8]); - z->P[9] = CONDNEG(x->P[9]); - -#undef CONDNEG -} - -#endif - -/*----- Multiplication ----------------------------------------------------*/ - -/* Let B = 2^63 - 1 be the largest value such that +B and -B can be - * represented in a double-precision piece. On entry, it must be the case - * that |X_i| <= M <= B - 2^25 for some M. If this is the case, then, on - * exit, we will have |Z_i| <= 2^25 + 19 M/2^25. - */ -#define CARRYSTEP(z, x, m, b, f, xx, n) do { \ - (z) = (dblpiece)((udblpiece)(x)&(m)) - (b) + \ - (f)*ASR(dblpiece, (xx), (n)); \ -} while (0) -#define CARRY_REDUCE(z, x) do { \ - dblpiece PIECES(_t); \ - \ - /* Bias the input pieces. This keeps the carries and so on centred \ - * around zero rather than biased positive. \ - */ \ - _t0 = (x##0) + B25; _t1 = (x##1) + B24; \ - _t2 = (x##2) + B25; _t3 = (x##3) + B24; \ - _t4 = (x##4) + B25; _t5 = (x##5) + B24; \ - _t6 = (x##6) + B25; _t7 = (x##7) + B24; \ - _t8 = (x##8) + B25; _t9 = (x##9) + B24; \ - \ - /* Calculate the reduced pieces. Careful with the bithacking. */ \ - CARRYSTEP(z##0, _t0, M26, B25, 19, _t9, 25); \ - CARRYSTEP(z##1, _t1, M25, B24, 1, _t0, 26); \ - CARRYSTEP(z##2, _t2, M26, B25, 1, _t1, 25); \ - CARRYSTEP(z##3, _t3, M25, B24, 1, _t2, 26); \ - CARRYSTEP(z##4, _t4, M26, B25, 1, _t3, 25); \ - CARRYSTEP(z##5, _t5, M25, B24, 1, _t4, 26); \ - CARRYSTEP(z##6, _t6, M26, B25, 1, _t5, 25); \ - CARRYSTEP(z##7, _t7, M25, B24, 1, _t6, 26); \ - CARRYSTEP(z##8, _t8, M26, B25, 1, _t7, 25); \ - CARRYSTEP(z##9, _t9, M25, B24, 1, _t8, 26); \ -} while (0) - -/* --- @f25519_mulconst@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * @long a@ = a small-ish constant; %$|a| < 2^{20}$%. - * - * Returns: --- - * - * Use: Set @z@ to the product %$a x$%. - */ - -void f25519_mulconst(f25519 *z, const f25519 *x, long a) -{ - piece PIECES(x); - dblpiece PIECES(z), aa = a; - - FETCH(x, x); - - /* Suppose that |x_i| <= 2^27, and |a| <= 2^23. Then we'll have - * |z_i| <= 2^50. - */ - z0 = aa*x0; z1 = aa*x1; z2 = aa*x2; z3 = aa*x3; z4 = aa*x4; - z5 = aa*x5; z6 = aa*x6; z7 = aa*x7; z8 = aa*x8; z9 = aa*x9; - - /* Following `CARRY_REDUCE', we'll have |z_i| <= 2^26. */ - CARRY_REDUCE(z, z); - STASH(z, z); -} - -/* --- @f25519_mul@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the product %$x y$%. - */ - -void f25519_mul(f25519 *z, const f25519 *x, const f25519 *y) -{ - piece PIECES(x), PIECES(y); - dblpiece PIECES(z); - unsigned i; - - FETCH(x, x); FETCH(y, y); - - /* Suppose that |x_i|, |y_i| <= 2^27. Then we'll have - * - * |z_0| <= 267*2^54 - * |z_1| <= 154*2^54 - * |z_2| <= 213*2^54 - * |z_3| <= 118*2^54 - * |z_4| <= 159*2^54 - * |z_5| <= 82*2^54 - * |z_6| <= 105*2^54 - * |z_7| <= 46*2^54 - * |z_8| <= 51*2^54 - * |z_9| <= 10*2^54 - * - * all of which are less than 2^63 - 2^25. - */ - -#define M(a, b) ((dblpiece)(a)*(b)) - z0 = M(x0, y0) + - 19*(M(x2, y8) + M(x4, y6) + M(x6, y4) + M(x8, y2)) + - 38*(M(x1, y9) + M(x3, y7) + M(x5, y5) + M(x7, y3) + M(x9, y1)); - z1 = M(x0, y1) + M(x1, y0) + - 19*(M(x2, y9) + M(x3, y8) + M(x4, y7) + M(x5, y6) + - M(x6, y5) + M(x7, y4) + M(x8, y3) + M(x9, y2)); - z2 = M(x0, y2) + M(x2, y0) + - 2* M(x1, y1) + - 19*(M(x4, y8) + M(x6, y6) + M(x8, y4)) + - 38*(M(x3, y9) + M(x5, y7) + M(x7, y5) + M(x9, y3)); - z3 = M(x0, y3) + M(x1, y2) + M(x2, y1) + M(x3, y0) + - 19*(M(x4, y9) + M(x5, y8) + M(x6, y7) + - M(x7, y6) + M(x8, y5) + M(x9, y4)); - z4 = M(x0, y4) + M(x2, y2) + M(x4, y0) + - 2*(M(x1, y3) + M(x3, y1)) + - 19*(M(x6, y8) + M(x8, y6)) + - 38*(M(x5, y9) + M(x7, y7) + M(x9, y5)); - z5 = M(x0, y5) + M(x1, y4) + M(x2, y3) + - M(x3, y2) + M(x4, y1) + M(x5, y0) + - 19*(M(x6, y9) + M(x7, y8) + M(x8, y7) + M(x9, y6)); - z6 = M(x0, y6) + M(x2, y4) + M(x4, y2) + M(x6, y0) + - 2*(M(x1, y5) + M(x3, y3) + M(x5, y1)) + - 19* M(x8, y8) + - 38*(M(x7, y9) + M(x9, y7)); - z7 = M(x0, y7) + M(x1, y6) + M(x2, y5) + M(x3, y4) + - M(x4, y3) + M(x5, y2) + M(x6, y1) + M(x7, y0) + - 19*(M(x8, y9) + M(x9, y8)); - z8 = M(x0, y8) + M(x2, y6) + M(x4, y4) + M(x6, y2) + M(x8, y0) + - 2*(M(x1, y7) + M(x3, y5) + M(x5, y3) + M(x7, y1)) + - 38* M(x9, y9); - z9 = M(x0, y9) + M(x1, y8) + M(x2, y7) + M(x3, y6) + M(x4, y5) + - M(x5, y4) + M(x6, y3) + M(x7, y2) + M(x8, y1) + M(x9, y0); -#undef M - - /* From above, we have |z_i| <= 2^63 - 2^25. A pass of `CARRY_REDUCE' will - * leave |z_i| <= 2^38 + 2^25; and a second pass will leave |z_i| <= 2^25 + - * 2^13, which is comfortable for an addition prior to the next - * multiplication. - */ - for (i = 0; i < 2; i++) CARRY_REDUCE(z, z); - STASH(z, z); -} - -/* --- @f25519_sqr@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x@ = an operand - * - * Returns: --- - * - * Use: Set @z@ to the square %$x^2$%. - */ - -void f25519_sqr(f25519 *z, const f25519 *x) -{ - piece PIECES(x); - dblpiece PIECES(z); - unsigned i; - - FETCH(x, x); - - /* See `f25519_mul' for bounds. */ - -#define M(a, b) ((dblpiece)(a)*(b)) - z0 = M(x0, x0) + - 38*(M(x2, x8) + M(x4, x6) + M(x5, x5)) + - 76*(M(x1, x9) + M(x3, x7)); - z1 = 2* M(x0, x1) + - 38*(M(x2, x9) + M(x3, x8) + M(x4, x7) + M(x5, x6)); - z2 = 2*(M(x0, x2) + M(x1, x1)) + - 19* M(x6, x6) + - 38* M(x4, x8) + - 76*(M(x3, x9) + M(x5, x7)); - z3 = 2*(M(x0, x3) + M(x1, x2)) + - 38*(M(x4, x9) + M(x5, x8) + M(x6, x7)); - z4 = M(x2, x2) + - 2* M(x0, x4) + - 4* M(x1, x3) + - 38*(M(x6, x8) + M(x7, x7)) + - 76* M(x5, x9); - z5 = 2*(M(x0, x5) + M(x1, x4) + M(x2, x3)) + - 38*(M(x6, x9) + M(x7, x8)); - z6 = 2*(M(x0, x6) + M(x2, x4) + M(x3, x3)) + - 4* M(x1, x5) + - 19* M(x8, x8) + - 76* M(x7, x9); - z7 = 2*(M(x0, x7) + M(x1, x6) + M(x2, x5) + M(x3, x4)) + - 38* M(x8, x9); - z8 = M(x4, x4) + - 2*(M(x0, x8) + M(x2, x6)) + - 4*(M(x1, x7) + M(x3, x5)) + - 38* M(x9, x9); - z9 = 2*(M(x0, x9) + M(x1, x8) + M(x2, x7) + M(x3, x6) + M(x4, x5)); -#undef M - - /* See `f25519_mul' for details. */ - for (i = 0; i < 2; i++) CARRY_REDUCE(z, z); - STASH(z, z); -} - -/*----- More complicated things -------------------------------------------*/ - -/* --- @f25519_inv@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * - * Returns: --- - * - * Use: Stores in @z@ the multiplicative inverse %$x^{-1}$%. If - * %$x = 0$% then @z@ is set to zero. This is considered a - * feature. - */ - -void f25519_inv(f25519 *z, const f25519 *x) -{ - f25519 t, u, t2, t11, t2p10m1, t2p50m1; - unsigned i; - -#define SQRN(z, x, n) do { \ - f25519_sqr((z), (x)); \ - for (i = 1; i < (n); i++) f25519_sqr((z), (z)); \ -} while (0) - - /* Calculate x^-1 = x^(p - 2) = x^(2^255 - 21), which also handles x = 0 as - * intended. The addition chain here is from Bernstein's implementation; I - * couldn't find a better one. - */ /* step | value */ - f25519_sqr(&t2, x); /* 1 | 2 */ - SQRN(&u, &t2, 2); /* 3 | 8 */ - f25519_mul(&t, &u, x); /* 4 | 9 */ - f25519_mul(&t11, &t, &t2); /* 5 | 11 = 2^5 - 21 */ - f25519_sqr(&u, &t11); /* 6 | 22 */ - f25519_mul(&t, &t, &u); /* 7 | 31 = 2^5 - 1 */ - SQRN(&u, &t, 5); /* 12 | 2^10 - 2^5 */ - f25519_mul(&t2p10m1, &t, &u); /* 13 | 2^10 - 1 */ - SQRN(&u, &t2p10m1, 10); /* 23 | 2^20 - 2^10 */ - f25519_mul(&t, &t2p10m1, &u); /* 24 | 2^20 - 1 */ - SQRN(&u, &t, 20); /* 44 | 2^40 - 2^20 */ - f25519_mul(&t, &t, &u); /* 45 | 2^40 - 1 */ - SQRN(&u, &t, 10); /* 55 | 2^50 - 2^10 */ - f25519_mul(&t2p50m1, &t2p10m1, &u); /* 56 | 2^50 - 1 */ - SQRN(&u, &t2p50m1, 50); /* 106 | 2^100 - 2^50 */ - f25519_mul(&t, &t2p50m1, &u); /* 107 | 2^100 - 1 */ - SQRN(&u, &t, 100); /* 207 | 2^200 - 2^100 */ - f25519_mul(&t, &t, &u); /* 208 | 2^200 - 1 */ - SQRN(&u, &t, 50); /* 258 | 2^250 - 2^50 */ - f25519_mul(&t, &t2p50m1, &u); /* 259 | 2^250 - 1 */ - SQRN(&u, &t, 5); /* 264 | 2^255 - 2^5 */ - f25519_mul(z, &u, &t11); /* 265 | 2^255 - 21 */ - -#undef SQRN -} - -#ifndef F25519_TRIM_X25519 - -/* --- @f25519_quosqrt@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: Zero if successful, @-1@ if %$x/y$% is not a square. - * - * Use: Stores in @z@ the one of the square roots %$\pm\sqrt{x/y}$%. - * If %$x = y = 0% then the result is zero; if %$y = 0$% but %$x - * \ne 0$% then the operation fails. If you wanted a specific - * square root then you'll have to pick it yourself. - */ - -static const piece sqrtm1_pieces[NPIECE] = { -#if F25519_IMPL == 26 - -32595792, -7943725, 9377950, 3500415, 12389472, - -272473, -25146209, -2005654, 326686, 11406482 -#elif F25519_IMPL == 10 - 176, -88, 161, 157, -485, -196, -231, -220, -416, - -169, -255, 50, 189, -89, -266, -32, 202, -511, - 423, 357, 248, -249, 80, 288, 50, 174 -#endif -}; -#define SQRTM1 ((const f25519 *)sqrtm1_pieces) - -int f25519_quosqrt(f25519 *z, const f25519 *x, const f25519 *y) -{ - f25519 t, u, w, beta, xy3, t2p50m1; - octet xb[32], b0[32], b1[32]; - int32 rc = -1; - mask32 m; - unsigned i; - -#define SQRN(z, x, n) do { \ - f25519_sqr((z), (x)); \ - for (i = 1; i < (n); i++) f25519_sqr((z), (z)); \ -} while (0) - - /* This is a bit tricky; the algorithm is from Bernstein, Duif, Lange, - * Schwabe, and Yang, `High-speed high-security signatures', 2011-09-26, - * https://ed25519.cr.yp.to/ed25519-20110926.pdf. - * - * First of all, a complicated exponentation. The addition chain here is - * mine. We start with some preliminary values. - */ /* step | value */ - SQRN(&u, y, 1); /* 1 | 0, 2 */ - f25519_mul(&t, &u, y); /* 2 | 0, 3 */ - f25519_mul(&xy3, &t, x); /* 3 | 1, 3 */ - SQRN(&u, &u, 1); /* 4 | 0, 4 */ - f25519_mul(&w, &u, &xy3); /* 5 | 1, 7 */ - - /* And now we calculate w^((p - 5)/8) = w^(252 - 3). */ - SQRN(&u, &w, 1); /* 6 | 2 */ - f25519_mul(&t, &w, &u); /* 7 | 3 */ - SQRN(&u, &t, 1); /* 8 | 6 */ - f25519_mul(&t, &u, &w); /* 9 | 7 */ - SQRN(&u, &t, 3); /* 12 | 56 */ - f25519_mul(&t, &t, &u); /* 13 | 63 = 2^6 - 1 */ - SQRN(&u, &t, 6); /* 19 | 2^12 - 2^6 */ - f25519_mul(&t, &t, &u); /* 20 | 2^12 - 1 */ - SQRN(&u, &t, 12); /* 32 | 2^24 - 2^12 */ - f25519_mul(&t, &t, &u); /* 33 | 2^24 - 1 */ - SQRN(&u, &t, 1); /* 34 | 2^25 - 2 */ - f25519_mul(&t, &u, &w); /* 35 | 2^25 - 1 */ - SQRN(&u, &t, 25); /* 60 | 2^50 - 2^25 */ - f25519_mul(&t2p50m1, &t, &u); /* 61 | 2^50 - 1 */ - SQRN(&u, &t2p50m1, 50); /* 111 | 2^100 - 2^50 */ - f25519_mul(&t, &t2p50m1, &u); /* 112 | 2^100 - 1 */ - SQRN(&u, &t, 100); /* 212 | 2^200 - 2^100 */ - f25519_mul(&t, &t, &u); /* 213 | 2^200 - 1 */ - SQRN(&u, &t, 50); /* 263 | 2^250 - 2^50 */ - f25519_mul(&t, &t2p50m1, &u); /* 264 | 2^250 - 1 */ - SQRN(&u, &t, 2); /* 266 | 2^252 - 4 */ - f25519_mul(&t, &u, &w); /* 267 | 2^252 - 3 */ - - /* And finally... */ - f25519_mul(&beta, &t, &xy3); /* 268 | ... */ - - /* Now we have beta = (x y^3) (x y^7)^((p - 5)/8) = (x/y)^((p + 3)/8), and - * we're ready to finish the computation. Suppose that alpha^2 = u/w. - * Then beta^4 = (x/y)^((p + 3)/2) = alpha^(p + 3) = alpha^4 = (x/y)^2, so - * we have beta^2 = ±x/y. If y beta^2 = x then beta is the one we wanted; - * if -y beta^2 = x, then we want beta sqrt(-1), which we already know. Of - * course, it might not match either, in which case we fail. - * - * The easiest way to compare is to encode. This isn't as wasteful as it - * sounds: the hard part is normalizing the representations, which we have - * to do anyway. - */ - f25519_sqr(&t, &beta); - f25519_mul(&t, &t, y); - f25519_neg(&u, &t); - f25519_store(xb, x); - f25519_store(b0, &t); - f25519_store(b1, &u); - f25519_mul(&u, &beta, SQRTM1); - - m = -ct_memeq(b0, xb, 32); - rc = PICK2(0, rc, m); - f25519_pick2(z, &beta, &u, m); - m = -ct_memeq(b1, xb, 32); - rc = PICK2(0, rc, m); - - /* And we're done. */ - return (rc); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/f25519.h b/f25519.h deleted file mode 100644 index 8450748..0000000 --- a/f25519.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * f25519.h: arithmetic modulo 2^255 - 19 - */ -/* - * 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 lightly modified for Secnet (2017-04-30): - * - * * Use `fake-mLib-bits.h' in place of the real . - * - * * Remove the 16/32-bit implementation, since C99 always has 64-bit - * arithmetic. - * - * * Disable some of the operations which aren't needed for X25519. - * (They're used for Ed25519, which we don't need.) - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * Arithmetic modulo 2^255 - 19 - * - * (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_F25519_H -#define CATACOMB_F25519_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Header files ------------------------------------------------------*/ - -#include "fake-mLib-bits.h" - -#ifndef CATACOMB_QFARITH_H -# include "qfarith.h" -#endif - -/*----- Data structures ---------------------------------------------------*/ - -typedef union { - int32 p26[10]; -} f25519; - -/*----- Functions provided ------------------------------------------------*/ - -#define F25519_TRIM_X25519 - -/* --- @f25519_set@ --- * - * - * Arguments: @f25519 *z@ = where to write the result - * @int a@ = a small-ish constant - * - * Returns: --- - * - * Use: Sets @z@ to equal @a@. - */ - -extern void f25519_set(f25519 */*x*/, int /*a*/); - -/* --- @f25519_load@ --- * - * - * Arguments: @f25519 *z@ = where to store the result - * @const octet xv[32]@ = source to read - * - * Returns: --- - * - * Use: Reads an element of %$\gf{2^{255} - 19}$% in external - * representation from @xv@ and stores it in @z@. - * - * External representation is little-endian base-256. Elements - * have multiple encodings, which are not produced by correct - * software; use of noncanonical encodings is not an error, and - * toleration of them is considered a performance feature. - * - * Some specifications, e.g., RFC7748, require the topmost bit - * (i.e., bit 7 of @wv[31]@) to be ignored. Callers - * implementing such specifications should clear the bit - * explicitly. (It's much easier for a caller who wants the bit - * to be ignored to clear it than for a caller who wants the bit - * to be significant to apply the necessary change by hand.) - */ - -extern void f25519_load(f25519 */*z*/, const octet /*xv*/[32]); - -/* --- @f25519_store@ --- * - * - * Arguments: @octet zv[32]@ = where to write the result - * @const f25519 *x@ = the field element to write - * - * Returns: --- - * - * Use: Stores a field element in the given octet vector in external - * representation. A canonical encoding is always stored, so, - * in particular, the top bit of @xv[31]@ is always left clear. - */ - -extern void f25519_store(octet /*zv*/[32], const f25519 */*x*/); - -#ifndef F25519_TRIM_X25519 - -/* --- @f25519_pick2@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, set @z = y@; if @m@ is all-bits-set, then set - * @z = x@. If @m@ has some other value, then scramble @z@ in - * an unhelpful way. - */ - -extern void f25519_pick2(f25519 */*z*/, const f25519 */*x*/, - const f25519 */*y*/, uint32 /*m*/); - -/* --- @f25519_pickn@ --- * - * - * Arguments: @f25519 *z@ = where to put the result - * @const f25519 *v@ = a table of entries - * @size_t n@ = the number of entries in @v@ - * @size_t i@ = an index - * - * Returns: --- - * - * Use: If @0 <= i < n < 32@ then set @z = v[i]@. If @n >= 32@ then - * do something unhelpful; otherwise, if @i >= n@ then set @z@ - * to zero. - */ - -extern void f25519_pickn(f25519 */*z*/, const f25519 */*v*/, size_t /*n*/, - size_t /*i*/); - -#endif - -/* --- @f25519_condswap@ --- * - * - * Arguments: @f25519 *x, *y@ = two operands - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, do nothing; if @m@ is all-bits-set, then - * exchange @x@ and @y@. If @m@ has some other value, then - * scramble @x@ and @y@ in an unhelpful way. - */ - -extern void f25519_condswap(f25519 */*x*/, f25519 */*y*/, uint32 /*m*/); - -/* --- @f25519_add@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the sum %$x + y$%. - */ - -extern void f25519_add(f25519 */*z*/, - const f25519 */*x*/, const f25519 */*y*/); - -/* --- @f25519_sub@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the difference %$x - y$%. - */ - -extern void f25519_sub(f25519 */*z*/, - const f25519 */*x*/, const f25519 */*y*/); - -#ifndef F25519_TRIM_X25519 - -/* --- @f25519_neg@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * - * Returns: --- - * - * Use: Set @z = -x@. - */ - -extern void f25519_neg(f25519 */*z*/, const f25519 */*x*/); - -/* --- @f25519_condneg@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, set @z = x@; if @m@ is all-bits-set, then set - * @z = -x@. If @m@ has some other value then scramble @z@ in - * an unhelpful way. - */ - -extern void f25519_condneg(f25519 */*z*/, const f25519 */*x*/, uint32 /*m*/); - -#endif - -/* --- @f25519_mulconst@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * @long a@ = a small-ish constant; %$|a| < 2^{20}$%. - * - * Returns: --- - * - * Use: Set @z@ to the product %$a x$%. - */ - -extern void f25519_mulconst(f25519 */*z*/, const f25519 */*x*/, long /*a*/); - -/* --- @f25519_mul@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the product %$x y$%. - */ - -extern void f25519_mul(f25519 */*z*/, - const f25519 */*x*/, const f25519 */*y*/); - -/* --- @f25519_sqr@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x@ = an operand - * - * Returns: --- - * - * Use: Set @z@ to the square %$x^2$%. - */ - -extern void f25519_sqr(f25519 */*z*/, const f25519 */*x*/); - -/* --- @f25519_inv@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@) - * @const f25519 *x@ = an operand - * - * Returns: --- - * - * Use: Stores in @z@ the multiplicative inverse %$x^{-1}$%. If - * %$x = 0$% then @z@ is set to zero. This is considered a - * feature. - */ - -extern void f25519_inv(f25519 */*z*/, const f25519 */*x*/); - -#ifndef F25519_TRIM_X25519 - -/* --- @f25519_quosqrt@ --- * - * - * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) - * @const f25519 *x, *y@ = two operands - * - * Returns: Zero if successful, @-1@ if %$x/y$% is not a square. - * - * Use: Stores in @z@ the one of the square roots %$\pm\sqrt{x/y}$%. - * If %$x = y = 0% then the result is zero; if %$y = 0$% but %$x - * \ne 0$% then the operation fails. If you wanted a specific - * square root then you'll have to pick it yourself. - */ - -extern int f25519_quosqrt(f25519 */*z*/, - const f25519 */*x*/, const f25519 */*y*/); - -#endif - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/fgoldi.c b/fgoldi.c deleted file mode 100644 index 6a8d35b..0000000 --- a/fgoldi.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * fgoldi.c: arithmetic modulo 2^448 - 2^224 - 1 - */ -/* - * 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 . - * - * * Remove the 16/32-bit implementation, since C99 always has 64-bit - * arithmetic. - * - * * Remove the test rig code: a replacement is in a separate source file. - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * Arithmetic in the Goldilocks field GF(2^448 - 2^224 - 1) - * - * (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. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "fgoldi.h" - -/*----- Basic setup -------------------------------------------------------* - * - * Let φ = 2^224; then p = φ^2 - φ - 1, and, in GF(p), we have φ^2 = φ + 1 - * (hence the name). - */ - -/* We represent an element of GF(p) as 16 28-bit signed integer pieces x_i: - * x = SUM_{0<=i<16} x_i 2^(28i). - */ - -typedef int32 piece; typedef int64 dblpiece; -typedef uint32 upiece; typedef uint64 udblpiece; -#define PIECEWD(i) 28 -#define NPIECE 16 -#define P p28 - -#define B28 0x10000000u -#define B27 0x08000000u -#define M28 0x0fffffffu -#define M27 0x07ffffffu -#define M32 0xffffffffu - -/*----- Debugging machinery -----------------------------------------------*/ - -#if defined(FGOLDI_DEBUG) - -#include - -#include "mp.h" -#include "mptext.h" - -static mp *get_pgoldi(void) -{ - mp *p = MP_NEW, *t = MP_NEW; - - p = mp_setbit(p, MP_ZERO, 448); - t = mp_setbit(t, MP_ZERO, 224); - p = mp_sub(p, p, t); - p = mp_sub(p, p, MP_ONE); - mp_drop(t); - return (p); -} - -DEF_FDUMP(fdump, piece, PIECEWD, NPIECE, 56, get_pgoldi()) - -#endif - -/*----- Loading and storing -----------------------------------------------*/ - -/* --- @fgoldi_load@ --- * - * - * Arguments: @fgoldi *z@ = where to store the result - * @const octet xv[56]@ = source to read - * - * Returns: --- - * - * Use: Reads an element of %$\gf{2^{448} - 2^{224} - 19}$% in - * external representation from @xv@ and stores it in @z@. - * - * External representation is little-endian base-256. Some - * elements have multiple encodings, which are not produced by - * correct software; use of noncanonical encodings is not an - * error, and toleration of them is considered a performance - * feature. - */ - -void fgoldi_load(fgoldi *z, const octet xv[56]) -{ - unsigned i; - uint32 xw[14]; - piece b, c; - - /* First, read the input value as words. */ - for (i = 0; i < 14; i++) xw[i] = LOAD32_L(xv + 4*i); - - /* Extract unsigned 28-bit pieces from the words. */ - z->P[ 0] = (xw[ 0] >> 0)&M28; - z->P[ 7] = (xw[ 6] >> 4)&M28; - z->P[ 8] = (xw[ 7] >> 0)&M28; - z->P[15] = (xw[13] >> 4)&M28; - for (i = 1; i < 7; i++) { - z->P[i + 0] = ((xw[i + 0] << (4*i)) | (xw[i - 1] >> (32 - 4*i)))&M28; - z->P[i + 8] = ((xw[i + 7] << (4*i)) | (xw[i + 6] >> (32 - 4*i)))&M28; - } - - /* Convert the nonnegative pieces into a balanced signed representation, so - * each piece ends up in the interval |z_i| <= 2^27. For each piece, if - * its top bit is set, lend a bit leftwards; in the case of z_15, reduce - * this bit by adding it onto z_0 and z_8, since this is the φ^2 bit, and - * φ^2 = φ + 1. We delay this carry until after all of the pieces have - * been balanced. If we don't do this, then we have to do a more expensive - * test for nonzeroness to decide whether to lend a bit leftwards rather - * than just testing a single bit. - * - * Note that we don't try for a canonical representation here: both upper - * and lower bounds are achievable. - */ - b = z->P[15]&B27; z->P[15] -= b << 1; c = b >> 27; - for (i = NPIECE - 1; i--; ) - { b = z->P[i]&B27; z->P[i] -= b << 1; z->P[i + 1] += b >> 27; } - z->P[0] += c; z->P[8] += c; -} - -/* --- @fgoldi_store@ --- * - * - * Arguments: @octet zv[56]@ = where to write the result - * @const fgoldi *x@ = the field element to write - * - * Returns: --- - * - * Use: Stores a field element in the given octet vector in external - * representation. A canonical encoding is always stored. - */ - -void fgoldi_store(octet zv[56], const fgoldi *x) -{ - piece y[NPIECE], yy[NPIECE], c, d; - uint32 u, v; - mask32 m; - unsigned i; - - for (i = 0; i < NPIECE; i++) y[i] = x->P[i]; - - /* First, propagate the carries. By the end of this, we'll have all of the - * the pieces canonically sized and positive, and maybe there'll be - * (signed) carry out. The carry c is in { -1, 0, +1 }, and the remaining - * value will be in the half-open interval [0, φ^2). The whole represented - * value is then y + φ^2 c. - * - * Assume that we start out with |y_i| <= 2^30. We start off by cutting - * off and reducing the carry c_15 from the topmost piece, y_15. This - * leaves 0 <= y_15 < 2^28; and we'll have |c_15| <= 4. We'll add this - * onto y_0 and y_8, and propagate the carries. It's very clear that we'll - * end up with |y + (φ + 1) c_15 - φ^2/2| << φ^2. - * - * Here, the y_i are signed, so we must be cautious about bithacking them. - */ - c = ASR(piece, y[15], 28); y[15] = (upiece)y[15]&M28; y[8] += c; - for (i = 0; i < NPIECE; i++) - { y[i] += c; c = ASR(piece, y[i], 28); y[i] = (upiece)y[i]&M28; } - - /* Now we have a slightly fiddly job to do. If c = +1, or if c = 0 and - * y >= p, then we should subtract p from the whole value; if c = -1 then - * we should add p; and otherwise we should do nothing. - * - * But conditional behaviour is bad, m'kay. So here's what we do instead. - * - * The first job is to sort out what we wanted to do. If c = -1 then we - * want to (a) invert the constant addend and (b) feed in a carry-in; - * otherwise, we don't. - */ - m = SIGN(c)&M28; - d = m&1; - - /* Now do the addition/subtraction. Remember that all of the y_i are - * nonnegative, so shifting and masking are safe and easy. - */ - d += y[0] + (1 ^ m); yy[0] = d&M28; d >>= 28; - for (i = 1; i < 8; i++) - { d += y[i] + m; yy[i] = d&M28; d >>= 28; } - d += y[8] + (1 ^ m); yy[8] = d&M28; d >>= 28; - for (i = 9; i < 16; i++) - { d += y[i] + m; yy[i] = d&M28; d >>= 28; } - - /* The final carry-out is in d; since we only did addition, and the y_i are - * nonnegative, then d is in { 0, 1 }. We want to keep y', rather than y, - * if (a) c /= 0 (in which case we know that the old value was - * unsatisfactory), or (b) if d = 1 (in which case, if c = 0, we know that - * the subtraction didn't cause a borrow, so we must be in the case where - * p <= y < φ^2. - */ - m = NONZEROP(c) | ~NONZEROP(d - 1); - for (i = 0; i < NPIECE; i++) y[i] = (yy[i]&m) | (y[i]&~m); - - /* Extract 32-bit words from the value. */ - for (i = 0; i < 7; i++) { - u = ((y[i + 0] >> (4*i)) | ((uint32)y[i + 1] << (28 - 4*i)))&M32; - v = ((y[i + 8] >> (4*i)) | ((uint32)y[i + 9] << (28 - 4*i)))&M32; - STORE32_L(zv + 4*i, u); - STORE32_L(zv + 4*i + 28, v); - } -} - -/* --- @fgoldi_set@ --- * - * - * Arguments: @fgoldi *z@ = where to write the result - * @int a@ = a small-ish constant - * - * Returns: --- - * - * Use: Sets @z@ to equal @a@. - */ - -void fgoldi_set(fgoldi *x, int a) -{ - unsigned i; - - x->P[0] = a; - for (i = 1; i < NPIECE; i++) x->P[i] = 0; -} - -/*----- Basic arithmetic --------------------------------------------------*/ - -/* --- @fgoldi_add@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the sum %$x + y$%. - */ - -void fgoldi_add(fgoldi *z, const fgoldi *x, const fgoldi *y) -{ - unsigned i; - for (i = 0; i < NPIECE; i++) z->P[i] = x->P[i] + y->P[i]; -} - -/* --- @fgoldi_sub@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the difference %$x - y$%. - */ - -void fgoldi_sub(fgoldi *z, const fgoldi *x, const fgoldi *y) -{ - unsigned i; - for (i = 0; i < NPIECE; i++) z->P[i] = x->P[i] - y->P[i]; -} - -/*----- Constant-time utilities -------------------------------------------*/ - -/* --- @fgoldi_condswap@ --- * - * - * Arguments: @fgoldi *x, *y@ = two operands - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, do nothing; if @m@ is all-bits-set, then - * exchange @x@ and @y@. If @m@ has some other value, then - * scramble @x@ and @y@ in an unhelpful way. - */ - -void fgoldi_condswap(fgoldi *x, fgoldi *y, uint32 m) -{ - unsigned i; - mask32 mm = FIX_MASK32(m); - - for (i = 0; i < NPIECE; i++) CONDSWAP(x->P[i], y->P[i], mm); -} - -/*----- Multiplication ----------------------------------------------------*/ - -/* Let B = 2^63 - 1 be the largest value such that +B and -B can be - * represented in a double-precision piece. On entry, it must be the case - * that |X_i| <= M <= B - 2^27 for some M. If this is the case, then, on - * exit, we will have |Z_i| <= 2^27 + M/2^27. - */ -#define CARRY_REDUCE(z, x) do { \ - dblpiece _t[NPIECE], _c; \ - unsigned _i; \ - \ - /* Bias the input pieces. This keeps the carries and so on centred \ - * around zero rather than biased positive. \ - */ \ - for (_i = 0; _i < NPIECE; _i++) _t[_i] = (x)[_i] + B27; \ - \ - /* Calculate the reduced pieces. Careful with the bithacking. */ \ - _c = ASR(dblpiece, _t[15], 28); \ - (z)[0] = (dblpiece)((udblpiece)_t[0]&M28) - B27 + _c; \ - for (_i = 1; _i < NPIECE; _i++) { \ - (z)[_i] = (dblpiece)((udblpiece)_t[_i]&M28) - B27 + \ - ASR(dblpiece, _t[_i - 1], 28); \ - } \ - (z)[8] += _c; \ -} while (0) - -/* --- @fgoldi_mulconst@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) - * @const fgoldi *x@ = an operand - * @long a@ = a small-ish constant; %$|a| < 2^{20}$%. - * - * Returns: --- - * - * Use: Set @z@ to the product %$a x$%. - */ - -void fgoldi_mulconst(fgoldi *z, const fgoldi *x, long a) -{ - unsigned i; - dblpiece zz[NPIECE], aa = a; - - for (i = 0; i < NPIECE; i++) zz[i] = aa*x->P[i]; - CARRY_REDUCE(z->P, zz); -} - -/* --- @fgoldi_mul@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the product %$x y$%. - */ - -void fgoldi_mul(fgoldi *z, const fgoldi *x, const fgoldi *y) -{ - dblpiece zz[NPIECE], u[NPIECE]; - piece ab[NPIECE/2], cd[NPIECE/2]; - const piece - *a = x->P + NPIECE/2, *b = x->P, - *c = y->P + NPIECE/2, *d = y->P; - unsigned i, j; - -# define M(x,i, y,j) ((dblpiece)(x)[i]*(y)[j]) - - /* Behold the magic. - * - * Write x = a φ + b, and y = c φ + d. Then x y = a c φ^2 + - * (a d + b c) φ + b d. Karatsuba and Ofman observed that a d + b c = - * (a + b) (c + d) - a c - b d, saving a multiplication, and Hamburg chose - * the prime p so that φ^2 = φ + 1. So - * - * x y = ((a + b) (c + d) - b d) φ + a c + b d - */ - - for (i = 0; i < NPIECE; i++) zz[i] = 0; - - /* Our first job will be to calculate (1 - φ) b d, and write the result - * into z. As we do this, an interesting thing will happen. Write - * b d = u φ + v; then (1 - φ) b d = u φ + v - u φ^2 - v φ = (1 - φ) v - u. - * So, what we do is to write the product end-swapped and negated, and then - * we'll subtract the (negated, remember) high half from the low half. - */ - for (i = 0; i < NPIECE/2; i++) { - for (j = 0; j < NPIECE/2 - i; j++) - zz[i + j + NPIECE/2] -= M(b,i, d,j); - for (; j < NPIECE/2; j++) - zz[i + j - NPIECE/2] -= M(b,i, d,j); - } - for (i = 0; i < NPIECE/2; i++) - zz[i] -= zz[i + NPIECE/2]; - - /* Next, we add on a c. There are no surprises here. */ - for (i = 0; i < NPIECE/2; i++) - for (j = 0; j < NPIECE/2; j++) - zz[i + j] += M(a,i, c,j); - - /* Now, calculate a + b and c + d. */ - for (i = 0; i < NPIECE/2; i++) - { ab[i] = a[i] + b[i]; cd[i] = c[i] + d[i]; } - - /* Finally (for the multiplication) we must add on (a + b) (c + d) φ. - * Write (a + b) (c + d) as u φ + v; then we actually want u φ^2 + v φ = - * v φ + (1 + φ) u. We'll store u in a temporary place and add it on - * twice. - */ - for (i = 0; i < NPIECE; i++) u[i] = 0; - for (i = 0; i < NPIECE/2; i++) { - for (j = 0; j < NPIECE/2 - i; j++) - zz[i + j + NPIECE/2] += M(ab,i, cd,j); - for (; j < NPIECE/2; j++) - u[i + j - NPIECE/2] += M(ab,i, cd,j); - } - for (i = 0; i < NPIECE/2; i++) - { zz[i] += u[i]; zz[i + NPIECE/2] += u[i]; } - -#undef M - - /* That wraps it up for the multiplication. Let's figure out some bounds. - * Fortunately, Karatsuba is a polynomial identity, so all of the pieces - * end up the way they'd be if we'd done the thing the easy way, which - * simplifies the analysis. Suppose we started with |x_i|, |y_i| <= 9/5 - * 2^28. The overheads in the result are given by the coefficients of - * - * ((u^16 - 1)/(u - 1))^2 mod u^16 - u^8 - 1 - * - * the greatest of which is 38. So |z_i| <= 38*81/25*2^56 < 2^63. - * - * Anyway, a round of `CARRY_REDUCE' will leave us with |z_i| < 2^27 + - * 2^36; and a second round will leave us with |z_i| < 2^27 + 512. - */ - for (i = 0; i < 2; i++) CARRY_REDUCE(zz, zz); - for (i = 0; i < NPIECE; i++) z->P[i] = zz[i]; -} - -/* --- @fgoldi_sqr@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x@ = an operand - * - * Returns: --- - * - * Use: Set @z@ to the square %$x^2$%. - */ - -void fgoldi_sqr(fgoldi *z, const fgoldi *x) -{ - dblpiece zz[NPIECE], u[NPIECE]; - piece ab[NPIECE]; - const piece *a = x->P + NPIECE/2, *b = x->P; - unsigned i, j; - -# define M(x,i, y,j) ((dblpiece)(x)[i]*(y)[j]) - - /* The magic is basically the same as `fgoldi_mul' above. We write - * x = a φ + b and use Karatsuba and the special prime shape. This time, - * we have - * - * x^2 = ((a + b)^2 - b^2) φ + a^2 + b^2 - */ - - for (i = 0; i < NPIECE; i++) zz[i] = 0; - - /* Our first job will be to calculate (1 - φ) b^2, and write the result - * into z. Again, this interacts pleasantly with the prime shape. - */ - for (i = 0; i < NPIECE/4; i++) { - zz[2*i + NPIECE/2] -= M(b,i, b,i); - for (j = i + 1; j < NPIECE/2 - i; j++) - zz[i + j + NPIECE/2] -= 2*M(b,i, b,j); - for (; j < NPIECE/2; j++) - zz[i + j - NPIECE/2] -= 2*M(b,i, b,j); - } - for (; i < NPIECE/2; i++) { - zz[2*i - NPIECE/2] -= M(b,i, b,i); - for (j = i + 1; j < NPIECE/2; j++) - zz[i + j - NPIECE/2] -= 2*M(b,i, b,j); - } - for (i = 0; i < NPIECE/2; i++) - zz[i] -= zz[i + NPIECE/2]; - - /* Next, we add on a^2. There are no surprises here. */ - for (i = 0; i < NPIECE/2; i++) { - zz[2*i] += M(a,i, a,i); - for (j = i + 1; j < NPIECE/2; j++) - zz[i + j] += 2*M(a,i, a,j); - } - - /* Now, calculate a + b. */ - for (i = 0; i < NPIECE/2; i++) - ab[i] = a[i] + b[i]; - - /* Finally (for the multiplication) we must add on (a + b)^2 φ. - * Write (a + b)^2 as u φ + v; then we actually want (u + v) φ + u. We'll - * store u in a temporary place and add it on twice. - */ - for (i = 0; i < NPIECE; i++) u[i] = 0; - for (i = 0; i < NPIECE/4; i++) { - zz[2*i + NPIECE/2] += M(ab,i, ab,i); - for (j = i + 1; j < NPIECE/2 - i; j++) - zz[i + j + NPIECE/2] += 2*M(ab,i, ab,j); - for (; j < NPIECE/2; j++) - u[i + j - NPIECE/2] += 2*M(ab,i, ab,j); - } - for (; i < NPIECE/2; i++) { - u[2*i - NPIECE/2] += M(ab,i, ab,i); - for (j = i + 1; j < NPIECE/2; j++) - u[i + j - NPIECE/2] += 2*M(ab,i, ab,j); - } - for (i = 0; i < NPIECE/2; i++) - { zz[i] += u[i]; zz[i + NPIECE/2] += u[i]; } - -#undef M - - /* Finally, carrying. */ - for (i = 0; i < 2; i++) CARRY_REDUCE(zz, zz); - for (i = 0; i < NPIECE; i++) z->P[i] = zz[i]; - -} - -/*----- More advanced operations ------------------------------------------*/ - -/* --- @fgoldi_inv@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) - * @const fgoldi *x@ = an operand - * - * Returns: --- - * - * Use: Stores in @z@ the multiplicative inverse %$x^{-1}$%. If - * %$x = 0$% then @z@ is set to zero. This is considered a - * feature. - */ - -void fgoldi_inv(fgoldi *z, const fgoldi *x) -{ - fgoldi t, u; - unsigned i; - -#define SQRN(z, x, n) do { \ - fgoldi_sqr((z), (x)); \ - for (i = 1; i < (n); i++) fgoldi_sqr((z), (z)); \ -} while (0) - - /* Calculate x^-1 = x^(p - 2) = x^(2^448 - 2^224 - 3), which also handles - * x = 0 as intended. The addition chain is home-made. - */ /* step | value */ - fgoldi_sqr(&u, x); /* 1 | 2 */ - fgoldi_mul(&t, &u, x); /* 2 | 3 */ - SQRN(&u, &t, 2); /* 4 | 12 */ - fgoldi_mul(&t, &u, &t); /* 5 | 15 */ - SQRN(&u, &t, 4); /* 9 | 240 */ - fgoldi_mul(&u, &u, &t); /* 10 | 255 = 2^8 - 1 */ - SQRN(&u, &u, 4); /* 14 | 2^12 - 16 */ - fgoldi_mul(&t, &u, &t); /* 15 | 2^12 - 1 */ - SQRN(&u, &t, 12); /* 27 | 2^24 - 2^12 */ - fgoldi_mul(&u, &u, &t); /* 28 | 2^24 - 1 */ - SQRN(&u, &u, 12); /* 40 | 2^36 - 2^12 */ - fgoldi_mul(&t, &u, &t); /* 41 | 2^36 - 1 */ - fgoldi_sqr(&t, &t); /* 42 | 2^37 - 2 */ - fgoldi_mul(&t, &t, x); /* 43 | 2^37 - 1 */ - SQRN(&u, &t, 37); /* 80 | 2^74 - 2^37 */ - fgoldi_mul(&u, &u, &t); /* 81 | 2^74 - 1 */ - SQRN(&u, &u, 37); /* 118 | 2^111 - 2^37 */ - fgoldi_mul(&t, &u, &t); /* 119 | 2^111 - 1 */ - SQRN(&u, &t, 111); /* 230 | 2^222 - 2^111 */ - fgoldi_mul(&t, &u, &t); /* 231 | 2^222 - 1 */ - fgoldi_sqr(&u, &t); /* 232 | 2^223 - 2 */ - fgoldi_mul(&u, &u, x); /* 233 | 2^223 - 1 */ - SQRN(&u, &u, 223); /* 456 | 2^446 - 2^223 */ - fgoldi_mul(&t, &u, &t); /* 457 | 2^446 - 2^222 - 1 */ - SQRN(&t, &t, 2); /* 459 | 2^448 - 2^224 - 4 */ - fgoldi_mul(z, &t, x); /* 460 | 2^448 - 2^224 - 3 */ - -#undef SQRN -} - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/fgoldi.h b/fgoldi.h deleted file mode 100644 index 1857008..0000000 --- a/fgoldi.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * fgoldi.h: arithmetic modulo 2^448 - 2^224 - 1 - */ -/* - * 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 lightly modified for Secnet (2017-04-30): - * - * * Use `fake-mLib-bits.h' in place of the real . - * - * * Remove the 16/32-bit implementation, since C99 always has 64-bit - * arithmetic. - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * Arithmetic in the Goldilocks field GF(2^448 - 2^224 - 1) - * - * (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_FGOLDI_H -#define CATACOMB_FGOLDI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Header files ------------------------------------------------------*/ - -#include "fake-mLib-bits.h" - -#ifndef CATACOMB_QFARITH_H -# include "qfarith.h" -#endif - -/*----- Data structures ---------------------------------------------------*/ - -typedef union { - int32 p28[16]; -} fgoldi; - -#if !defined(FGOLDI_IMPL) && defined(HAVE_INT64) -# define FGOLDI_IMPL 28 -#endif - -#ifndef FGOLDI_IMPL -# define FGOLDI_IMPL 12 -#endif - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @fgoldi_load@ --- * - * - * Arguments: @fgoldi *z@ = where to store the result - * @const octet xv[56]@ = source to read - * - * Returns: --- - * - * Use: Reads an element of %$\gf{2^{448} - 2^{224} - 19}$% in - * external representation from @xv@ and stores it in @z@. - * - * External representation is little-endian base-256. Some - * elements have multiple encodings, which are not produced by - * correct software; use of noncanonical encodings is not an - * error, and toleration of them is considered a performance - * feature. - */ - -extern void fgoldi_load(fgoldi */*z*/, const octet /*xv*/[56]); - -/* --- @fgoldi_store@ --- * - * - * Arguments: @octet zv[56]@ = where to write the result - * @const fgoldi *x@ = the field element to write - * - * Returns: --- - * - * Use: Stores a field element in the given octet vector in external - * representation. A canonical encoding is always stored. - */ - -extern void fgoldi_store(octet /*zv*/[56], const fgoldi */*x*/); - -/* --- @fgoldi_set@ --- * - * - * Arguments: @fgoldi *z@ = where to write the result - * @int a@ = a small-ish constant - * - * Returns: --- - * - * Use: Sets @z@ to equal @a@. - */ - -extern void fgoldi_set(fgoldi */*x*/, int /*a*/); - -/* --- @fgoldi_add@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the sum %$x + y$%. - */ - -extern void fgoldi_add(fgoldi */*z*/, - const fgoldi */*x*/, const fgoldi */*y*/); - -/* --- @fgoldi_sub@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the difference %$x - y$%. - */ - -extern void fgoldi_sub(fgoldi */*z*/, - const fgoldi */*x*/, const fgoldi */*y*/); - -/* --- @fgoldi_condswap@ --- * - * - * Arguments: @fgoldi *x, *y@ = two operands - * @uint32 m@ = a mask - * - * Returns: --- - * - * Use: If @m@ is zero, do nothing; if @m@ is all-bits-set, then - * exchange @x@ and @y@. If @m@ has some other value, then - * scramble @x@ and @y@ in an unhelpful way. - */ - -extern void fgoldi_condswap(fgoldi */*x*/, fgoldi */*y*/, uint32 /*m*/); - -/* --- @fgoldi_mulconst@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) - * @const fgoldi *x@ = an operand - * @long a@ = a small-ish constant; %$|a| < 2^{20}$%. - * - * Returns: --- - * - * Use: Set @z@ to the product %$a x$%. - */ - -extern void fgoldi_mulconst(fgoldi */*z*/, const fgoldi */*x*/, long /*a*/); - -/* --- @fgoldi_mul@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x, *y@ = two operands - * - * Returns: --- - * - * Use: Set @z@ to the product %$x y$%. - */ - -extern void fgoldi_mul(fgoldi */*z*/, - const fgoldi */*x*/, const fgoldi */*y*/); - -/* --- @fgoldi_sqr@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) - * @const fgoldi *x@ = an operand - * - * Returns: --- - * - * Use: Set @z@ to the square %$x^2$%. - */ - -extern void fgoldi_sqr(fgoldi */*z*/, const fgoldi */*x*/); - -/* --- @fgoldi_inv@ --- * - * - * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) - * @const fgoldi *x@ = an operand - * - * Returns: --- - * - * Use: Stores in @z@ the multiplicative inverse %$x^{-1}$%. If - * %$x = 0$% then @z@ is set to zero. This is considered a - * feature. - */ - -extern void fgoldi_inv(fgoldi */*z*/, const fgoldi */*x*/); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/montladder.h b/montladder.h deleted file mode 100644 index 4292158..0000000 --- a/montladder.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * montladder.h: Montgomery's ladder - */ -/* - * 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 (2017-04-30). The file's original comment headers - * are preserved below. - */ -/* -*-c-*- - * - * Definitions for Montgomery's ladder - * - * (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_MONTLADDER_H -#define CATACOMB_MONTLADDER_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Notes on the Montgomery ladder ------------------------------------* - * - * The algorithm here is Montgomery's famous binary ladder for calculating - * x-coordinates of scalar products on a particular shape of elliptic curve, - * as elucidated by Daniel Bernstein. - * - * Let Q = (x_1, y_1) be the base point, for some unknown y_1 (which will - * turn out to be unimportant). Define x_n, z_n by x(n Q) = (x_n : z_n). - * Given x_n, z_n, x_{n+1}, z_{n+1}, Montgomery's differential addition - * formulae calculate x_{2i}, z_{2i}, x_{2i+1}, z_{2i+1}. Furthermore, - * calculating x_{2i}, z_{2i} requires only x_n, z_n, and the calculation of - * x_{2i+1}, z_{2i+1} is symmetrical. - */ - -/*----- Functions provided ------------------------------------------------*/ - -/* F designates a field, both naming the type of its elements and acting as a - * prefix for the standard field operations `F_add', `F_sub', `F_mul', - * `F_sqr', and `F_inv' (the last of which should return zero its own - * inverse); and the constant-time utility `F_condswap'. - * - * The macro calculates the x-coordinate of the product k Q, where Q is a - * point on the elliptic curve B y^2 = x^3 + A x^2 + x or its quadratic - * twist, for some irrelevant B. The x-coordinate of Q is given as X1 (a - * pointer to a field element). The scalar k is given as a vector of NK - * unsigned integers KW, each containing NBITS significant bits, with the - * least-significant element first. The result is written to the field - * element pointed to by Z. - * - * The curve coefficient A is given indirectly, as the name of a macro MULA0 - * such that - * - * MULA0(z, x) - * - * will store in z the value (A - 2)/4 x. - */ -#define MONT_LADDER(f, mula0, kw, nk, nbits, z, x1) do { \ - f _x, _z, _u, _w; \ - f _t0, _t1, _t2, _t3, _t4; \ - uint32 _m = 0, _mm = 0, _k; \ - unsigned _i, _j; \ - \ - /* Initialize the main variables. We'll have, (x, z) and (u, w) \ - * holding (x_n, z_n) and (x_{n+1}, z_{n+1}) in some order, but \ - * there's some weirdness: if m = 0 then (x, z) = (x_n, z_n) and \ - * (u, v) = (x_{n+1}, z_{n+1}); if m /= 0, then the pairs are \ - * swapped over. \ - * \ - * Initially, we have (x_0, z_0) = (1, 0), representing the identity \ - * at projective-infinity, which works fine; and we have z_1 = 1. \ - */ \ - _u = *(x1); f##_set(&_w, 1); f##_set(&_x, 1); f##_set(&_z, 0); \ - \ - /* The main ladder loop. Work through each bit of the clamped key. */ \ - for (_i = (nk); _i--; ) { \ - _k = (kw)[_i]; \ - for (_j = 0; _j < (nbits); _j++) { \ - /* We're at bit i of the scalar key (represented by 32 (7 - i) + \ - * (31 - j) in our loop variables -- don't worry about that). \ - * Let k = 2^i k_i + k'_i, with 0 <= k'_i < 2^i. In particular, \ - * then, k_0 = k. Write Q(i) = (x_i, z_i). \ - * \ - * We currently have, in (x, z) and (u, w), Q(k_i) and Q(k_i + \ - * 1), in some order. The ladder step will double the point in \ - * (x, z), and leave the sum of (x : z) and (u : w) in (u, w). \ - */ \ - \ - _mm = -((_k >> ((nbits) - 1))&1u); _k <<= 1; \ - f##_condswap(&_x, &_u, _m ^ _mm); \ - f##_condswap(&_z, &_w, _m ^ _mm); \ - _m = _mm; \ - \ - f##_add(&_t0, &_x, &_z); /* x + z */ \ - f##_sub(&_t1, &_x, &_z); /* x - z */ \ - f##_add(&_t2, &_u, &_w); /* u + w */ \ - f##_sub(&_t3, &_u, &_w); /* u - w */ \ - f##_mul(&_t2, &_t2, &_t1); /* (x - z) (u + w) */ \ - f##_mul(&_t3, &_t3, &_t0); /* (x + z) (u - w) */ \ - f##_sqr(&_t0, &_t0); /* (x + z)^2 */ \ - f##_sqr(&_t1, &_t1); /* (x - z)^2 */ \ - f##_mul(&_x, &_t0, &_t1); /* (x + z)^2 (x - z)^2 */ \ - f##_sub(&_t1, &_t0, &_t1); /* (x + z)^2 - (x - z)^2 */ \ - mula0(&_t4, &_t1); /* A_0 ((x + z)^2 - (x - z)^2) */ \ - f##_add(&_t0, &_t0, &_t4); /* A_0 ... + (x + z)^2 */ \ - f##_mul(&_z, &_t0, &_t1); /* (...^2 - ...^2) (A_0 ... + ...) */ \ - f##_add(&_t0, &_t2, &_t3); /* (x - z) (u + w) + (x + z) (u - w) */ \ - f##_sub(&_t1, &_t2, &_t3); /* (x - z) (u + w) - (x + z) (u - w) */ \ - f##_sqr(&_u, &_t0); /* (... + ...)^2 */ \ - f##_sqr(&_t1, &_t1); /* (... - ...)^2 */ \ - f##_mul(&_w, &_t1, (x1)); /* x_1 (... - ...)^2 */ \ - } \ - } \ - \ - /* Almost done. Undo the swap, if any. */ \ - f##_condswap(&_x, &_u, _m); \ - f##_condswap(&_z, &_w, _m); \ - \ - /* And convert to affine. */ \ - f##_inv(&_t0, &_z); \ - f##_mul((z), &_x, &_t0); \ -} while (0) - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/qfarith.h b/qfarith.h deleted file mode 100644 index fcedf3e..0000000 --- a/qfarith.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * 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 . - * - * * 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 -#include - -#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 , , and - * 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 diff --git a/x25519-tests.in b/x25519-tests.in deleted file mode 100644 index 875b0a3..0000000 --- a/x25519-tests.in +++ /dev/null @@ -1,655 +0,0 @@ -### Test cases for arithmetic mod 2^255 - 19. -*-conf-*- - -###-------------------------------------------------------------------------- -test add - -## Some easy things, mostly to test loading and storing. -x 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 -y 0000000000000000000000000000000000000000000000000000000000000000 -z 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 - -x ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f -y 0000000000000000000000000000000000000000000000000000000000000000 -z ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f - -x edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f -y 0000000000000000000000000000000000000000000000000000000000000000 -z 0000000000000000000000000000000000000000000000000000000000000000 - -## Random tests. -x bb8cd45b6185ee8ca34c4d7560425fd5c2fc22871113c6427198e8f9439a8523 -y 98f16cc5e44b7228b7f3b6ed91930d68bba5071157d19259c48034d2817e30d5 -z 667e412146d160b55a400463f2d56c3d7ea22a9868e4589c35191dccc518b678 - -x 8ef938a7b07a668c234c2c5bb65115b8e2e22a3703cda51c70e7a56a075d4f34 -y 1f3cd4bf4f768058c4de1aa5aeb90e227338e308c7a0a199050ca1c38d1e034c -z c0350d6700f1e6e4e72a4700650b24da551b0e40ca6d47b675f3462e957b5200 - -x 8b2c4678fd4f8b7254eea925e4da8d472db7f97d349d1b2134ced884b747ea7d -y 58dca7954f843b7e4dc56b048903e7728df66ef6824f29932b2f568c995ddf2c -z f608ee0d4dd4c6f0a1b3152a6dde74babaad6874b7ec44b45ffd2e1151a5c92a - -x 9cd64f0cf439bccd224f7a789396b9f888998d1ba9759c93a5d6a27f45db0e67 -y 12f724a127052612081e27e3915db9a540de9b64c566edc313914ad94424464e -z c1cd74ad1b3fe2df2a6da15b25f4729ec97729806edc8957b967ed588aff5435 - -x 82e59fa9703b2557303665fe24e3d46259da974d78155f05c6b8891f92fc808d -y 98a073ec62baf1354b681a3c78d62df1698ed5077dbe2bd68ba4a6e0233e3447 -z 2d861396d3f5168d7b9e7f3a9db90254c3686d55f5d38adb515d3000b63ab554 - -x 686ceca221d0f4c6d98287e97c506085064e7b172672b88ee555dd0308bfd309 -y 60adc3675be5e6c2921a74b5b8b24b0a26341a19567dae713a720786bc72df16 -z c819b00a7db5db896c9dfb9e3503ac8f2c8295307cef660020c8e489c431b320 - -x a50a5b82d2451ed9a5844585712202a6dc0e0230501d57b8c00f4bd4771aed9e -y 98d71b8b140aea02ad47d9b19e47d2a03257adc1d5c47611adc667652b78c87c -z 63e2760de74f08dc52cc1e37106ad4460f66aff125e2cdc96dd6b239a392b51b - -x 1637e3eb4c5d173b8cba29bdb13b930f48ae0599e354819f8ae0cf70f0f7b61b -y ffeef1767df70de7a4a75864c03935d7934c6cf5228b9c3000813ed0e55447e2 -z 2826d562ca542522316282217275c8e6dbfa718e06e01dd08a610e41d64cfe7d - -x 9e8bf571c45bc5f37c9126e70498698978903b94d9c6712baef91894ab924fda -y 480f68f8ee644bfb64e3fa514eaf16aea6368da6813802c4c3e6ce8f6540dfa3 -z 0c9b5d6ab3c010efe1742139534780371fc7c83a5bff73ef71e0e72311d32e7e - -x df9bdbd478bd1ec1ff078cdc76f2a5fcdc52f0198ba412e0b5a10e664b175dad -y 080bc47bd2fb2ba3be6a07a02162f76020479f2cc6469c6766df23acf9517896 -z 0da79f504bb94a64be72937c98549d5dfd998f4651ebae471c8132124569d543 - -x b6dd223f5d8a3dc5dd6f7a0679173ff656303017a17f17f4086fd4ecd3a23020 -y 560d827aad23c26fddbfd16c3514a9b518a4586d6e3c5739860743662b14f4b4 -z 1feba4b90aaeff34bb2f4c73ae2be8ab6fd488840fbc6e2d8f761753ffb62455 - -x 1d59691a670c40143ca7f7e693389ab64a911b17a2fe4368fba9097b40864162 -y cb42d3ba12a8b90ef1622ea09241d3157c515043040914356d6d99b95089fa07 -z e89b3cd579b4f9222d0a2687267a6dccc6e26b5aa607589d6817a334910f3c6a - -x 82b48877e9c8c18edb52db3e1417d894e572a8edd84335d93c642158f2a926e0 -y 93c6a39c1ef97f318c3b13bf8e77bea653b2eb130bdf43b00a0e0e40a362e819 -z 287b2c1408c241c0678eeefda28e963b39259401e422798947722f98950c0f7a - -x a6137481c5b9b8bcb3c87f3868c5f812da71aeb21c5ce18a508773120ea4f659 -y 812eacdc5a8eb2e8fde0c23a19c2e33466d754ab3109d28ff48fb41dab8066e2 -z 4d42205e20486ba5b1a942738187dc474049035e4e65b31a45172830b9245d3c - -x 598fb4096a7054e317e66bc9633d56dfcaeabc31a7bbc9da13074b242edeca09 -y 929b1bddd55c99b06b99a3ffbac5adc1d28823cb8354adcfea60b7a87fe32039 -z eb2ad0e63fcded93837f0fc91e0304a19d73e0fc2a1077aafe6702cdadc1eb42 - -x c42183d915267e655409326b1b77a042d8918feefd75dd3d18551f398ef426e7 -y e3729a6110686ffa57d1c69284a60fb36173148a89b1810d04614f03c8f90084 -z cd941d3b268eed5facdaf8fd9f1db0f53905a47887275f4b1cb66e3c56ee276b - -x 67b8b7ea7e7f9f52d686f906589c919b293bff6d3127e7ac581dc1630af7bcc1 -y 99d18d2190ef0da148b843c014fea3efea59f9adbb28fa38407191fcc24e029c -z 268a450c0f6fadf31e3f3dc76c9a358b1495f81bed4fe1e5988e5260cd45bf5d - -x bc3422b79e01234fefd3637a19bfb2dd0a83bf2071b27bf5389918a50e579294 -y b665dffe064aceffaabba94697cf27054d016427ebaf68858c5250cc5c1b770f -z 859a01b6a54bf14e9a8f0dc1b08edae2578423485c62e47ac5eb68716b720924 - -x d419cbfd5514d9cffa1765b9f273fd7492000a3d110586ed0b8137760a2e808e -y bcb52f423917c074464b2078d1c3f883fb793b02411b8b13c08266d17658a499 -z b6cffa3f8f2b994441638531c437f6f88d7a453f52201101cc039e4781862428 - -x 2f7eb8051d16a52b797e2618881bd0857eb205bf97e581e09680f86308f7e082 -y 9ceda63b29c3bfedbb6f3f0be2f3f2bd285bb9d21620c3edde69629b00b1c3cd -z f16b5f4146d9641935ee65236a0fc343a70dbf91ae0545ce75ea5aff08a8a450 - -###-------------------------------------------------------------------------- -test sub - -x dfb53b4ff67c742728c564d50ae20e3e3617804478a95e511d37ff4dcf04fa3f -y 9bc2006bb07dcf7bf0b461e7599e3c3cbfcdf6b6f41fc1db2219767ce9c43bcd -z 1ef33ae445ffa4ab371003eeb043d2017749898d83899d75fa1d89d1e53fbe72 - -x 432ec65076c94af41e054a43f64fe4eecb23f50a303fd38e0172e4e846e67394 -y 3642c84c5f5fcd5a0f3f2e37114beb8e7b614c39d354f1b32fe7e9cc918da5c8 -z faebfd03176a7d990fc61b0ce504f95f50c2a8d15ceae1dad18afa1bb558ce4b - -x 1725a986c03d9d53346ab2064545ba90ab38191e19ded9ecc2f44d422ab04150 -y 11a20caef0239e4ffb5ab2f7d3576633a0d4a08c78a02f35765fafff5398c48b -z f3829cd8cf19ff03390f000f71ed535d0b647891a03daab74c959e42d6177d44 - -x ec5d5cdfc8183f9aa3d47634d16427c3a399e2166bfa4ddfecbc911e5f33ceba -y 649f8e29c483765c4232c369fd0e50a0026eac306eb4bd6924e7b4d7d3f73e26 -z 9bbecdb50495c83d61a2b3cad355d722a12b36e6fc459075c8d5dc468b3b8f14 - -x cc9927c331884612d8fab9a2262ad0db38f55e0cc587e45b972ea8b1f504450d -y 30c5c9f8d5491a350051bbc6bb78e568d98061b43cb1797cd3d7454e8a7aa1bf -z 76d45dca5b3e2cddd7a9fedb6ab1ea725f74fd5788d66adfc35662636b8aa34d - -x 662bc96da214e50f13e07a15b8e0b78f512c744a66975b2170ba28079ca7d03b -y 84b072295dca0abef806ec5c1e594179dc5e9eb172c178af1902a42ea7a3728e -z cf7a5644454ada511ad98eb89987761675cdd598f3d5e27156b884d8f4035e2d - -x ed6f947157492eccc5fb1d0542593d58a47e2d87355dc0378e65376163fcf457 -y cb27e06c5ebf42a61caadd4fb222799772aaef31487bf61ac84c15f58af265d3 -z 0f48b404f989eb25a95140b58f36c4c031d43d55ede1c91cc618226cd8098f04 - -x 33c2fc57d8ffc29e6d670cfc4e25b695320055cf443ade53f49f6c23c452f644 -y 3814860ccbb4391894c107961170d3af1594988a7972b97d0fb2169631b216fa -z d5ad764b0d4b8986d9a504663db5e2e51c6cbc44cbc724d6e4ed558d92a0df4a - -x d0fd0d5e73be5c534aa37645aecc49b202fadb30733f16d0de719a70bec2c751 -y 910c7b4d317397cff70c91e5bf8ec42ba1700b0866adbbfe99b7fbb2c46c7093 -z 2cf19210424bc5835296e55fee3d85866189d0280d925ad144ba9ebdf955573e - -x e0f8130d6b0125e824b254ed57edc59455a8a4704a3f14a4ae8dbf8721595468 -y 4e4f69af6f85742068ad70225e8850c85aef3d3fb3ba3b52c2be979db4eb979d -z 7fa9aa5dfb7bb0c7bc04e4caf96475ccfab866319784d851ecce27ea6c6dbc4a - -x 204d5f69ebab4597d2aa9295ecc2959480a2ab0b225674cc8a147cf7c1e59717 -y 3abdd29c94819ec7507673bd5cc4fb267fcb17c1509abd5e462b46b012f815a8 -z c08f8ccc562aa7cf81341fd88ffe996d01d7934ad1bbb66d44e93547afed816f - -x e2d75c74060aee615b6cfc815c8618f826b07c4987e10f20d27ff74eab3ac7d0 -y 7a06b32d284b5faedb91dac8e94cb7f76c678bad81ed78ac4e75eb9edd8d11e9 -z 55d1a946debe8eb37fda21b972396100ba48f19b05f49673830a0cb0cdacb567 - -x 8d50b0573b0bb945bf128e1a9a37c151e991581673cf6295db5a6223d428ac9d -y 47ca477794fdf378f3486355b5348960ee957470b8c74d62199ac48b4478c4ca -z 338668e0a60dc5cccbc92ac5e40238f1fafbe3a5ba071533c2c09d978fb0e752 - -x b66b49190a99456aaac5c33beaec423a3fa79a84df0f00122aed29151185ceef -y 13c06f7941743bfa261845d99772fd0d5f1a8258aeda53b161505ed8bdca1bc8 -z a3abd99fc8240a7083ad7e62527a452ce08c182c3135ac60c89ccb3c53bab227 - -x 44ac89bb8d4de1a8756b00401236ea4e316a2fe637f6e5f052576da70c29c4ea -y 05dd39ac32768d899b80ed10279aa10d6316d60ab2d061e877dc5f21ce8e1140 -z 52cf4f0f5bd7531fdaea122feb9b4841ce5359db85258408db7a0d863e9ab22a - -x ef0f6c7f56ff22260c66d583f79c7f581181d3a0f3167c93786bb6c89de4372c -y be934afeffaf5e6755a92e6606ffd054627dbe1b18ad6ae543363a01da605512 -z 317c2181564fc4beb6bca61df19dae03af031585db6911ae34357cc7c383e219 - -x 773e0db8f86c5182b5f51d10376f42cde275dac6a646ab1cab065760e045107e -y 3f92ddafdfe67d357b4f9b61807bcb8b0f1f6c2dacba27902f48fc15a31db606 -z 38ac2f081986d34c3aa682aeb6f37641d3566e99fa8b838c7bbe5a4a3d285a77 - -x 34860a848d0afb20e43f4a36b3c8941f5821864216da9cb3ce1a11f056565a3d -y 9dfed86048acd45ec0009c1ba3b20a1ba645ec141070fd8ae41d25e159bbce9f -z 84873123455e26c2233fae1a10168a04b2db992d066a9f28eafceb0efd9a8b1d - -x 854ba91672ae1b8f6c29395dcfa4f3514ed97dc2c9e1e419f926825619fac55b -y 7a700653ad355caf17f89045ecfb3ee821194b54048e55d8eed41fea2b0a22ab -z f8daa2c3c478bfdf5431a817e3a8b4692cc0326ec5538f410a52626cedefa330 - -x 0c66b3d8c3916940b70d381d232ba8aecfe27e3ae63fa6cbb287216708f224f0 -y 477186656245c4083dff93a95c6e5deb707916e52cd74abbd522743c24c53088 -z c5f42c73614ca5377a0ea473c6bc4ac35e696855b9685b10dd64ad2ae42cf467 - -###-------------------------------------------------------------------------- -test condswap - -x 14e55571df646a69a8280bf8dbf8e9afc15bf5558bb8b8236ebcaa19a96053bd -y 8bef5021598a8175565e1f2b522ed1c4306fef4e0e973b50d3a03db1fcf11a43 -m 0xffffffff -xx 8bef5021598a8175565e1f2b522ed1c4306fef4e0e973b50d3a03db1fcf11a43 -yy 27e55571df646a69a8280bf8dbf8e9afc15bf5558bb8b8236ebcaa19a960533d - -x 53d8c54864e18f8fc742b2cb996f1d7595122ca9c90de9f49485cf5a5ef05058 -y 9aa95be655b6704a3dd482e8424f82d17443ae26ab41092fad95df9cac678787 -m 0x00000000 -xx 53d8c54864e18f8fc742b2cb996f1d7595122ca9c90de9f49485cf5a5ef05058 -yy ada95be655b6704a3dd482e8424f82d17443ae26ab41092fad95df9cac678707 - -x 8c7b4ffbf50edf7edcf8d69b67796de38b56a5d4e3a9fb2201354cca0b1b7c57 -y 856e707988c37e59fc6689d024b98bc01b71034484ba194ec7f45106267cb7f6 -m 0xffffffff -xx 986e707988c37e59fc6689d024b98bc01b71034484ba194ec7f45106267cb776 -yy 8c7b4ffbf50edf7edcf8d69b67796de38b56a5d4e3a9fb2201354cca0b1b7c57 - -x c8cb24a636f6d8f2c045c8441b21314884a71d55c73d4ef7ad65620ac0d86616 -y 02b47be53df7c8521d57589256e69b8bbeb1e838d84c090287c04a25d5c08e1a -m 0x00000000 -xx c8cb24a636f6d8f2c045c8441b21314884a71d55c73d4ef7ad65620ac0d86616 -yy 02b47be53df7c8521d57589256e69b8bbeb1e838d84c090287c04a25d5c08e1a - -x 7d96f47612fb7135edfa71dd4526d8b4c944d74ddf004e1653d3af52485168b4 -y a4e83162602d20cf71a279c1071038ecf94f38be11ad1191927b3f480d393e1d -m 0x00000000 -xx 9096f47612fb7135edfa71dd4526d8b4c944d74ddf004e1653d3af5248516834 -yy a4e83162602d20cf71a279c1071038ecf94f38be11ad1191927b3f480d393e1d - -x c3a3d4462091b36bd6fd494e70c3166478be0a65bca7f7361246c52dda402981 -y 62d0ae1abbe5cb909328f59e71330269e4f2b1d3c664e7f1f0780e0a4774c262 -m 0xffffffff -xx 62d0ae1abbe5cb909328f59e71330269e4f2b1d3c664e7f1f0780e0a4774c262 -yy d6a3d4462091b36bd6fd494e70c3166478be0a65bca7f7361246c52dda402901 - -x 38c9b0d92be50270e29cc3181952e745cbf21c8d145ae0c0a6e59f25394ea59c -y caf4896a2d3666200741d817ee1dac661652b9a1741ea966d5ed7cbc4c76217a -m 0x00000000 -xx 4bc9b0d92be50270e29cc3181952e745cbf21c8d145ae0c0a6e59f25394ea51c -yy caf4896a2d3666200741d817ee1dac661652b9a1741ea966d5ed7cbc4c76217a - -x d637a72affa4112bbccd2878208ce34fae442e97175e1b39f43c00b14d312a2b -y 76209f8b1f152ba7e1e6294f707831021eb2ac03872ed3774ab8fc5e6a0e864f -m 0x00000000 -xx d637a72affa4112bbccd2878208ce34fae442e97175e1b39f43c00b14d312a2b -yy 76209f8b1f152ba7e1e6294f707831021eb2ac03872ed3774ab8fc5e6a0e864f - -x 12f3bd417fb3860b2a4fd04eb1c51c558a4c5a3dcc1ac457654a45a3cd45b0d4 -y 46f802836c7bde099775f3fb4f5f6345364a7e158bae9e16c4c99aee0cfa5e42 -m 0xffffffff -xx 46f802836c7bde099775f3fb4f5f6345364a7e158bae9e16c4c99aee0cfa5e42 -yy 25f3bd417fb3860b2a4fd04eb1c51c558a4c5a3dcc1ac457654a45a3cd45b054 - -x bf1809201f83a34cb07aa2e2372516631ba0513e600956e6702903e9084770c4 -y 414bbc77d13d7b4e706acc07406e8d624f2485463f9948d81b72268c1e086a14 -m 0xffffffff -xx 414bbc77d13d7b4e706acc07406e8d624f2485463f9948d81b72268c1e086a14 -yy d21809201f83a34cb07aa2e2372516631ba0513e600956e6702903e908477044 - -x bb8703f2ddaaaaa6ad19219684b1bde576b38bbe9065178b24c1bc55563fe525 -y 1cb3ca7846a3c584b1bc05b25ee91d4779ab9ac64ecef0fcbaea8d311b55d618 -m 0xffffffff -xx 1cb3ca7846a3c584b1bc05b25ee91d4779ab9ac64ecef0fcbaea8d311b55d618 -yy bb8703f2ddaaaaa6ad19219684b1bde576b38bbe9065178b24c1bc55563fe525 - -x a07c7110c32e362864a42cd2f371ff420bfd442d291cc15ec079d642b5c85bdf -y 497fa7867fcd0617c4cd765aa6f46b89390744b5b57d11ab732153e075fcb607 -m 0xffffffff -xx 497fa7867fcd0617c4cd765aa6f46b89390744b5b57d11ab732153e075fcb607 -yy b37c7110c32e362864a42cd2f371ff420bfd442d291cc15ec079d642b5c85b5f - -x 10fddb7f48015b394512257da026938b67f65dd0a84dace51417d68da003a913 -y ebd6706b7cd2ee2d97848ee1adaa990d8ddbfad48e43f51d7ef843fa7597410c -m 0xffffffff -xx ebd6706b7cd2ee2d97848ee1adaa990d8ddbfad48e43f51d7ef843fa7597410c -yy 10fddb7f48015b394512257da026938b67f65dd0a84dace51417d68da003a913 - -x 1dd835e2173b936a91da37b3aa11e848e4497964a9a78ea929a19105eb981a24 -y 3e6f1ab7d5c460dfb7ad1926c60b64a8dd48ed0115b0655a6d8619666b8c8dde -m 0xffffffff -xx 516f1ab7d5c460dfb7ad1926c60b64a8dd48ed0115b0655a6d8619666b8c8d5e -yy 1dd835e2173b936a91da37b3aa11e848e4497964a9a78ea929a19105eb981a24 - -x c4541b1380e796a333d88affdccb4d2bc68bc5a1b3890ef2fc1a2c38dbcac725 -y 6f6338ad8dc0562bc02e307743b81013ffff6c135fdf8603f9956b7f94eb55fa -m 0xffffffff -xx 826338ad8dc0562bc02e307743b81013ffff6c135fdf8603f9956b7f94eb557a -yy c4541b1380e796a333d88affdccb4d2bc68bc5a1b3890ef2fc1a2c38dbcac725 - -x d71f16494f041d1547e5dd9ed539e6b9c1506cebb66f6424e6c7aaf6d0ace080 -y 78c1e6cc0b6f64e161def3b2ede7465f21f6afe61299e9a3c52b1a7a080b9b26 -m 0x00000000 -xx ea1f16494f041d1547e5dd9ed539e6b9c1506cebb66f6424e6c7aaf6d0ace000 -yy 78c1e6cc0b6f64e161def3b2ede7465f21f6afe61299e9a3c52b1a7a080b9b26 - -x 4d90838ab9cc0a79f4e2aa6a860bf8cfbce5f834aab428d4a06f8ef4a2da582a -y 53124b302e7675ea5784e2e7d9fdecb38d9c8be158312dd81c51757bafb79b42 -m 0x00000000 -xx 4d90838ab9cc0a79f4e2aa6a860bf8cfbce5f834aab428d4a06f8ef4a2da582a -yy 53124b302e7675ea5784e2e7d9fdecb38d9c8be158312dd81c51757bafb79b42 - -x c8e764092ea695b0dd8f0ecbca5a4e02096c821b0f5cd57de8e3e50d8b2a40db -y db7fb38dfede5259a584dbcc697f259ce380110636e301acb308bf687449110e -m 0x00000000 -xx dbe764092ea695b0dd8f0ecbca5a4e02096c821b0f5cd57de8e3e50d8b2a405b -yy db7fb38dfede5259a584dbcc697f259ce380110636e301acb308bf687449110e - -x 34cf8e55b3d2494362a87a24907fbdab61cb4f452ef5a889a1aa40a22be6d976 -y 679c6d6f6dca1b71bb098e3854c63ffb8ddb76f1a1cb246ce956fd71d6477c20 -m 0x00000000 -xx 34cf8e55b3d2494362a87a24907fbdab61cb4f452ef5a889a1aa40a22be6d976 -yy 679c6d6f6dca1b71bb098e3854c63ffb8ddb76f1a1cb246ce956fd71d6477c20 - -x 9638ab322ced065068f98597cc61fc2bd846b5849dc39a881209b8efcbc95eec -y 32922ff2b62e968417225b765f2787387c8a42fcab1dbec3815298f53813a8cd -m 0xffffffff -xx 45922ff2b62e968417225b765f2787387c8a42fcab1dbec3815298f53813a84d -yy a938ab322ced065068f98597cc61fc2bd846b5849dc39a881209b8efcbc95e6c - -###-------------------------------------------------------------------------- -test mulconst - -x 8d517a8804d934ae93388e1d59748c3c22866d7be6cec58a357ec43f6dd029db -a -319312 -z 3f2fea85c9195f2246f4f6fd2e8d5de95c5065edbea45a174bc0d1ef3db4aa54 - -x 1b5d6a6c9cdd0dabd126e5f5ee2513f3d27c56dd3aad89c882fe9fd2d38a93b9 -a 499342 -z dd310555966ebe7f409dcce2933f91af8e14c8909f78e4f113606789dd7f504b - -x 9e03b44e93743e0cf5768f65bd3c0f255e001de330d5e1a863d6e4dbb11748a9 -a -284189 -z 6e8c7f8d0f1476cf2603f5702fe8e8bba5c01e86b6e008ac72987fdd6721183c - -x 9cc65e302736aab9bf02dd451c216ac3dd2066af299d7f6bb361eb3b36777f74 -a -15738 -z 8c067e5dccdafaf56301050be17b8895c07e7f13572bbc5ce1af8b5be043d91b - -x 7f36ff91ed165c6ee44aca261dc09e3e124c2ed8167064c20d9b84fa226e2555 -a 423857 -z dc7415db1ab5e5a5658d089ced49bf97718bccc55e2f15b83a28157cbe47e559 - -x e8852c80db69c7e55d476ed00ca7c0735052f7f72f81198a57236feb89a5903c -a -140934 -z 4923ee40bb01314c2fe9f2f87d0743823311b2d9265219eb7a6de5fdfd09a308 - -x 505ef65d294b77e260757bc867199c4b0922b5022dfd6a1fe7478ea27ec102c5 -a -307893 -z b14d72c991a0bfc22b1b95934bbe589b6a4a1f9c76a89d7012f8cb03379a8844 - -x e410c260dc8c1838f3e9658ae586425039b373ee2ab88c750a51853b012af0af -a 471420 -z 42ae337a920ee1b83768cbf0750f524cf1f9e98b99f195e869785f90a2356756 - -x e2d181914b54175190462d11402717f42efa37967b2fe0bc4433fd4c862fd646 -a 492178 -z 4c6e1ba6896d2d661fbf99b77f63e3095d3341f04bf258dc3e4f51e39c68f576 - -x 9cdda0d7da106ef5cfb34774f48308b64953e92869dab0ba804927080509d8a2 -a -312149 -z 4e75e56793563268480efaf6232ad702bc5aef6246bd44e3499ff437810b523b - -x 9dac4442858b8dcc324464911e6f23ed046e42612e8105dc3aa2b9eccea15dc8 -a -88818 -z ce52a0897600a05383df0a0b99a451f0d5568146b4323392fc164153715ecb0a - -x c9f92ceffa7027ffa71e64b714c36b28a6a18c3608f8170d11d51acbee3c62ba -a -259755 -z 89582517069925572219b2eec2a25029e8e1c78772ca8c50bf23220d02740763 - -x 8f8bcf28f4920465680c8e15befba4ebd23c1e27b71c224c98461f69caf76eb1 -a -430350 -z e96b93f0aab6ca70f7d2c1121110efc320aff34e1ec693d7bf17bce1a756d622 - -x 6f4d413a27388fe84a2585e809927bd470ba1b0dc749ae6e2dfa100617a5a7db -a 11486 -z 1cf1f5bd0770d949ee36df858e5842805d121722de30d2ef6bc2b82d021fc14b - -x e1d05a072d1ab70d895969271f44b7c9d1654171836cf234724d2f90434c04e6 -a 8057 -z e32b3c792cd3b6a770eaa2627ff8de8895873d73d734b961646fbce0643a443d - -x d8564ee3ff02c80f0bf3e9cdfce42cd8ac1012ad8ea74f8c0f5754b5775a8de5 -a -304373 -z 884266ea43a6a9b72d113b437dae63c664ef53884c893212fd864412f4e5e457 - -x bf66769ee0cf873764524e760ee654e8d5090aa774f2e96144d945f8da37af19 -a -159091 -z d7438999b3bdb99a46e2f3dc8492cbaf52b0a19c651cc382c384940861bccb6b - -x 72b7d02b1fe23adea87696864c0a9f0466db85e39db397f0eb428a50e277aa2a -a -521654 -z a611bd153336e178a7f3d912adc2fb39b342132458faeedbdb0a35973efae23e - -x ff5c39d4b7fff86810a7a3b14a58bc01e6ecf062116adaa78dac0d1bd3f6039b -a -140759 -z eb9e32bf7d027cda198048da50aa79a11bc99f3b37a219a2104c78f4affb584f - -x a6f1f7f30e3f9e5467f180f92d2c94165fd9427d0c7d383b9077ca9a7e50dac5 -a -317637 -z 56a32847c50bc9609db9796e1650fbe97524aacea746d3cf285f0f2fced01a49 - -###-------------------------------------------------------------------------- -test mul - -## Easy multiplication. -x 0500000c00003800006000004000000009000006000048000090000040000000 -y 070000180000200000e00000800200000400000c000030000090000080020000 -z de200094610090df0020fe0180270700650d00dc2a00f84100e0340040570000 - -## Random tests. -x adcc6f10734dae2273304a6aa493ee8f96e05f2402341c0d997dce58ea57ff6f -y df3c8d5bb6380fa278d4ff2994c7865bcc146596d3c3126242f0dc3509b57449 -z 5ee2615b75a40367ced4ed4bf1578d13e7afa4d415f38f802b7e7b374365b627 - -x 054bc4d5e9b78b068fd20645eeb1f03aef2e89a1f56cb50e5f1170a86529526a -y f976ffa1d1b4a33d0fd866528897cea3eaffdc75e31aa65450a62ff765fe7985 -z 0210280745f6c29a04433f07f880bfd2eddd758d82996e79c65de817c30e7309 - -x e361c6fedbbe081b7cd683d23a2bf0ac889806be7230b56d9398959713a300ec -y c8121e53d78c2e9ba2ba7f51b7cb15cec970a63b4a642ac470aa1f2145f07bd0 -z b48bb1c7ddd26cd9e5a2cb73bb3885dbe4a47e03886d4dfd59e5729d544d566a - -x 463158a2077f931567d45e19deb4454a2ae77045db70a2c078e160ebdb74fd94 -y 3f311e3f8d225016448fbce3fbfbe84002736e3b0d5a90f57d705ede8706008f -z 44cd97e25c20ae2fe2ef4f2630981a1fe54c79ebd904bc40e39d9fa615ffa76c - -x 1c73fca52556e01204d4b957a01d1049f2247c8666d90c1d3703cff16a38c8bf -y e9afa0cc85577ec7eb1ac66d87260d5f3659936ff88cde8bd1c3fa1d499e8bcb -z 0979a8baf734c86a4f57ae400b7790c4985fba3088cb1b265dfc7a66c794121b - -x 6e2bab74e427b1a44f0cb181f9dedd6fed43cfd395d3708c4ae8fd2137215eb6 -y ef400834f2dad8763a1a5a58a37d1b36a78873860e4dac808d3166f13724942c -z 0d481adbce7bd82ebc5a3e5ed7a492e78a032ebf211a5bd2371c528c77954936 - -x cb3575b41d9521da5c85c6438af14903a8d6d9c3857aa8e101e5295fb277de7b -y 9f76715d2ae3c8ca182406553d3481fc36d67727ca2d51f5db37940aa3208d8d -z 0b2fa619265bd424b9e20d38bf4552ad63de8ab552166080d099edea5fbadf7f - -x abd66cf3b20dc4c5a866f1a3b965f794a726f96dd00f576d16ead66eea3a1177 -y 97f70fc92e0cda0e010f2a9d7608c33db954af18bc18ad55bf66e7d91ae31abd -z dcbb2cf34274971ef030827865b093a00761de3da90e46f00e18d0fd934a2b7f - -x 3b3c96ff9be8e17e0a0d3979ea5e5623fff5fa18914151abf79fe66639beef06 -y 1d29c361677805f1dd2b839e025e56208a10c0b8d9f2a8c490b0a892c0e27080 -z 0050873016bc67023d0c479fffa56a5a70512f9864d00b0a3e951f1e85c8b412 - -x b263d4a71b6d963e0a972819e5e5805b9522f142d3c0ff2738c51cce31e9f0d5 -y 64f3fbcff2195c297292df3e1cf900aae457e09864c5a6248ea21ef8efd557d9 -z 7e6f6f511cbf2743c0fc1c6431243908606cb257d20f8a8a0885e6ecd000e811 - -x 0df0497e1e01dbcc4a48d4865127d9cc31a9a0a56e90cc31619e65c1521b2369 -y 9277f0c6a5bcd7c7ed8dcf7182795f67a12e856b126d09966689834c43aada47 -z 798d270ae34aa2452694b4ff74049a6a5169d71c85bd1a9ac59625e9298cdf1b - -x 1dc64bef2189eb5349f5a8983c1854a40141a5390ea4bf8535a15aa71d0289b7 -y fb59dc9b08f9163881b10020ce040da296ed8c1a9a935c27ca0047a4d7f6342b -z 9fc23104cefd3014a469e6d3a0631338eaf91e24994ecd50bfc0b4547317317e - -x 975b108909e87803af98af9425d2a982865b6cc9c144985b32fe5bb842702e24 -y a69e9130dc40be50e827dc50dac05bf900946cf67ec35f1bb1705001314e4fcb -z 12d042e50d0cff7b43a5ede61ce827a99619bf84995d488fe9eb56a8de769164 - -x 39c0db5a4b161c368b0f71c7e8ef97dddc444e4a33181e0743519f2a879ae04f -y d3cc45ff509ed45998bd5f218408ad51f7457b35e8ad69d5431f174047d7c6e5 -z 96b877604f52782ff2a5b1a12d7db642371ca993b648c4971cbf593213503219 - -x f8c6715e4a327cbbdbb08d74121619abc73dc421d7267029e39b50c1510d2045 -y 63870a83cad4c1c64195ae7b92f3b19c830f35f1a3186815565d846c787c7ffc -z 286a0b8c6681a7b79a5f85426fb60819b7bd349e93c1e11943c41c8dfd57d00f - -x 49c9bcaf5434b8205a348df290a96da27df084f34047efbf91cf544057a50bde -y 54269f8b23c05b94c9c1cd74eae88d9227af12a6fb337548eb93c2a88a75a8a5 -z 1e3dcab5d7361f00e70198b52e8fb6d1fba74abd79d99480527f6711b21b833b - -x c7212b43ff0d10fc52d3a2a7e15bb9cf53856f7ce33b79df89e1d13f95a94511 -y 5213ec20bd054491a5485f665075835da609ad4f3dc005744f061480862ee602 -z e136339fa01067c6c0823a7ebe2f84d917600e244a9883191900bb95a3b59764 - -x a15d62c6308448f1f70602f43be1825696d228eb170bed55322a21d2b1afa915 -y 58afe65bc8adbe22807026aa1b0d68af330bca268fdc054406aa41c820960e71 -z 996c597e0a024c2ff0ffe289d8c7270e4ea1d38e294d7210eddeb2c0725a1305 - -x ea233ae033ca93034bc8fd8ea3c0625bbb15b00265264fdd61f62cc808b505fe -y 09e12ef9b3426991f7119c2e8349278342ed0072317c4ec7ab24561b61396b39 -z 1fd72191fe9f00b0cca6a635d14904bd0c1e0ccd1275e84ad0b7bde134866e2a - -x fe1fd3da05524af4ccd538f1d2ede09582101fc2a47c2e63758a546bed6cc5ec -y 523346406ef3df6ac9a455d0d2e7f732ad01c88245b07a888cc21c40fce11a76 -z de6cac8fdc878d9c4eda6b78f8b629ecf776980e49fed56bab936fc03924f44e - -###-------------------------------------------------------------------------- -test sqr - -x 4dc87ad85abe8938634492ce2ea10bf48dc4aa2fa37a6a0fde3e5a01e90dde2b -z 346297c756d77b8ea312ddc455223f4577aea2a2e8d944cb24adb487de143b46 - -x a33aed91165d7fd13a543760d3915c1b5d411a21895cde81b2f3640b87550cc9 -z f923e49da9d5f45e23a782f911fac1a6c2e67cbbc7b03ee4675a0c5fbec03641 - -x a1406e453db6c92ef808295d1919c5bb2491c0ce6d5326d276c57e57943e0acc -z 18425bbd92149991c4545e65495af0e6372289e9a32649c127122243204bdd73 - -x 70a56b8484234ed002a68c8d535a4e527a61c360f7d4ee5b4970c8ace1e12de0 -z bed1c435139f151d0650577e03c32428f63cdb7bc1920110b5fdbb27f08cb200 - -x 86c3236a6194f1585b4dbeb09d0247fb7d3ae08063ccf9fc4fde70fc23735710 -z 9b6509acadd5d31c4c843e91cec78be00aec4fdf7d86132965bd6f62f078f711 - -x 0e5e83c51a8c091673425c38785e0aa1d74c7261a035a891bf734cca8c8a3db3 -z 4efe5029e99438835a8a45d0180b8de357eac82ba9dd8e127baac0d758dfca1d - -x 31c39a5afc33f8a8d3c570b9dc5389bea6fdaaeeb44cd7524f6c445b9583a34c -z 359b7c8791cc87aa8b3c799c9d4d7e1f4062a4f64436d8c01071597e8c262127 - -x 5a06203c15d6c1db6ea0fcf468a1e3f09d68c4a0f64c3d7e30e70290545e708e -z 07f8b435ea322bedf613458b1eb420f1d6bc96741d69695899bd40f7eca6f72a - -x b1973433646474167b791b326827641260fb33d6a2c96d4e963a6b091f824505 -z 52a62396dbbceead62912f8adfed2707fc25edb51aac19b2a274c246f1209f26 - -x 96b157d71e107168fac206dd63007f10f4ae1225b0761c470ee18ecdb4fff20b -z 84ba2a84b156437cdcc39ecc8b1ad01bba934d8dfb7d504b9f2442db0ad01167 - -x 6167d77675e19785960c28df551b458e41dfd0dfe5e56e785b7367997d5eb0a6 -z 79a558436af4310d3eaee93f9a7cab72bd817fdf59d267e2c530ba8d667a005c - -x fb4b2ab08db932ce10dd62639aabbb266f9ce775fb5a5e0875864f18a3ee506c -z a6013661f2f0ab875739836039bff6bff4c993aefdda43dccecf4c404b9a612a - -x ea26bcf0bfc3e15d4df7ddbcac8b5b9e9a7215d74196d77c9e0524e861c6aeb4 -z 113e06861e3d338618695f4713464cea536c8019da77ff0dd9946f3b860df062 - -x b67b1ffffec757ef147e86cf60898c5dac515f080f43f4e120017caab4eee5ee -z 7d9748a1ff6ca9cdebeb3dd6668522767afb9ebf1c680fe7fb3f5848f7222036 - -x c122016f17f12e53f9ac031719fe428c826217b2b757ae44f2f33d1b8b1bb553 -z dc068d032b97c98eea6dd6c8bc42e9a0a6250c81a36a8f64615489e191287c72 - -x 1266ff0654c08e6183cd6c3cc760cc5c88d1f49b918f2f8f587b3edd4adea513 -z f07f17fadb2e2dbd282d296fe5a15cc5c2baf6b45f5fd5dc4692f252039bc862 - -x 4c4dd9c6e46fb2c096388583f2a0c969245452b23f16ea43e15064c45357ccef -z 5127fd4415a84115997b8b3ebe88a590efde9f8b53a43e86b1a4d60782c91025 - -x 095d149c2616212e5f770f133e719d285a8bc888414271296684e732feb5473f -z d8038bee551cac14d1c610bbc0960d943b01526072c589bc913ab51fd47bc848 - -x ad55f9f916d62bb13ceb1461b99e82d76b860c084ca408dd4a18f154b907754a -z e5c86ee6350c9ab736229f3f53e2ab852641bb8a62fdda609444df377e9ca04a - -x 2e4976f45acc671e38add93aa6a89669cdc9874975879b3134dd37c633c9eb14 -z c6513f1a11346d33b05ad65eca13f11125cf70bdcdd6e666a8a7b9c5b6098429 - -###-------------------------------------------------------------------------- -test inv - -x 344ff33a2bc801f861bd13575797da35352c8164808d27f51ea7ca46931b2b1f -z 07f678dfeef071b038d692bf825cb4e75bc1934bd3a6e3dfea99e78bdaeecf3a - -x 670097e2fbbecf6516e949d98f6d722d3f732c33bfb4e62512f9d28d94546b64 -z b2f5cbcd7d8c996ed33a813b1aa39c36f5826b436867bd89b4ce43a156c1e96b - -x 234f3bd8760cdc8ae7fac9457da418cd082e42906ffe59a13e52185a7845e61c -z 7488ff9231e4819684148e16ebc25440732ffe7d211eb3d3263db1af9f1d0513 - -x 22a39a35b1cabc6dfecd1b898593070f0c81bbd04b4b20f43a9c7c14b5dfe967 -z 892024fdbc8937b9b3aef794f57b8ed8517510b6de3f6088987b1310c1dc7932 - -x d850c118c69198268826d05650958c6bed55b181090cf1c96493ecc4635a913f -z 7aeae1b0dc5211f374872e78da8f225325f3f33f9c42bfdeff25d425dff7710f - -x 33ccdc0e39f7cd0a61782c87ac089eb7bbcabce4dd222f05088d3d6332efe959 -z 668f87e23239e965c80740d4daa9c913609388f291c11f950684f45e689a061d - -x 7c06f93b2f66001c74073b8ba7536049738e89b0a0d859a8a73710de3fadcf79 -z 52df0aa24bb4a7474e6ed9852ba542c1f4c5219372a7b5d60988890e2955491e - -x 9a0ce9ff4026bd58abcf8a128dbc55a19c446005834a143634452821d5f9f0ee -z 79eaa93b6287705c0ba564c31bab1854c7f4354845be065c4bf94d38a7a8b421 - -x a13a127490bd3443fdba99baf61d113f3aadd6966c9732cd16348f9fbed32e0e -z 67290b25e6bd7328dd804309a6203c02a75657f593c7e66e48c9192524e5b87b - -x 35f7ac3eaa36c4ed338388fe7eda61cf237eff6ddc0847cb0c95255bbaef8ddc -z 4950601d2cfe75eb9c4524e2f40f404fe82d0014c916dc43d9416cd2e274992d - -x 8a058593035986da3a19e63dacaf40fb3db4cf382205fc4e4802e0ff0c61c8d6 -z 6a23b743dc2fa4a4132780cf6edfed4c219760f3b31343b08710ea18d2c0fc43 - -x a10d03234e700ec92270b6105fdb787d8edd3f960fdd78ea2e169f49dc708d45 -z 101dad1720604d0b093831baaa97fd0701ce773b9c1be1db0403533ad4376c0a - -x 52d3b9e030a5ed574f7f9489c47e73f78ef88a39b570045f9ef73c9a3e65f425 -z 83da3e088dbc9a3cbe06496c5a52edc8d7abcbb8a0f839361762137b119d961a - -x 9928b5f14ec80a036479d7b08c128e601db880daebef36adde6fbd1f50f82629 -z 8dcaa9a2439b77cbe44928ac2877e09755c505f58df4d0ffb9b23fc256b12779 - -x 5a956523956f8ace6166ea6cb3c7421f8d1142d26084a81d615f00d578e03448 -z 658a3ee24ec5b5f1d2d12614e535247c9f2f259131b00f654e09b4517c63ea09 - -x 157492cd38a07802351ca0d1a5615d5c5f254692acce930fb6be351e9a52f088 -z 32fec1eab85ddf8d27a437876e7f5a07f012b02e7971869811c3c31230204164 - -x 2d07c109c332847567621ef4338e149b99c5bc3bf6e50943695da7fed5d8141e -z a81472d28a8235bff43ad5cc012d52e95ece3dbc5ba2962dc54cf9e7f81bee04 - -x 7e172f6c03415e83d4671e0191151d49e5257651ba73848254e68fad0a095c50 -z 1a8efdc57ae9d39ffa64afbc5d2dc1f25a29d365ac3dee0d8529977c14aa4415 - -x 1934546e37b0bac80319fa7f2f86c18e83de8da830b9d0b5019c26768974eda4 -z ffe55479771f20518d8fc6491055368b5dcce9b4e193d19897f1e116b9cdf946 - -x 90324ccfe0e34e9b08db1862be3bc17798a8581ee097be76545e3bf9d586a2e6 -z 0f5ccf4920d617c9b4f7fe6e2c9e95e89b5516555d5e3f5f9900485451d7425f - -###-------------------------------------------------------------------------- -test xdh - -## These are from Daniel J. Bernstein, `Cryptography in NaCl', 2009-03-10, -## https://cr.yp.to/highspeed/naclcrypto-20090310.pdf - -k 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a -X 0900000000000000000000000000000000000000000000000000000000000000 -Z 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a - -k 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb -X 0900000000000000000000000000000000000000000000000000000000000000 -Z de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f - -k 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a -X de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f -Z 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 - -k 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb -X 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a -Z 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 - -## These tests are from RFC7748. - -k a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4 -X e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c -Z c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552 - -k 4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d -X e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493 -Z 95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957 - -###-------------------------------------------------------------------------- -test xdh-mct - -## These tests are from RFC7748. - -k 0900000000000000000000000000000000000000000000000000000000000000 -X 0900000000000000000000000000000000000000000000000000000000000000 -n 1 -Z 422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079 - -k 0900000000000000000000000000000000000000000000000000000000000000 -X 0900000000000000000000000000000000000000000000000000000000000000 -n 1000 -Z 684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51 - -## This one takes aaaaages. -##k 0900000000000000000000000000000000000000000000000000000000000000 -##X 0900000000000000000000000000000000000000000000000000000000000000 -##n 1000000 -##Z 7c3911e0ab2586fd864497297e575e6f3bc601c0883c30df5f4dd2d24f665424 diff --git a/x25519.c b/x25519.c deleted file mode 100644 index 19f3518..0000000 --- a/x25519.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * x25519.c: Bernstein's X25519 key-exchange function - */ -/* - * 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 . - * - * * Remove the test rig code: a replacement is in a separate source file. - * - * * Ignore the top bit of the input public key: in Secnet, conformance - * with RFC7748 is more valuable than flexibility. - * - * * Strip out the key-management definitions. - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * The X25519 key-agreement algorithm - * - * (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. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "fake-mLib-bits.h" - -#include "montladder.h" -#include "f25519.h" -#include "x25519.h" - -/*----- Important constants -----------------------------------------------*/ - -const octet x25519_base[32] = { 9, 0, /* ... */ }; - -#define A0 121665 - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @x25519@ --- * - * - * Arguments: @octet zz[X25519_OUTSZ]@ = where to put the result - * @const octet k[X25519_KEYSZ]@ = pointer to private key - * @const octet qx[X25519_PUBSZ]@ = pointer to public value - * - * Returns: --- - * - * Use: Calculates X25519 of @k@ and @qx@. - * - * Note that there is disagreement over whether the most - * significant bit of @qx@ (i.e., the value @qx[31]&0x80@) - * should be ignored or counted towards the represented value. - * Historically implementations respected the bit; later - * convention seems to be to ignore it. This implementation - * honours the bit: a caller who wants to ignore the bit can - * easily clear it, while caller who wants to respect it has a - * difficult job if this function ignores it. - */ - -void x25519(octet zz[X25519_OUTSZ], - const octet k[X25519_KEYSZ], - const octet qx[X25519_PUBSZ]) -{ - uint32 kw[8]; - uint8_t b[X25519_PUBSZ]; - f25519 x1; - - /* Load and clamp the key. The low bits are cleared to kill the small - * subgroups on the curve and its twist, and a high bit is set to guard - * against careless implementations, though this isn't one of those. - */ - kw[0] = LOAD32_L(k + 0); kw[1] = LOAD32_L(k + 4); - kw[2] = LOAD32_L(k + 8); kw[3] = LOAD32_L(k + 12); - kw[4] = LOAD32_L(k + 16); kw[5] = LOAD32_L(k + 20); - kw[6] = LOAD32_L(k + 24); kw[7] = LOAD32_L(k + 28); - kw[0] &= 0xfffffff8; kw[7] = (kw[7]&0x3fffffff) | 0x40000000; - - /* Copy the input point and clamp the top bit. */ - memcpy(b, qx, sizeof(b)); b[31] &= 0x7f; - f25519_load(&x1, b); - - /* And run the ladder. */ -#define MULA0(z, x) do { f25519_mulconst((z), (x), A0); } while (0) - MONT_LADDER(f25519, MULA0, kw, 8, 32, &x1, &x1); -#undef MULA0 - f25519_store(zz, &x1); -} - -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -#include -#include - -#include -#include - -static int vrf_x25519(dstr dv[]) -{ - dstr dz = DSTR_INIT; - int ok = 1; - - if (dv[0].len != 32) die(1, "bad key length"); - if (dv[1].len != 32) die(1, "bad public length"); - if (dv[2].len != 32) die(1, "bad result length"); - - dstr_ensure(&dz, 32); dz.len = 32; - x25519((octet *)dz.buf, - (const octet *)dv[0].buf, - (const octet *)dv[1].buf); - if (memcmp(dz.buf, dv[2].buf, 32) != 0) { - ok = 0; - fprintf(stderr, "failed!"); - fprintf(stderr, "\n\t k = "); type_hex.dump(&dv[0], stderr); - fprintf(stderr, "\n\t p = "); type_hex.dump(&dv[1], stderr); - fprintf(stderr, "\n\twant = "); type_hex.dump(&dv[2], stderr); - fprintf(stderr, "\n\tcalc = "); type_hex.dump(&dz, stderr); - fprintf(stderr, "\n"); - } - - dstr_destroy(&dz); - return (ok); -} - -static int vrf_mct(dstr dv[]) -{ - octet b0[32], b1[32], *k = b0, *x = b1, *t; - unsigned long i, niter; - dstr d = DSTR_INIT; - int ok = 1; - - if (dv[0].len != sizeof(b0)) { fprintf(stderr, "k len\n"); exit(2); } - if (dv[1].len != sizeof(b1)) { fprintf(stderr, "x len\n"); exit(2); } - if (dv[3].len != sizeof(b0)) { fprintf(stderr, "result len\n"); exit(2); } - memcpy(b0, dv[0].buf, sizeof(b0)); - memcpy(b1, dv[1].buf, sizeof(b1)); - niter = *(unsigned long *)dv[2].buf; - dstr_ensure(&d, 32); d.len = 32; t = (octet *)d.buf; - - for (i = 0; i < niter; i++) { - x[31] &= 0x7f; - x25519(x, k, x); - t = x; x = k; k = t; - } - memcpy(d.buf, k, d.len); - - if (memcmp(d.buf, dv[3].buf, d.len) != 0) { - ok = 0; - fprintf(stderr, "failed..."); - fprintf(stderr, "\n\tinitial k = "); type_hex.dump(&dv[0], stderr); - fprintf(stderr, "\n\tinitial x = "); type_hex.dump(&dv[1], stderr); - fprintf(stderr, "\n\titerations = %lu", niter); - fprintf(stderr, "\n\texpected = "); type_hex.dump(&dv[3], stderr); - fprintf(stderr, "\n\tcalculated = "); type_hex.dump(&d, stderr); - fputc('\n', stderr); - } - - dstr_destroy(&d); - return (ok); -} - -static test_chunk tests[] = { - { "x25519", vrf_x25519, { &type_hex, &type_hex, &type_hex } }, - { "x25519-mct", vrf_mct, - { &type_hex, &type_hex, &type_ulong, &type_hex } }, - { 0, 0, { 0 } } -}; - -int main(int argc, char *argv[]) -{ - test_run(argc, argv, tests, SRCDIR "/t/x25519"); - return (0); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/x25519.h b/x25519.h deleted file mode 100644 index b7b03e6..0000000 --- a/x25519.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * x25519.h: Bernstein's X25519 key-exchange function - */ -/* - * 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 . - * - * * Strip out the key-management definitions. - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * The X25519 key-agreement algorithm - * - * (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_X25519_H -#define CATACOMB_X25519_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Notes on the X25519 key-agreement algorithm -----------------------* - * - * This is X25519, as described in Daniel J. Bernstein, `Curve25519: new - * Diffie--Hellman speed records', PKC 2006, - * https://cr.yp.to/ecdh/curve25519-20060209.pdf - * - * Since then, the name `Curve25519' has shifted somewhat, to refer to the - * specific elliptic curve used, and the x-coordinate Diffie--Hellman - * operation is now named `X25519'. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "fake-mLib-bits.h" - -/*----- Important constants -----------------------------------------------*/ - -#define X25519_KEYSZ 32u -#define X25519_PUBSZ 32u -#define X25519_OUTSZ 32u - -extern const octet x25519_base[32]; - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @x25519@ --- * - * - * Arguments: @octet zz[X25519_OUTSZ]@ = where to put the result - * @const octet k[X25519_KEYSZ]@ = pointer to private key - * @const octet qx[X25519_PUBSZ]@ = pointer to public value - * - * Returns: --- - * - * Use: Calculates X25519 of @k@ and @qx@. - * - * Note that there is disagreement over whether the most - * significant bit of @qx@ (i.e., the value @qx[31]&0x80@) - * should be ignored or counted towards the represented value. - * Historically implementations respected the bit; later - * convention seems to be to ignore it. This implementation - * honours the bit: a caller who wants to ignore the bit can - * easily clear it, while caller who wants to respect it has a - * difficult job if this function ignores it. - */ - -extern void x25519(octet /*zz*/[X25519_OUTSZ], - const octet /*k*/[X25519_KEYSZ], - const octet /*qx*/[X25519_PUBSZ]); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/x448-tests.in b/x448-tests.in deleted file mode 100644 index 753ac8d..0000000 --- a/x448-tests.in +++ /dev/null @@ -1,669 +0,0 @@ -### Test cases for arithmetic mod 2^448 - 2^224 - 1. -*-conf-*- - -###-------------------------------------------------------------------------- -test add - -## Some easy ones. -x ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff -y 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -z ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff - -x fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff -y 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -z fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff - -x fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff -y 0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -z 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - -## Random tests. -x 6b3944398448a0a5f6c4e1be9abfcbb082b8f68f1c831d51ef2244f6e1a4c4baaf0ada769c1261b8e14b4856de381d69961078ea1949d39c -y 62e933c5f93e57e042d66b89d3c72ee85441b1207732d888b3d6bc35f3bcef91a6f4564cb085fd3239191c2fe427dcdb0e81164d30ca8145 -z cd2278fe7d87f785399b4d486e87fa98d7f9a7b093b5f5d9a2f9002cd561b44c56ff30c34c985eeb1a656485c260f944a5918e374a1355e2 - -x 34938a406030a285024e9ff0a45987b53accc9d5d59828de8b8e07ba693b64d1dd2c7a190e708253a9ae57572e44fa458c8f8ac87cd96037 -y 9d05863131328886c7203fe70924761e56244d40a04d4b5592f1c6a457b9d94fe950fb8a865f9091ba9223479f3e46680fb78ccddc776bf2 -z d298107291622a0cca6eded7ae7dfdd390f0161676e673331e80ce5ec2f43d21c77d75a494cf12e563417b9ecd8240ae9b4617965951cc29 - -x 4e9cb6823482233daf59662d00212f2afe42183f8ce949b2e0ca5473e32ab647fe9bc1c472b2288715c0d5b118043fbc9aec782654363cdd -y 6c62329ec8eb576b6866cb6af702b891dd2cd72d21c354ada34221141381acca066fb46a8fbce28df44f0ac8062e38847067b8639be867f8 -z bbfee820fd6d7ba817c03198f723e7bbdb6fef6cadac9e5f840d7687f7ab6212050b762f026f0b150a10e0791f3277400b54318aef1ea4d5 - -x b46d33f24a69c2288bed34eb054d1fcd6244606cffca7d53ff4e68f113174655a9a72898ad2699fe49d069a0a84e077bf48205008dee04aa -y 9abc68911a75a6a376837cc6fc0e18c63cfb81747a59ba1314412f032f8b2a2fc5dde29176d141e71dbc11aeb2ecb9a336c8467882a175ea -z 4f2a9c8365de68cc0171b1b1025c37939f3fe2e079243867139097f443a270846e850b2a24f8dae5678c7b4e5b3bc11e2b4b4c780f907a94 - -x 1195eae69f2bad43b7b8330395e41c811bae2f753f0a6727b9decd2e553dce743dbb568b45140c3a464c8646db12b3af18df328a95640706 -y 8fc020ba693b4014fbf4e9c64223a8c3234e1361b8e2a745e3897f582537e20417831c159c107451fec49b88c4cde774330d8986430b39e0 -z a0550ba10967ed57b2ad1dcad707c5443ffc42d6f7ec0e6d9c684d877a74b079543e73a0e124808b441122cf9fe09a244cecbb10d96f40e6 - -x 4b25a323cba12b5d042369a065a3696c7613898205f7defd3ab15ec351ec9fe1ba453c8b9abf254ff793c92b1f77d5f23f7629c04ec5c70d -y b12ee8f930b029e2e4b79b808566b88b8087a510e5f80751ffc8f5426709bc2b40608e3e769dbd97d37dfe8a36fd25fbc1efb2cd9eda09f2 -z fc538b1dfc51553fe9da0421eb0922f8f69a2e93eaefe64e3a7a5406b9f55b0dfba5cac9105de3e6ca11c8b65574fbed0166dc8ded9fd1ff - -x c441e6cebc634bd7de7de356e855528d52f4affae7cdd585352d94218ca171929b17b8f49ea294f5151a277c116519de5ff92ce4e2f6ce0a -y 809617d4e40d53223f01887bfab5a7d2dc1eb4f680ae59981b33e11fe71345b3155f567cc867cd9e48c8b534870c7df49dff883c0900d8cd -z 44d8fda2a1719ef91d7f6bd2e20bfa5f2f1364f1687c2f1e5160754173b5b645b1760e71670a62945ee2dcb0987196d2fdf8b520ecf6a6d8 - -x a92361d9c458605877a6d9229128b1a52f7bab378d0d389568aae10d09d419b0e6436684b438abcaa3e1710efee5ecec1af06cf0c82b339d -y 74bc6cd43025234b1a6e15fe2d4fab520c874af6f896b82ecb096b0ec3cf73ecf04ef1d13ca612ef0981b8aca0a769ae60202eca36410b0e -z 1de0cdadf57d83a39114ef20bf775cf83b02f62d86a4f0c333b44c1ccca38d9cd7925756f1debdb9ad622abb9e8d569b7b109bbaff6c3eab - -x f0ed25db758767b83b1d5ab6f8bdbe8e263b18341ea296b2a5d27c0d928004d6c48695ac88af863ed12be6629d8a1b58ca83ddb4ff9c778b -y 44998d5a87e29ace239af04334451efca0d8bb88b441140caab3e79da9c73f1354df0c4e2a8148141bb44c33eb63f1c0025ec2b289390e06 -z 3487b335fd6902875fb74afa2c03dd8ac713d4bcd2e3aabe4f8664ab3b4844e91866a2fab230cf52ecdf329688ee0c19cde19f6789d68591 - -x 64429139cb6dd44a64984ac73cdf306354a32772da0724c647164d89218906de465c0c47f2841564fc69933d140088a02584bbeb7a138e7a -y 391d7bf04dd8082b6b196651c251737ba319720b66075f2e65a06023e1dc9697ee4c540b6fae20bdc333c9a95e69266b5ebeccf0b2aea18d -z 9e5f0c2a1946dd75cfb1b018ff30a4def7bc997d400f83f4acb6adac03669d7535a9605261333621c09d5ce77269ae0b844288dc2dc22f08 - -x 0bb7ca441d108e3d7a4c43025798eb1f1036e2d2200e2457aa93a631c068bf9e99805e8c69344d6f5fc063865f2e94bb954c20645f8b7003 -y 3f47bc6701604867acc3cf534d62c9847617954d860c34ac2bcacbfb1c24c99a7442a6170ea6539df0c98afaf6fc8f45dcaa77afebcc8290 -z 4afe86ac1e70d6a426101356a4fab4a4864d7720a71a5803d65d722ddd8c88390ec304a477daa00c508aee80562b240172f797134b58f393 - -x 93205ac6e814337d0d12f8e55f0b62a32ba948cbc6df03293d51e67a7aa7e1457d201991f3392f1cc4a4a9b6b2ed27407ac4e24a5b0e2664 -y c2d648607a99e6dccb9f9940ffed57de39928d9c3fcbabd79876ecf1a5476ff5a637d0052f04d82a2794bf0e31268fd6ff640b4aa1ac921f -z 55f7a22663ae195ad9b191265ff9b981653bd66706abaf00d6c7d26c20ef503b2458e996223e0747eb3869c5e313b7167a29ee94fcbab883 - -x 42bb562d81bac7f606d2157697f29f1799b3e5172f003f44785b80006fb56681b832ff6e7875d6a146b09a9a95f9f3cfb210f5b9aa545e0c -y e7cc109d2ea008a1c938c66e296911c0d7503b1a961f23edce9532c718e53518729dcc6f7e921f831c56d1d8ee7c5b4919f4030ce6703e68 -z 298867caaf5ad097d00adce4c05bb1d770042132c51f623147f1b2c7879a9c992ad0cbdef607f62463066c7384764f19cc04f9c590c59c74 - -x 4cfc133cf2b3e22f569340c3a59299087f9caf8b36562d418f2e18494769278c16a22641e4de8f675e9540d6fc0f8c210a64dd63c8d01453 -y f33b0a3beaad1fb12ba48d69ef999bb7a5af3bd2b977aaf518bc65a13caaa9d61cacbb7c5ce6173a282d341cf83c86a458c8d2d10a1c1ac2 -z 40381e77dc6102e18137ce2c952c35c0244ceb5df0cdd736a8ea7dea8413d162334ee2bd40c5a7a186c274f2f44c12c6622cb035d3ec2e15 - -x fc64ef657d34477c17b0674b697cc5a4bc8e665ba1dee02e5afd0d2f57e0a64abb2bc428215d9e8ece95c5283e4233d483201c286e4997cb -y ed4af51625762548e95f32e7042f07bb260f734fb9ba43301daddff9a863990d79791d5db1bbbdbad75c09ce313d93638c219c989702c5ed -z eaafe47ca2aa6cc400109a326eabcc5fe39dd9aa5a99245f77aaed280144405834a5e185d2185c49a6f2cef66f7fc6371042b8c0054c5cb9 - -x 2fa4cdcae0b01f3f3aa28d4ff311054c73683c09749eb312cd4ff7cf018fa647a66b44477459cab757b9149623ecf9064dba16d5601eafb7 -y b378045a6652eea3cc9a8530dea6361daa86866f038e579670f2d50e072417342f1887827335a0a041d1411b24a68d8f190edd8a251ac3c7 -z e31cd22447030ee3063d1380d1b83b691defc278772c0ba93d42cdde09b3bd7bd583cbc9e78e6a58998a56b14792879666c8f35f8638727f - -x 5107c636bcd6bc59ec9c7fcf04efbf90fdde936bff7e221be660d542f74fcccb8b49220b93744203bdb7b026f1bb9fd9a64c0187fd3d99a7 -y ee48bc6d5c231bd7be253ed69171d2525157d0d8fe12fdafa6e7a3285f0d966fd4c570928f61850138489fca5cb540444c24b602d9025899 -z 405082a418fad730abc2bda5966092e34e366444fe911fcb8c48796b575d623b600f939d22d6c704f5ff4ff14d71e01df370b789d640f140 - -x 475e593758fa8506baa94e1b6070aeaff278d905af67f9e5a5273ae0737825d220c02ae7a89f39998f98895c83e51e7bd0cc0c9126273792 -y 3f724d7bbb27bf8b2f4e328bd865e412ed6207802703def28b9b64567b15f7648c1f96ca5092400e32427f9880c95fa0a83f7fbdd6b2d2b7 -z 87d0a6b213224592e9f780a638d692c2dfdbe085d66ad7d831c39e36f08d1c37addfc0b1f9317aa7c1da08f503af7e1b790c8c4efdd9094a - -x fb7923d1a8666b372b41792749ae312903e1b1a8198970a5da6d85dc19a4326bcde206ee841a2bf106c95e99b42fa7eb3fa559b4b88d31c2 -y 45e467dafaee144bbd614028c0ea4d3a37b4ef99ded5c9e44b7526916218202401233364bffadac9424143bac99b4c2d89ceea71c3fd0ea4 -z 415e8baba3558082e8a2b94f09997f633a95a142f85e3a8a26e3ab6d7dbc528fce053a52441506bb490aa2537ecbf318c97344267c8b4066 - -x 2212850af1b191227fc4875e981ee15968832cb6898243af481b62d91ae5cb26fdcd72e45a54cbbbd9efc5e1739f8683d8ab318586b51e7c -y 6b7b3294bfd31a11644924c988b0b19cfc1db66d8e674040ee21537b54aed4e1e217f0b3427d7d4d9dc7d9dcbcda8c2c47c5348b9eaa7ddb -z 8e8db79eb085ac33e30dac2721cf92f664a1e22318ea83ef363db5547093a008e0e562989dd1480977b79fbe307a13b01f71661025609c57 - -###-------------------------------------------------------------------------- -test sub - -x 890e734c6f4af5b1c62cf6fdd0facf76af535bdc9781396c59a6cd8c37cc96aac97fa61bef07c60c69dfb633049014868473d28481385ba1 -y 0a06a622804bfe9041259a435be8c40aa56d1be10dd3c4261157c16c0d0d99d11b0f5dce0b164a2e6d4c53813242954830a39f2c894fb315 -z 7f08cd29effef62085075cba75120b6c0ae63ffb89ae7445484f0c202abffdd8ad70494de3f17bdefb9263b2d14d7f3d54d03258f8e8a78b - -x 17935b9768cf9ecdc3b3a4c3c87ee20f766bca820f620c1852a48d680f445f1a28ee6a9a18fbdcdb9f35846bc6f0bbb1687b227bcadd4c3a -y 9f913b62023a48e577ac9aaa6d06bb5cf46ea3acc2946a80f66fba02859837491a31b6740a5ed1178c8b6faf4198ac836419deb8aa439c0d -z 78012035669556e84b070a195b7827b381fc26d64ccda1975b34d3658aab27d10dbdb4250e9d0bc413aa14bc84580f2e046244c21f9ab02c - -x b1689e72355c7305d5cab07e2d672e7b92872c115f03f9b45fe7c9d3354ea0d3702f4f915900085ec44e816dcd731086c999c0e97ce52b40 -y a85e9b5cbe9f628049f91b9adcc1db63f19e8f7c37b92e43015d0f76f188c1cfe89c86910afb82c2c6f1f7197562b919380a1b32b2439006 -z 090a031677bc10858bd194e450a55217a1e89c94274aca715e8aba5d44c5de038892c8ff4e05859bfd5c89535811576c918fa5b7caa19b39 - -x 8f952f2233cdba45ccaafcb8e6d17b38529a44ff49e8ac8dc6378710d5e5af052c460e2758e3ee28f5866e71737c9b6e7731c03d11d21cd6 -y 5bc41fd436b58032dd4f50cd0c57bda1127a3033c2183d8133cb9c40760ea41bb42f48f36b6a2f3bcd0dbc60b5bef5e4b712308ca0f2b443 -z 34d10f4efc173a13ef5aacebd97abe963f2014cc87cf6f0c936ceacf5ed70bea7716c633ec78bfed2779b210bebda589bf1e90b170df6792 - -x 708939d3a13fe996dd90b1128231b7da3593c12d9ab880a4da9febe7f12bfefe72aab1608145911fdfa1e3f1f59b426a06dee253d4d3eeb6 -y 008929e61e53becf9bc6dcbf6414f3a71e9f134fcab293cd42e096fef3d87a472a79ed1ce623708aee31e12f5bef9bc6d0aa470ce2a52f80 -z 700010ed82ec2ac741cad4521d1dc43217f4addecf05edd697bf54e9fd5283b74831c4439b212195f06f02c29aaca6a335339b47f22dbf36 - -x a7996b0ae1d8ad5856ae5cf3abc8fc61c4b3579d951b632b9af67dce957365759fb5a6f54965a86b1dcccc9439eebdeb04f616c3fb4db382 -y 2df8e6cf52e985d0e20f4f5e9bbaf1b8bd7d7b982da05568b7ea82fd2a5c0302d0ce9feec5e135eca886fd30827905eae204a51e498a173d -z 7aa1843a8eef2788739e0d95100e0ba90636dc04687b0dc3e20bfbd06a176273cfe606078483727f7445cf63b774b80122f171a4b2c39b45 - -x 74179531aaf2ee4e7a309350982fc9ce501ad18c650f0adacce5da9b520ce27c04ca69dca0e719713d4d10db532401bee26b7ff9819bf532 -y 6a3554898f2951ed005bc4ac74dfd0ef124cffbb52301109d8414719473dc17a602a3b530195c383efa22dd6da87414395886e4b9dd5b5f3 -z 09e240a81ac99d6179d5cea32350f8de3dced1d012dff8d0f4a393820acf2002a49f2e899f5256ed4daae204799cbf7a4de310aee4c53f3f - -x e7c145e38ca66fd86991538ab11231abb60af8b0ab7460e047f7b5b69bbe4a3a56c28c14131c35621f4014d541ffabd642c774bc1a5c66c7 -y 9ca047c2251cc6012bd734198e4b2c6ca0d50a85db601659b8380510fc6c1d08a27fa5fb8eb3c9e5622185f83fba6ed128d153cc9563e1d6 -z 4a21fe20678aa9d63eba1e7123c7043f1635ed2bd0134a878fbeb0a69e512d32b442e71884686b7cbc1e8fdc01453d051af620f084f884f0 - -x 8f01ab3bbedf7ac443423793a422910a54dd73f121ce6f52270d7953386bf2b0eb228b2560b7103aa94f3190e80038505f2b21a9f138c414 -y 44a6b845b4b3b6d9c55478664fa2134df50e7ff4c5184aa57bcc8d01da42cdbb78da3898fd92287b604b6a369c06d695241c48605b57808f -z 4a5bf2f5092cc4ea7dedbe2c55807dbd5ecef4fc5bb525adab40eb515d2825f57248528d6224e8be4804c7594cfa61ba3a0fd94896e14385 - -x 1b6f84c1ad9ec3d008f345a19305aa35e5b55efeb535024b0fc9aee4be1c031bb070655fc5e672ea75b5db98cff0dcfb5427e21e5ffc4fa9 -y ad5d4e308c69186e87ac97551e9ec34f2d1746d5f6712b126c3415346ac2271450aca96fc6b9e82ef7e2f3fad60df4f184e34dff8fb53b02 -z 6e1136912135ab628146ae4b7567e6e5b79e1829bfc3d638a39499b0545adb0660c4bbeffe2c8abb7ed2e79df8e2e809d043941fcf4614a7 - -x 25ce194230be078d7f35b85d68706d768fec7994654fcd3f63f3d32eaf59f17bc87a617d41f76b7d0c78b63377a203e43194f0b056d26b0b -y 76266bea72a15cdc355867a490e775c909b7b6cfc833107e7c6b7dbaed2c8491c6d000b2d7d2beb72d72937285aa1bceff18aa35d0c52158 -z aea7ae57bd1cabb049dd50b9d788f7ac8535c3c49c1bbdc1e6875674c02c6dea01aa60cb6924adc5de0523c1f1f7e715327b467b860c4ab3 - -x c010bfa3d130f868f2b975318139c2a847c69014b76164192b437fd7e26b892a5a2425670fe3e8fd9efdfa250f57579d1af2d24f8eb6ce92 -y bfe65616e278b6ce46b295600131bf5ea092451a87f6bc3adf1c86f2fe717351b073062ced1394a14051bb33f3874cca569aae8ba97605f9 -z 002a688defb7419aab07e0d07f08034aa7334bfa2f6ba7de4b26f9e4e2f915d9a9b01e3b22cf545c5eac3ff21bcf0ad3c35724c4e43fc999 - -x b2f21992b1f2155b7afc3a1d731b52c03cf14208e634b7da123888d652afcd919e9f5f0bea8b9986c71a7ba08fefe58ee0402d9a23b95f2c -y ae241fa6292c63f3c09301255a866825b39c9645512ea123486f9a873cacab567cd169c463fb1cf0417633a7055d831d23fd1d58dd42e726 -z 04cefaeb87c6b267b96839f81895e99a8954acc2940616b7cac8ed4e1603223b22cef54686907c9685a447f989926271bd430f4246767805 - -x b714b60b2614ab6ce63bf8eae621357f2e921f79de94982fcd5f524015db3faa52b15ff042733958fa202786f61bfed0b9fb5d5873619aec -y 0c99e1da4c747ad1a625321cf9359b1d823544d1eacfddc38e4bfd729ed2f9fb37760242340f7986843fb8fa0435bcb5cffdf11453caebcf -z ab7bd430d99f309b3f16c6ceedeb9961ac5cdba7f3c4ba6b3e1455cd760846ae1a3b5dae0e64c0d175e16e8bf1e6411beafd6b432097ae1c - -x c5425daf8f7089def2ff910e256d9496fc109d2698cf15dec1ce3f8116231969c5ed327626362b0658c60e74023a3cae5ef128fb5d27cad7 -y bc4e49fbf095f73894c4d623a210475cb7ba78ebbcbee8ab55a851162f789fb21e72de95afe4ddd45b90289f94f6d02b5f5a4b90c603ea31 -z 09f413b49eda91a55e3bbbea825c4d3a4556243bdb102d326c26ee6ae7aa79b6a67b54e076514d31fc35e6d46d436b82ff96dd6a9723e0a5 - -x 9aa20b4259efd3a701a63347181fa63f56f42a97ef836bf3aab88d30bbf28a91bbf713a0170024e6057e2281ac113f9b58cb13d63e850ea7 -y 09e7104367d8c0441d811ecc619af04def9236752c2d47bc508b0de3c3b29c74533d8eb9fee13279aed8d58247e4010206c697d9b72bab43 -z 91bbfafef1161363e424157bb684b5f16661f421c35624375a2d804df73fee1c68ba85e6181ef16c57a54cfe642d3d9952057cfc86596363 - -x e8ead9316aeb8f56d43418cd3bb1a71234c9e20b4a6dc1604ffdfdbcaacebe73b71d18c2c167544304d895d67e2daa2538a4ad0708cd9acf -y ff3603f0960bb7a92f2b7fbfe242b467164e0ca72e89bcab6c467b5391166d05c601b38de40643f04d5b50ff8ec62b18c69e9df74f01babe -z e9b3d641d3dfd8aca409990d596ef3aa1d7bd6641be404b5e2b6826919b8516ef11b6534dd601153b67c45d7ef667e0d72051010b8cbe010 - -x f37b41d9950036d560f02b8befd6f5c73096b8995850b9fc563291fba59fd994916744fbd4c1dd5d17a9e5ecd4ec4a658dfdae1ba7024bc6 -y eeda58ba400f16a946381fb11f0ac0db895957236bcc629ce9d1ea425eef8412ea73af488b97f1afa950736f26c3cace887417b699cc3410 -z 05a1e81e55f11f2c1ab80cdacfcc35eca63c6176ed8356606d60a6b847b05482a7f394b2492aecad6d58727dae298096048997650d3616b6 - -x 2bdb71a053047c4173718ce104e5b8671fbd61c59bfe8b20b890ceda15a69d24eec3775f4ce8a9c16d36e50626bc334e0fc1be492d800c06 -y b1ccd0dac33ac46b2709f9626ed70136f98dfbc705ad93ea8f1b325d644daf2c0180cb83bfdbb7398d3f58c0f6600056a174850b9db91ed4 -z 790ea1c58fc9b7d54b68937e960db731262f66fd9551f83528759c7db058eef7ec43acdb8c0cf287e0f68c462f5b33f86d4c393e90c6ed31 - -x 8f3fd6346c7f2dacf0d7cdb88a5bca3b222a895a07b169d0bcd0af0a9aa634876ae1a939262dd75bd12b5a97127155a015e00acac7d5cbc8 -y 0e9c03c5a06accdddd0d8613e41a00f2b586e297e366987e02e7536e0ca1b4c2c75fed619655acddffe8585c7a828432d90575731a4c8519 -z 81a3d26fcb1461ce12ca47a5a640ca496ca3a6c2234ad151bae95b9c8d0580c4a281bcd78fd72a7ed142013b98eed06d3cda9556ad8946af - -###-------------------------------------------------------------------------- -test condswap - -x db0be3ccfda1e2f8492bffb5d3344f1856ff1896b6a067d2fa064423ac5b05b669db1c9b51899c44a7f470be4173856d9aa3d1cd10cb8c9b -y 3005560f89232a97cebf6808e7493dd0f17e572556b53723b57faee51d8a0a45c7fb51aeb916f59c74ea6041494483b2fdce72189d1bd031 -m 0xffffffff -xx 3005560f89232a97cebf6808e7493dd0f17e572556b53723b57faee51d8a0a45c7fb51aeb916f59c74ea6041494483b2fdce72189d1bd031 -yy db0be3ccfda1e2f8492bffb5d3344f1856ff1896b6a067d2fa064423ac5b05b669db1c9b51899c44a7f470be4173856d9aa3d1cd10cb8c9b - -x ea009751f6a7045ec7d6d46b16cbe663f5a78fca3835626c79864bec4030443bb9349654d52b2edab92b8f4aa876a97e868aa6267a54e6b1 -y 8c6f864ef7f664f4985ed8c1ea0c63bd7ab355b5321c2712791b610a2dadddc90a65ca8d5c25ff199b011193796b08f96420934615103b7b -m 0x00000000 -xx ea009751f6a7045ec7d6d46b16cbe663f5a78fca3835626c79864bec4030443bb9349654d52b2edab92b8f4aa876a97e868aa6267a54e6b1 -yy 8c6f864ef7f664f4985ed8c1ea0c63bd7ab355b5321c2712791b610a2dadddc90a65ca8d5c25ff199b011193796b08f96420934615103b7b - -x dc3aa7d363058993cbdc54e95f3c972a2cea17cdf9370fccdfedfa1ba939ca35f762c5c6283f84348282fd56d83539804427eabe3bd6170d -y 8c47a0990eccf7300986232dbc8ee26e8996c3bb4b73663ec5525312bea8975221c9f49039840c181d042654a8c1806bb86702ac7d0b80f4 -m 0x00000000 -xx dc3aa7d363058993cbdc54e95f3c972a2cea17cdf9370fccdfedfa1ba939ca35f762c5c6283f84348282fd56d83539804427eabe3bd6170d -yy 8c47a0990eccf7300986232dbc8ee26e8996c3bb4b73663ec5525312bea8975221c9f49039840c181d042654a8c1806bb86702ac7d0b80f4 - -x 69b45538513af2148e0a2903539bc5e20fca4da447278bf5967091d2e781121080c14a41989f9ee5218c444d3a42989ba890c7be7faae5d3 -y 935eadbde0c571c29deb4d8404dd39a8cca177ced36c359abfa7a6cafe6075422e1d79cba8d81cdbdfa4a5144faf37b19ca22b2b40fe1a0b -m 0x00000000 -xx 69b45538513af2148e0a2903539bc5e20fca4da447278bf5967091d2e781121080c14a41989f9ee5218c444d3a42989ba890c7be7faae5d3 -yy 935eadbde0c571c29deb4d8404dd39a8cca177ced36c359abfa7a6cafe6075422e1d79cba8d81cdbdfa4a5144faf37b19ca22b2b40fe1a0b - -x de30072f175127ad4200a08099f4d0df0edfa40eb02e21a03c5628dcb2f70da8bce9ebbb1ebed2aca391e73a4114c06bcdbf762bf28777cf -y 5eaf3aecf1f7d1fd3b43be8fa450163c79f162b0c6eaa4b1ad39baaf3a4c36564e001c935fdce38e90789151beff0f3cc4fdfc2d86dcb587 -m 0x00000000 -xx de30072f175127ad4200a08099f4d0df0edfa40eb02e21a03c5628dcb2f70da8bce9ebbb1ebed2aca391e73a4114c06bcdbf762bf28777cf -yy 5eaf3aecf1f7d1fd3b43be8fa450163c79f162b0c6eaa4b1ad39baaf3a4c36564e001c935fdce38e90789151beff0f3cc4fdfc2d86dcb587 - -x 1bb20a5a05b190737ad6b2bc5bc2b9259fa7e36eac8f3032a7c56ed59c1510baaea32bba898b329b0c64fadbe454095b9f82b366bfae3d8b -y cf0a87c8befed020caf82f37b4c5f17d2aa9ff8ab75baa156cfe2716ac1eaabf9bc760c2ddcd66a9d02a8384ad1db9e8f857b151d126e0ef -m 0x00000000 -xx 1bb20a5a05b190737ad6b2bc5bc2b9259fa7e36eac8f3032a7c56ed59c1510baaea32bba898b329b0c64fadbe454095b9f82b366bfae3d8b -yy cf0a87c8befed020caf82f37b4c5f17d2aa9ff8ab75baa156cfe2716ac1eaabf9bc760c2ddcd66a9d02a8384ad1db9e8f857b151d126e0ef - -x c186531a219344dc485cd5dad6500616ac8e0653693168573cb9be590b02dfb1ddc5d87d27f2d9fa46ffeda955a6285b7ef2b9bf84825d06 -y 91f3be7eb2e0be38d92974d81be5126ef40d358f242d23aa4863fb16ba3e8844e02edc87c0206e211587886ed532da0ab148cfcf64e9b58d -m 0x00000000 -xx c186531a219344dc485cd5dad6500616ac8e0653693168573cb9be590b02dfb1ddc5d87d27f2d9fa46ffeda955a6285b7ef2b9bf84825d06 -yy 91f3be7eb2e0be38d92974d81be5126ef40d358f242d23aa4863fb16ba3e8844e02edc87c0206e211587886ed532da0ab148cfcf64e9b58d - -x 9f2476d6db424d19ee0cba4ed091da5b44ca63caf2f711eaeb7edcc75f49e0d0c367c1f2817b6bb39460f897432901064cabed7f6a03b1f0 -y 66e7dcd34d76a19e3285685112b7619f9a3557764a918922faf1370bb97c2b2fa845dd34662cfe7299ab702c68fd43b5f6f15a0af6625f2e -m 0xffffffff -xx 66e7dcd34d76a19e3285685112b7619f9a3557764a918922faf1370bb97c2b2fa845dd34662cfe7299ab702c68fd43b5f6f15a0af6625f2e -yy 9f2476d6db424d19ee0cba4ed091da5b44ca63caf2f711eaeb7edcc75f49e0d0c367c1f2817b6bb39460f897432901064cabed7f6a03b1f0 - -x f124ac31d304a29cdd94bdc0611c61064a7c5f09cf6847bccd52fc7a7b77ede73b42b1ef75f000de4361028e0fb63896f4ef5ad3bc1b9c90 -y 6629084a230c793086e469b9a01e052ad7a5680d6955667e0dfb19a250f447d9e238695400dc4ecaeefcebed44d374e57ec4e414f5629e63 -m 0x00000000 -xx f124ac31d304a29cdd94bdc0611c61064a7c5f09cf6847bccd52fc7a7b77ede73b42b1ef75f000de4361028e0fb63896f4ef5ad3bc1b9c90 -yy 6629084a230c793086e469b9a01e052ad7a5680d6955667e0dfb19a250f447d9e238695400dc4ecaeefcebed44d374e57ec4e414f5629e63 - -x b64f2952510827bef3d32ef6347251274c7241d9913268a7a6a5c360a4b29e7ed04d09a9ee5aa83235eaf8c0582b076b21d78b7062952773 -y 77897028a9a81fd54362a6085aa2c2fd6fdd44589f447c7310b9b3b5a29b54ed15c57e2c9fbff16f20129a4dbd43640a0d1037e277ca5c93 -m 0xffffffff -xx 77897028a9a81fd54362a6085aa2c2fd6fdd44589f447c7310b9b3b5a29b54ed15c57e2c9fbff16f20129a4dbd43640a0d1037e277ca5c93 -yy b64f2952510827bef3d32ef6347251274c7241d9913268a7a6a5c360a4b29e7ed04d09a9ee5aa83235eaf8c0582b076b21d78b7062952773 - -x 4d75efd204a66aed323456e6f55cb891ee7a31d739ae89726e0ea84532f9c740d1b647b117094fb85da2c62da04f3b9cb13db6b840046b7c -y 0afd07bb073a150e7b82711e1f42f7b0789af8192ea6b4e1b24a3d48de7f8b802875aca5a02a9d24deca0b58c895992a449d01026495b96c -m 0x00000000 -xx 4d75efd204a66aed323456e6f55cb891ee7a31d739ae89726e0ea84532f9c740d1b647b117094fb85da2c62da04f3b9cb13db6b840046b7c -yy 0afd07bb073a150e7b82711e1f42f7b0789af8192ea6b4e1b24a3d48de7f8b802875aca5a02a9d24deca0b58c895992a449d01026495b96c - -x 1ff4eb5f0280744f0c909cede8be29cccb8ae43e4626018a9a1d352a97d987678863ba34bdeb183bb5e9347e96760665f5881570778a2e19 -y 49cd390a9edc7fad6c84c2e44ce09e490161094d2dc6cad30759fbef10aa30e5aa6474bc46571188418f3e4a2b19ecfc379a1f94e3a44e48 -m 0x00000000 -xx 1ff4eb5f0280744f0c909cede8be29cccb8ae43e4626018a9a1d352a97d987678863ba34bdeb183bb5e9347e96760665f5881570778a2e19 -yy 49cd390a9edc7fad6c84c2e44ce09e490161094d2dc6cad30759fbef10aa30e5aa6474bc46571188418f3e4a2b19ecfc379a1f94e3a44e48 - -x e96c0316baf01c25ef8a41c02e99aa84c82f8eecd3249be268834afb5f7e95f0ad10bfad4160bb335c30ffd6a1090c91c57eb6ac7a7a5e66 -y 115e6f115bc4e19af60710f3dd821fb58cb680a32d6973eae9ea3e48f1928dc1d9f684a8c8de80affc59bc0fb342bb040f89d2d46b8ff8fc -m 0x00000000 -xx e96c0316baf01c25ef8a41c02e99aa84c82f8eecd3249be268834afb5f7e95f0ad10bfad4160bb335c30ffd6a1090c91c57eb6ac7a7a5e66 -yy 115e6f115bc4e19af60710f3dd821fb58cb680a32d6973eae9ea3e48f1928dc1d9f684a8c8de80affc59bc0fb342bb040f89d2d46b8ff8fc - -x 71bd8f5036da4c33f6940348ea448c2f9bccb152dab40b410bd695923a9e255b33aaf361055be4bb9a570e201dce784cc1ccb0f89faca85f -y 971b2f6569ddd9099a87ec4086d8218abcfbe81579f25f03634e471170a5088f48a6cfd09ed9e389ca37b780165c00b206304229135b6044 -m 0xffffffff -xx 971b2f6569ddd9099a87ec4086d8218abcfbe81579f25f03634e471170a5088f48a6cfd09ed9e389ca37b780165c00b206304229135b6044 -yy 71bd8f5036da4c33f6940348ea448c2f9bccb152dab40b410bd695923a9e255b33aaf361055be4bb9a570e201dce784cc1ccb0f89faca85f - -x 0f1165e19968f3e6159e9f7f843c1b849e5c3917af4e2798869112c6efca9993ed339c8495eec8c54b286820bf7befdc8ae344e4d309c077 -y 7ce5a2ae66b9bddd30c98d9aa9fcdd6ef90d244d10115d15cf5d81e9e389f6852b153a42c642447043fcfd278166b92c624508973449b0e8 -m 0xffffffff -xx 7ce5a2ae66b9bddd30c98d9aa9fcdd6ef90d244d10115d15cf5d81e9e389f6852b153a42c642447043fcfd278166b92c624508973449b0e8 -yy 0f1165e19968f3e6159e9f7f843c1b849e5c3917af4e2798869112c6efca9993ed339c8495eec8c54b286820bf7befdc8ae344e4d309c077 - -x 6dd07b4891d8f45ad1ee64da38383ec50d6f29634767607eca19a547cadc3c157ebe7d86a28d4d2fa2d40f2c5402d8b338cfd8d30aeadb6a -y 63da9a5a0cd51e58168ddb305c0e70a2f898279dae6394e1b3e1ef3a0763847d5d2f15be493114360204d037d7d3c3a9e746d27dcb544ded -m 0xffffffff -xx 63da9a5a0cd51e58168ddb305c0e70a2f898279dae6394e1b3e1ef3a0763847d5d2f15be493114360204d037d7d3c3a9e746d27dcb544ded -yy 6dd07b4891d8f45ad1ee64da38383ec50d6f29634767607eca19a547cadc3c157ebe7d86a28d4d2fa2d40f2c5402d8b338cfd8d30aeadb6a - -x d91228b648f75350d775432af35be9aa283e9729fcd3b689f0c7ee02ea67efd33493980ae5eec92ad6ab42ccd253a7aab5a62c26be275278 -y 07c5d1b4f9b8db88cd4187b1ae5e175bf703af12b26d066c1d55dd367569d3e23e3d0470f3c47e6761746ce7de39cf563500d026a6791980 -m 0xffffffff -xx 07c5d1b4f9b8db88cd4187b1ae5e175bf703af12b26d066c1d55dd367569d3e23e3d0470f3c47e6761746ce7de39cf563500d026a6791980 -yy d91228b648f75350d775432af35be9aa283e9729fcd3b689f0c7ee02ea67efd33493980ae5eec92ad6ab42ccd253a7aab5a62c26be275278 - -x f9e764e20657319802b53ee29df43b0d83d994d9049b9820fc0c31b631265c49f6613923a042eadce5902fb81753784ff5a9c0de2c4f6b12 -y 6ab2f8279e82aa65e8326e5c60bfa067e4967b3ea67d0369853282e5429736529a43eeee3fdf24ebbe5ca85b59647994fc99c90da83c6229 -m 0xffffffff -xx 6ab2f8279e82aa65e8326e5c60bfa067e4967b3ea67d0369853282e5429736529a43eeee3fdf24ebbe5ca85b59647994fc99c90da83c6229 -yy f9e764e20657319802b53ee29df43b0d83d994d9049b9820fc0c31b631265c49f6613923a042eadce5902fb81753784ff5a9c0de2c4f6b12 - -x 772289865ac905fac203e4654b258890ddb91cac71c6d2af3826e3acfebfa222c937b40069ce3a757e2ffd960b5821ed1ad54e4ad2e3c6fd -y 58dbf838ab81a754533c7f80fea48cbc981f724e4c150ddbb0afb5c711a8e21079446f77c427f7eb1892c096fa3eae5e2b070413611cd184 -m 0xffffffff -xx 58dbf838ab81a754533c7f80fea48cbc981f724e4c150ddbb0afb5c711a8e21079446f77c427f7eb1892c096fa3eae5e2b070413611cd184 -yy 772289865ac905fac203e4654b258890ddb91cac71c6d2af3826e3acfebfa222c937b40069ce3a757e2ffd960b5821ed1ad54e4ad2e3c6fd - -x 0bd6656d68c41bfc5389db274367f69191754919435ba58d2256017b5bc595d102c6f4f745b3ceb0c32bd0a6cdadded3a3dc925ef2b5c73c -y 1d903009c74d3d135a192bd42466cd28303f482626a7d10832f1f6eae72c3b051b0373e62300a71226011475034f0bfc6c9a65601bb83993 -m 0xffffffff -xx 1d903009c74d3d135a192bd42466cd28303f482626a7d10832f1f6eae72c3b051b0373e62300a71226011475034f0bfc6c9a65601bb83993 -yy 0bd6656d68c41bfc5389db274367f69191754919435ba58d2256017b5bc595d102c6f4f745b3ceb0c32bd0a6cdadded3a3dc925ef2b5c73c - -###-------------------------------------------------------------------------- -test mulconst - -x cb908747a1af81f52715ef8440aed06aaacbcd7903c99cdecef5ec54e7845bedaad6475028b0cbdb0d53b6eeb71843f900fefd398a083d5a -a -417895 -z e95e64fd1b2e2e79d1bfef5c96942eaf7ca5d40b1af774ed9c4ea2351c8ae81013f896bafd1f0b0e3a3c2ca3347c6cf88f988877af5e009b - -x 46b23d83c0848e79af947191cb76b087483beec6224af749e59c0c5ae27ff8abada31da895f8132aae0457f5ddc30d18a8d52046fbe6ef55 -a 384370 -z 31c9bf2f3bdfd3c1dc115db96d7a1c15e2a9ae67dfebccddc9408a0dcd147d9aa62ce4a55a2d6ad54542317756a08d6be3b959bf132624e2 - -x 53e19751de62909506bebf74411d359014ec4b6afbb8ce14eeed8a3938013f0fee6897e3cc3adcbc90d7df321c4caa1941d0e5909551335d -a -49682 -z 82fb902a8992ec1032a6837cec56189c45d1c1fdc47748e17dd9ecabc807a52eb537d6411f99f4d3b328e7ca76475924f90506a8adeb908e - -x 7ff3b9b3d8ee248a48d0c8d308d8c3658374acc92303143061a46656ae2b35094ed7b5b27d23366c0e42ee0a9471a4355d81cda0e4390348 -a 131908 -z adbb3dd21e634dfe2c41593c65249f03a048338037d4a107892df36f10e3ff68402d6f48e74bc7a7858f2c3650fd2a10acdfd4213850529e - -x f532f4f5ab5447b083ee4225246aaa4448696e4fc8bcf5b0ec1b52df88354e5327d7a3cf6e15db9945205968c275755ea3906a27437d29ed -a 383911 -z 1f42b3585a2553ab19b14639c3e3aca636d88053c70fb758962713783bcd824b729fb4d01dd56a344d991bf2d32a2967acf470b39bee88a6 - -x ef0e2a829097e50575eae6b1ad3fa10b8e417b0363654e0cb07a563a905c02e367c6f1ad7be1469b9f5295e3db0726853adffb820715f7d1 -a -226220 -z a7c5387af1b9f61f09d628feac1a050173021386775c9f534557b8841b812155325e3632eee7a2302ef8af0b4746575d6c2bcf3b29f674b0 - -x 3b4655b1c22542ca413f76bc24751a01cdab6b385b50301d67fd62ba31ad132150e38e12a849405112c4742e93b92849bd8b872c29edb2f9 -a -89924 -z b51c0dfa2407a89435fedbcfd7835b6e0849d8626995fd00974f44c49d794d3c5dc16028e9fdee45bbcd269035e8bdba695a6653028d4d59 - -x 48bdc2073bff25ae9bf7fcc368d65602a71e48c343bc7181c361331f108867d56c588f698aa5b91222f5dbbc859bce656f2607b053222fc7 -a 66432 -z e845dfe65d563884074ffeecaa325706df4a129b73b056cab6ad999588216d72525222ce00ce4d2ffb09fcf6f010a6eeb2eb753fefd44b47 - -x 98a26f23f83673a480076b2fc7ccfef07fbbe70c4160d5af638c345f7d17b00931efff543fd47b7b8b362a70657a458566ada4aefd1c5eaf -a 492192 -z 0ef483482255b5ca0f8338317f6eaf9c4fbf8bde8b8b04e26d2cdc0632186f1e62a9c3a1be23e8dc444ce50783135aeca614c884bdb77a30 - -x 6ebf7c4e06837120cc852a077945656046e64c2d88ce440bdfc8d38736a4d510a722bc8b0d225f11df0e704e4b04c48bf481da68fd1e150e -a -7098 -z 8d4e2cd12323b5744442fe4e4fc21748b344d7f94794398ec187f0f986ee743cd733a7a16bd4495818ab033103f020c794c988c5d2c1628a - -x 94e49f2bb473a7273abed94363c4dc3d13db159e3c3698a62ce5f321252aa03c7f63dd6eff9529c985f43abc7283d11140cb44ff6fd0f3d3 -a -392951 -z 58a606cdc1bf1d5646fc08c7a6b3336fbe532c823c70242ea7536cc6dcdde7c4f492306e39ac0fb88367e41d63a8305d69fab57a52c8c284 - -x cd262298ce3b73294bfb523c30206fc3771144890a0ebcef19e02e5085973a6aeefabdf8cb7186d57be38ee84b114b9a7a22556c0cf88df1 -a -237681 -z 7553420c53b255fb909d6e9008f043e7af25a2a9c29b177b830ff1ae6f6fdcb6aefb8386465f24634fb04c6078322ac691586f91cf7928bd - -x cc9bd2e72ce15dd50877f95812b65c65cf09b14e2817784a5b296c123e498c532362180a932a455b2ddb75e26335dbcb21eb94a90ebb6940 -a 246794 -z 8838e720b6e497d9cde9fbddc2333c13cb5bdbbbe5afe41ffd61f5035c8c4987fddb8036c25b0505765bf1a5aa369c6bf7723c65278584a8 - -x d8ab6b8f3523e98f49140e051c0b744bb0068d20f499c0763aa28ec1d1dd7e86356f357149c317376be96cd520b3ae04a2c4d468d74745e8 -a -360296 -z 4c0bc5f6fc52c6302b74c790d57ccc8fae59f2aeebb59c3393c56e70060f4d170ea41354f5040804a6e8dcb4a7c585ee71a6d90454e701de - -x 6036fbfb9fcc223a1776ec67c9424788aabe553a7d6a0472159edc747ebaf97e99f7263ece635ef0b702a3610aef32e17f59fae503e18d74 -a -5433 -z f6fa9a49b55077330fcda976a19ba7cfd98e44fa54044840df0ae9e19710193e684703f7fadbcbbc534e7be3adec0cae0d95ea414494f368 - -x a3433dfc89ec4d6d858bb5b018e2d474b7de7604ed4491957fe16453d3793740ef88136814f59b19ed3610252e74cbc3a36571d02e57913b -a 237641 -z 7a01a802b7a5aca44675887d9cf94d04d4893e2dc5d7474090cb32798fa370690255f57d18dce2a57126bb5883672b5a74a1c780f48f7bd8 - -x c17ecc6099e9630a4ec20f4199abe1c10d414f6d734014ada1e6f097090a2bb4e638fb52d9bf56080d77c2b535f52cb091cbaad3c65072e8 -a 517226 -z 708adeac4ff99cac4c3eb649d55276f58a7d21a0507af176a53893c567050d352af501a9c242baf53121e8b56f5679b175dc01538350b644 - -x 134263fd765e5f1da64900df5643c5241d4fa8a9e96ee59f01667b64f9122e85e995b90d4bf5d5fe9f68825dfa6edd19d8ce009270ae2984 -a 390674 -z 2ffbda7ccbeecd8dc4600965679146753c496d35bfa546e13edbbaa259065b024c8aaa3a17a3384f4f14d5ee01371ac55fb50a153b4ac1c0 - -x 54326fffef9f0fe1207a07c8ac063d64b3fe81528e005f857319a74da2c3423a552b05f8c465908b028a2dcf15cb7158c99a1d2bdfd890da -a -255467 -z e554e875e480c68c4fd780425ff8fb50f18bbafd0536a09489bc7cf197fdcb80dd4c7e31447a1a862066b6761ea39ea3b8c3002039c86b40 - -x 5c30f73ec3addb2d27e0e79579063f2d30fa9fb47c2b6a3a32553120a047cad83abc901e5a5b4a65f8e51144f7eb0abec9a4d105236b2618 -a -466309 -z 5ec894f6abe2d88971da11b982c3322d1f533a326057816f6273585bfa186a7f569ddf93c27e8e74719ddb515689d5935c56e6b86936f22b - -###-------------------------------------------------------------------------- -test mul - -## Easy tests. -x 0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -y 0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -z 0600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - -x f7ffffdfffffff00000050000000000000a0ffffff03000090fffffffbffffafffffff00000020000000fdffff9ffffffff9ffff7fffffff -y ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff -z bfffff6f02000083ffff5f010000a1ffff9ffcffffc0ffff6ffdffffc4ffffff02000082ffff8f03000089ffff6ffaffff7cffffff000000 - -x f8ff7ffeff5f00001000000800000300000100a0ffffafffff130000fbffff0100000000e0ffffebffffffff7ffffffffeff1f0000080000 -y f7ff7f0200e0ffffefffff070000faff7ffefffffefffffffff7ffff040080ffff1fffff8ffffff7ffff0500800200000000f0fffffbffff -z 0a0100240020f5ff7ffdff4fffff4100003a00201400400300a8feff030180e6fffff9ff8f02003001002c0000f0ff9f0600d0f8ff670200 - -## Random tests. -x 94aa99eaba90c5eb2efd7101c8efeffc1e44c8fcd84ccb8ef27b9792ae12534c0a250e5400407177bd655e51c343f776a3fd26474da4dc74 -y 284a0f7df2d7d7c760cc57b1606625884c1643020230a9eecca7de6098f5338ddf9297daecae8a07e199494cb6db91c2c683566bf79545d2 -z 213a31ed7e494f470736ded872f2c4f3675562a7b42bf01ea246be0ecaae2a61ae500690df9f99ea9fa8e5e1b9ccf3614bc34148b7693c91 - -x a434abefb0de3c7f5e33f9230ead871bb3f06888c0d568b9a74fa32b676dc600fed2d54a042e1b97340852c4d6ef796a18561884d760d4ad -y 99d4c85f047d3dd8e530c50ae7d80815a30ec6ba820316f5da922cfa7a51ab45290ac2ab8a53082716a6d7f77ac5a285fac298eca4fd9c52 -z 97b2991fcc858d5667d3674484db9435ba71ab0c836c534efb823c123f9e94d0d3445257c55c73e8bd62f1d7acf1d75fea5eea669bfb9912 - -x fe9911abbe57f1ddd61acd062d59637b129a1571af65fb70169db0d8b12b498a66d1eefcf9c8cbea01179f113afef0ae192550828885689c -y e371e9a11f662e38caff28cf4cf5ca8cdfe4a8b99fa12a33765a22ae25506874fdcd85388ed406a955d293320e01957f119027ec4803c2a9 -z 171b49441f9891d927d2f6436eee1dc59e7872730be496638017b42151cdf00e9abb212bafc47c05a4e185bf7cf21ccd97b0c8ea426e4381 - -x 1c300df44d28406d070b10c1920e01ea8b9056d9e1d6f9704dbda3f6328c26a28e9e4aa07dc79e03c09c5639cf8b8c783c8b430b9d8c21a8 -y c565b0357a1e8aff3b3a6164ff34c9598a1c15a1551224fb38d25dfa3b0627c9d992dbd215910236aeeed23f4efd99640054b6648946346c -z f7871e06efb6f737cb4e04f708827092e94e3c70faee57f70096b9d674d0ac5b228824924bb705de49de9f9c0e834462093a9a5551fc7d5d - -x 9014dd22854f1f21fa1475d74eba669101c871c2a21ffd5d10f0792e3cc5d34f15b4735759575dda169e2dd868a5ae64dbeaa2a654cfde5c -y c6f59ecf6add5ff92813cd6f37de9c6f8d3ae9cd33e4f3236ff43127f463f297c3067493868adf7823bc285a3d609a57d9b0b841a9b628a1 -z cbebe67e30ed82acb0de699a5d874121257b78c2b0642583713b58fdcd089a6277a5c5e571538e4af9025dfc63cd78931be51780055dfb2f - -x c8fc23a431d744e45e8bcd2dd2ca612db40b26287970aa878a5cf6283c51b2bd4edb76f705f29bc3911a9aee8fb7272009520f3590ac4c4a -y c1015900ea58d6305b8b558c992bff50a8614843cd3d11274830dff6e1db405f8b268100fbc5e44c477cc2a9e83f825c7840e560fc2b2920 -z 6ecf49d92efb60a15a9de38ff37d3b23b339d889ad8b11cb332df260b9c49fd28b287a559fa5a5edf732b3bd1014711fb7d088a37cf6ef72 - -x daaea5c9549776d866be36a032027a65eb8325b1684d3c37cba068e69aad7d4f104ff47c14f669883cdef5dae9a0c7840379631ef97e6bc3 -y f8dc00891a9c55481a224309a8024ea257850b2bc62ab10bb5ea5b836776cd46994900d6656b7f7e0d9092fd824b16d20ea14528a0de7729 -z 83d3eb62429c2ece396cd7069dfa2985630da2fb0949b52f1df9231c82f32022543d4a2302241d0146b4db97f44ec5342b6444f463ad056f - -x 786f4ebb20161c96f93ffe3ee2b0cae50fc454d910b3fae4fbd8454b8ab7975c6cab8f6a1b593996b24b22603137a52ee732f9d19f9a6e43 -y d78d3df4f455c8f5d98baaa17200d4c94056e21768c4ca783188bf15c28dc86c581fd9c150f923f905becba19361ca94f7434d8a74744669 -z e857a2020e1877b50151772bcf06763285c1d8b2b5ffdb63e13ef4985ccc3b965fdb053305f16feea4a3ac0edad21423c80ef847181bdff7 - -x 6b48bf18ec4557e745cad3e106511bd5a9bbe136c77cf639745f891f54bb16c11e19770eb5112df8bb6755b97cb1e23c9c7efe589693764e -y 95c2a38f889c451f792c3d5d8b3237eed3f99e2b4857bfc48f75d7c0de3f293d2cfa7f97d65d75e0e3df633d84931973ac542ce07ba974b1 -z 2fdfb1146b569ac98b0811e600e2d8e578023024ed704f97c7f7d56a2b4a33ac6ec68d14f0789441a904d175fbf8b91603c532ecdffd27e4 - -x 1fbba059c333843e3cf0cff19bec99bd0cfc89c3b390200165680b742fe540b32042959022e7393c9e13ef7fa3f1dd5ac46595803210c536 -y c723bb3649b1d95647636abffd325e363931782f02002ad6d75d2082c980a7a2c5e1d51045880b36d4f62c16250faffcb2acb824d8d3d5d4 -z 97041eef8892ecaaa97c4effb8c69160b3878fd302bc5f0862bfe4894bf23193738d8dd95c9eee9539e23fff67243372b97f02c3a3934555 - -x 26f5bc0c2c49899690fa423478ab1cf7000be27609bf683896a6ce3f619510b061ca04debb6c64540e724d113cd4b8ff3485337851367700 -y b8540188b9ca77a82899c7fd26412dcbd6a3c9b45be595f63bce7426d7c16eb20c3a2dc86afe9064edc19840f75f05de828c276e98451ee5 -z d973580e88abb6c83defc009607082ffbdcae6ce9d577218580459711682f8708a15de9c62e3ca3b50e91a7bf5781deee152ac801a64fe81 - -x 6c044d6556abb8efdf5b180695293464a8bc4b9cab201822053c7295973ea0a8866425629cfff1d372a48f51dbc6a7f828691194c32c2c5c -y da28b84dfd48f206972fe282449991597bc7f0734916b6f7a253897fca2ccd6b80aa477cfd08549b6d25bd18932128e59889e2dcfaf76157 -z a599fabf997468487b9376500b58a51e0e00c86d9eac6f50157aa1017d99ac8b95e7842b36071a192784ef72433c06a1dd042990b71ffe8f - -x 50378c6ac56816962d428ea523a0cf87121fb3c53b37bac6d3a05fcbdfb8a5fb20aa014f1e1b01a3963534d403baeb7c436f72cf3cc5db58 -y 78901fa015c6f0d3e1072aa87d865579fa405615691a3f27945f9b1431ee8bce8ac9965a1f9b0f42ff10bc77c43cc93566eee9a9b79866ed -z 00127644003ed4b518f04abbd058a46015fb328883b92070bc5cf0fd98d7307dfabbc65f3e8551c622792efabe55f03953e498e360410790 - -x 5db2f6db35af2e1c84ab6832b967bf987cd03adea7113fb8806ce8fb3ffa426dc10997e13afcd39cf5cd65f65f8a09e650fad8e5f6ef2648 -y b063695bc97a18d6ccb0785ee4588951dcbee420ce8e37b25cce325352968015c94f9bb784f3a2bfa34c6a1edf710b63f139fff6d4f7b2f3 -z 999284a309482f67ab6460e73ad1ad267052b59fe50cd58a245e22079e2b50b119e312ff60a65037cf9faeaa259d22f689eaedd7924f1093 - -x d5baefaae7fc9000e0d55f287f740dfb1899ba6e9e36338959a16ac5e5f45442a37086b5519a0b439f38b129328aebf468dec4b59c89a249 -y 4febc8666dcf2b150faec9902a5f57e97275e7b122724c2b77d9b78655b455d424db93f859b8de6b09c4bad6d5ba68349c65c41caca67f8b -z 19e6ed86dc819e6b4368d196679328710f63bf1fcba6652265508b509ecd0e3e8b8bf17f8f1eeb361af107ef684a729a3635cb55de3f8605 - -x 9974be322a0f471cfe0855456104219d8037ca1cb5aacb9ff5da86a047ce159430cfd92f67e764244996668ac44d8d9787dc1b5754d215c1 -y 78c00f878fb41fdb0cd22c026881d5022fc470755e6261945b9bfcc3868f591f08288e4d64a65c9f3d0b05d3ab7f27d801aef29e5e98caf8 -z fd51b84f21b06377054dc879b8a176a7799951d5669486b210e4528b9f52bd60f88c2a068f722d85fa12761a4caf2f05bcdeecb7ed62646e - -x f4048d4a1602eeec43cdf20c3ac9f7b359935bae3648070276faf07a5c58fdf79771ba6c077ddeae47617971e2145f4960587637e7028822 -y 32635c7425108f5d19e35e4d91a4bdf3310bc884c9061d0697556ae25e17cd611e090c1179ca9a68225b283c8ab98a7b1e97508592c60c66 -z 8d6a91d016aaa7a0da03b06f5876ce8e8a71d1e5e5eb430d6c5ae16e1d6d9b61e77179b4f6fe43ce37cae27689983d41923f3b30e9d9f930 - -x 9023c019bf7ef6df45e0e44111903c622220bd3dde046679540302451d001e47a153b0ac7dcfb9831e2d262d8e27002197d9640900e4c1cc -y 1f5e2ca612ec6f14df4b528cc35001e763b9414a81381a1a3c7008c0cc525bdb00aea94ce2348f380dda43b5edf4fec7c8cf5ea2f5fec4b8 -z bf2c241efc180988232b83cda91e12dd0aec0d22ab68353c9841c4ea0547fd1b377fbca125f8cf92c426f8eb859f85a3853516ec104d9b6e - -x bbdecfafa9284e3067081b7d1bd7ce0e488829859628a8f6a38bc1a3ca6ec3130dbc1345b69abb7224b047fd3f2dadcf9cc11a8ec46a6436 -y 49a956ee69cdfecf29440d60fde9db1edd94619af97f625d45dc83c64994fe6c1ac858150cb526ca3c58a9fdc09d409ee3ed0b0cbcdb711c -z 7abfd47fdfcceb278c917afd059e335110bec63fea48dedf7f8275da8922201ea06be39e3d1bccea2d38f5eb7d7aa5ef4e6fe6792a9f0ce0 - -x a9483d4f0c94eac273adc392c3f425be610206683cbb6806dca47be3b54ad142fa2c54a7a473675556bcc8cfd50649af3c58d7a91e84b428 -y b986365aa08f088fe04aaaf2e00468af3fb41cda961b56ece5bedfd83cf9a0fb959ae70c23d9b27cd1eaf8b611d9e578aa0b9d899b81d5f1 -z 4af529627637ad3f3f1269319f4fd426d31e276287ee525d0c64974e55fca1cd58694eadf47e44dc3e843e01c36b22f9717067a907840ca1 - -###-------------------------------------------------------------------------- -test sqr - -## Easy tests. -x 0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -z 0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - -x f7ffffdfffffff00000050000000000000a0ffffff03000090fffffffbffffafffffff00000020000000fdffff9ffffffff9ffff7fffffff -z 8c000040010000f3ffffff040000f4000040120000ff0000800a000099000060060000030000000a0000e7010000180000290200800b0000 - -## Random tests. -x 776cf7ee39df23538f76e6be87ecbb1ed78477b858e3520f24b2b36f09a7dd61daf7bd5990af13c11b1419d8215eb69c30efc3917097797b -z 870001f8ff173e02ce682526a513ff99c6e9688cbec13839ecbf0fbc11d8f84f6cf53041b5bdcbc624f9787db9babe61cd477cb9395590d1 - -x 1e5ef8dd68207b3c3d3c670acee7ecb277ee6bc10be9fa3f3d800e1414bf402298ca443de6fd57ca899188c884a93d4b9c9d1b00a7c9ce44 -z 4a6d6da8002b6a0f3f5c3a9631254ccc62cf66c93279c4b77dda55d32514c8b388b543002f8055321c7195ce1fd26f51f48732e664cdc62f - -x e02eba6cd5ec1cc39ab92db439896520e50a5f9e9ed6d31ad37d00ebb2a54cb68f1c0ae537006ec2ffb14aaad2de16ff06194929b702b95a -z 95632fd74045a49782f6f9d0c86d554cf6efd07f9eef57d669828c77537d4c3a69138d755855640064f5e9bc8fbe0eca96fb04053f565431 - -x bad2a1348fc0b54791f9f2875009c8be2d30f14526fbbc22c439c1ae2b865436cd74f428766e4e676b795fe9333312f6334d4e4ec2378e26 -z d87a8f7ca45620b4646fad2c22792538bd16f37879dbc4d87c21cafa60c282f6415fde2fb6293a8b8a6e5b3901f88d75f9243023b68f41d3 - -x d6d221f2bf71eba62e49db570e13ca69f4a8a33543298619cda7c8d2524c9446b11ae7b7d301579f047565b7044b5286c2478896800ad992 -z fdb163312b884bc6d74c4c269011311388ead9c069884f48487f9ac0d62b39aa175e81976fb599716aaa68db4c02985a6f0ffe522b0fb21b - -x 20cc05120202e684981bce1db74af493d218ed8e0f5e76fad46bfeb98c69e504113b0eb91771c602cb422ae09846fbfef7c47afd09689277 -z b07d84ff34dc5f0cbcc60037400ee04ba09f34d1d7a0c6a80672a3f6c1da630681d4207ce1325d301b36f0acaafd7579a108646f5a26b755 - -x 72c4c3e4fcfd36389f558e0d4016f3f088145be47b2de85ee7ab963fcd8c7adf449d5b7c37ad8a32cf97ea9bde5c220fc896cf1b91633e19 -z 1e8f68736c3b259b661c0c1ec065a642e717f9e4d86003411b8e15ff89537d8e129c116d2f8a9e7e1b46879deedd66fa6ce2b60ab680cfb0 - -x 8c524f059e7ebcf3af3072dbd2f76ebc530adba6d26240c8675b5451d5558db648e7a61fefb1369cf2939ba1fadcf8e40385db5d57cacace -z a19188e6821f5cc2c53b7e59ae6f70e95fb929c0f282627ccfa2c6d9cb59dc871e9dcf3e2a8d6d66b7a6907d4d36c9de03c3d74325d8c1f1 - -x dd47eb6f4f68cd3a9abd6af401bd6f3c795d89474dd41a89025b24c8349a0de417c3676bb6ee36002d7c8ff6b4fb4491e693cfa617e079f8 -z 871f46c93dea48a0d937b3f1f724f66615daa9200f0b48cee01c3b20e4a05dd6ce01bd7b2713e096cc2bd1c5ce7ca0c075aed0fc1ef6fa51 - -x 577870fdb83454eed0711eb51d7bd91f9843769737566823e41d0668fad45c82fe069347769244af7230e6fbc40f5a71151279ae65e9893a -z efabd464218df4a490b9870d541c45e9b7ab29bae25d9e976539a553995ded0edc5610916883642a032eae4e96eb9e4e1443f747dec98135 - -x 8ba84194db2aad7b46005423b1251555ea931b933e0083fee76b9863fb528927f27a4a0617b8d75de306103b592a0fbd51b72bfbb051ee2d -z 3a29e940174d846df65d51070295f535a03e988fc401ef62f5dd2456cf52668390e61e7b6912186d6d5260f6d6977004003bb106abbdaf02 - -x 9f17e0943b4e39051abfd8f4512ef177fd5c368ebdf4b0af49df2e1d89e30c4e68ec474d81203964bfe9c1fecc1279e5e4f598ac97b48cb0 -z d794adb47cff3f7666dd0a934896015e59f278d9b1d6dc7a06328da96d6e6520670598129b7e1b26f9537216364199cf5c0010f23692ec90 - -x a6b51625066e4cccb7d45dff5b182e2a6bf4b1cce7090a187d38dd39f08afad6f868c0277bf70d5fb88b6e67432526e4feb39ae707e34990 -z 67315efb85e16a1e97130092cc351759d9c18261845329f63eba1e77d91ad2c7df51ffa50b655de81bc807ea2b3e137214a2b08b400f2b7a - -x 28a0fe53cf73a0419fdb4cb493c6425be8aa812c3693411816c90621097a9d5687feb16ebf874a30ec849297742b7aab5921427d7b474190 -z 69300770a5bc2c9c599431e5f879ef3f3ec065e3a2cfe82e3499018add58acada581e9e81d40799fc74674b9721da018a64138519abdb108 - -x fad58259395fd5bbcfca35b095253a3a121b62f1694e14cd9e2f85bd08e8a15d1dff98e3b81eeec678821a1ee9d6192c8351bde45ce0581f -z bee7e0d6d4de419981ba2aa3964adfc7545e21b72b65c774b2029c22e06f251cebf04cdffd23e2051b57f986cbf7e56f047050714a275e72 - -x 91e548171a8136d2d26e6bea02cb16ec9591e9cd5b913184b22b43d1029bdb214ef737f6e45f473f7d95b8fde075645c3b0c2dd2bd224278 -z abe2936ecf2ac3012455dcac906f691f2d96490539c9621658fd7f66790bbfe0d2df07165ea80e0c3282642d45b63b7db476b53e4f94f1c5 - -x a52c855daa9ede16ea8de7c681436d5d31eda6ca5b441f972e5cf5639a1c56f689fcb411965271853de2893f22b81d7d0facafdb49292e39 -z 382480e92d44199fe5f7c357ad2e5a7277beab1a3055d48e679516151ca85ee3cb498b172087d588738daac2ec1da9638552d76be97626ad - -x c65888cdc1a575fc9a06dce8800607f56fe88839948b7e4e2713aae44b0ae6b7c6b68786b11b430d22766e9e4d76af118a972729c67c06b7 -z 31311e4ff9600089b533cdac6c05de3ddfe6a450ee7fc90cde1bb297e2deb750336ac3ed2f6fa9b88ece846be6f6aeb392f6753eb6fa475e - -x a61c81d621df61ece4b7274f63ae4e9f2e2df1d603fc9303ee361962b2d70bd783ff1b5d8f3ed27f17e7773b2b1c85af7fbd70387bdef5d3 -z a014ef20adc291c0238be3759ceb9f9645524b961761c8a991ce67efbddda568359fe36e762980d75a58a7ba10b803c9f883fe4d2239a08b - -x 96ced952366c324c5fccd48ac5d475cc1944e7e455dc093f0d9680d6d6abf1e45c76a286ac46acb4de061b9eb673a2d3124e6c3b921ad71f -z 6debaeff6a7d2bb2c1389cb3338fc87b2a32e651ecb8d43fc012efc9b9c59c79487b742f0b30d0b64ac283af0d3b877102c6a7ff0f606eb9 - -###-------------------------------------------------------------------------- -test inv - -x d665678f17043846f953fb09c88295d7fd0a53bc70ec7d396aff56e7dfa376f3a338f0da0af9e07b66d3ff7443e3829b541bd667201999d4 -z 6839ab730bf666c6ca987d254d83bf32b981b466c147f04b823981da75e12c9ded469a0a462861a987c13f05739f47596401fec25a5eee5c - -x bb8d567f6163a92603a388405121bd58abfcf05c596bf0624bf65b6a8fe03e6940648382fe01e5ab58e37ce235f4acbfb9e02624001c49da -z 3f60d0fa0036da2db915e232bd841d09f006d4ba018c1d268af86d36990579d669ee63393b95c202645dcb1225fe9e64d14270905e63eb79 - -x d456692d8e00bf9cd86d22a9f4ad9e9879e6298274854ae82729ebbdb0cc46877caeb381506dbb097b10c180d615661189da65d431e3003b -z 6e0f5a173fb60be882a2b570200515dc7ad473e2192470ba89e6dda6cfdd6ff77026a1d76acdded7b5881a54d68605140a4ffceae70906d5 - -x 359ab073b7465de1358a5772aef79db09118541c062421cb30a972525a351f16b5545daed5f9ce8e91a283818df6cdbf443831fbe5f3e848 -z 2b0ea74e6f4533498eb3f34247a9674f3a2cf2ab0e4fde65ff11b0d1e756430bc5452ca4b85bd3a1f10f6e4e3b1874df8d19f390a9021757 - -x 3509fb8b7688f354738d4a8ca4091f66c880db794aacec6115e675090394ca77e1c83b955aaf4d8e75c6e4e9200be1ce5693532a561d970d -z cafa18317193054cff7884bada249422ba889c19693d66610fb774fb4bdfeac0e67a5ba6f84ace126c125c46b4cfd627ee777e231a6ffc1f - -x 42e2babc095d88b61caa8883e91fd045106db9c4eeb4d945703c1dee3229c58869e21f73909ae2f3c4437d301a2a3724d67f6ad310f63835 -z 28c43a594b6471412f504dc10fd79d2c04ec029a7723cfa0a90aef036991f1b56cf156e2cbc7533671086edb54036e9f4ddc9bfe2e3ffcda - -x 9c01d006213bcfda413517ec815e8cebc06707f5649398a9d14a5d64754375c1ded8aaefd838e8eba84746de07a0f9b32caa2325c4c8e540 -z 0a3b64374ac2149d602a9f0ee4fcf6d814c476f451531a086b04b0dd598287b1758f77780b7de08573326a9767e816309d871fb1962bb1a4 - -x 7bbd8a2de4bd2ffee4e93d0dd2fa9c5d4abcf9ab86c097921fe7d603b7ffdd07006c7d79d1a10267edce9b3069b134bed727c8f0ed1aca13 -z c909ffafbcc09a96723b9afba8ec0d00d5ce0c9d85de3c1e4de24cf44fb934bd0d2397b380885b7419cbbeac339fc85e2161f08c2f3515d7 - -x 6a64650ccf103604c3b030415f7114c88c7094fbd0fd2f2b6b907a27fe104ef4e0684c17ff9f26f15eee5e7442e679ecad3e49a0629cb5c3 -z 9db77e47433997640b4c0916c5123e8a4d9c7c0bcd12b2dafccbababd6c9dbc3f4ec7991ea68b3ad4ffc6f0be4920764c65d98bdeba8a811 - -x c3823c71f6c0f3679cb9c776e437e718f856c8fde038418942d062423113352aeb60ab84138f2bf73f268386cab0f2a1419660e966c24187 -z 558bff4fffa85d6f67ad44938f5b4473d250a87a120af9ff645a7db37a43808abe30c19c90bac94adb190840078214518e189d6c9fc5bef2 - -x 44bd920b0eaf47695f93d063cd85c43c58470c23796f4a106b298d5f2b091210d103e9575c369bb0be66b2323d89cc29602a8071697931c6 -z 67464f2dab3a95c9ac7c783017105df7d561d7ae499ad89c4698da2c0710a1654c89966a7bd30d2d5c0511ed9f020309cde84cecd66be8d0 - -x a6b12fc35e62532ea7c1fd49dd834bb7957da914ec3daf2e4f446b54916d016054cb59ffd4e3d9eecd4a18b08033ee8d9ff84db072cc4f86 -z cc70960f0bb743da1b23d11eb87530a820484a861abd68d2ed7079b487d88481d915b1b34c29d9938b5fa54d05c75cb1aebf0b722a6770b6 - -x 1773dc978cd9f94186b83fd5e10a456b48058acd9e3bbacbecee2cfd0f8303c64721ca64c2913d57764336ea055700c2fcafc60d9f4b817e -z 49e443096eb28c167ee62c63bfe4079418fa8e7f9e58757e13327680890b02ce7c9e5bbbc51366e0b3f5315edc456b6f65a09ea1b1a24438 - -x 552158406db36accc32edde2f0ce46e23a1d406f60e54ca6a789386df36a57434c826c9586c4b371df3179f675e5956fe7dc3022f785d9e0 -z e0025a1007d3dff5e44947a0292bee8db5abbd1a0fca1d3ab0a64a37925396cd96c21af54d36656eb0b60c63fd5651622ec5487d53f976e4 - -x 6b006d36f60750bb5c59f6eb31e2efe6098ab67de7a7a8a27201652380a295c408ec78351c2a799d62227dffd4731b7605e5c462dce2c1e8 -z 21785aae5f73da711f6144894728627824b685fac3d95068a9d0c4e0ee058301a8953322a5ee5be75452164a55477f1a987103a718bf98ca - -x 700cb76911e718ce8829f8d767c53e333dd2f7f20d2c020d1da3cc9ce96b9f6c7aad67450d5aab8f8c60e8ad77d4b5fdb86fae92a0ac30fe -z 257f202b457f19f27ceed047e6778204c2b71646fcc96e19c6f07518780bb5b1c456fd6e93ce2f1cb0aea1a225137511dc71e446c1fe22c3 - -x 0c909e0326649d4d375452c5b233a86e90b0fa88b20aa54e02685edd02b70aa022ed8af31e994b70b20101a5cfd8e16ba53c702840b4a16b -z 98c41073ea843b4b5ad6b0589699f48a1576e3d834f8e595b8859069b71bf5e16126aa93b20259ff0a03976ff6d7f78239ec1059f8cf1193 - -x 4529761361781e67037eae69c5ca9977b1e21468834eb83cd369471e5092249015cd263563bff9348a0f51e4a8517e27236ed1ecfe30a780 -z e20d5896be18bb273bb0ba84f6c070de45378bac6d793685e654764e5aa847d48403a68560b48dcb12573ac737366ae701072300615b4659 - -x 6fae83f7eadeaca22b6781f400b01f9de186b12e31fdf56e0ebe98a8420baacf5069ffdf26d0215c16b64027dd69ff29709a64cfe8f52dcb -z daa266a02c4500d989670eb63ab78219892d9c1ca2e17f4b5200cf1d920cfece5e80050be77f81a616de840bf19c23835ed17d57aeeea0f5 - -x 23ca16e8b4c15f8f2b216441d851368d185a7f8587f398b0cf775875678241094538708da0cb2260c5e056b59c003c30c8f84f5088d0c99c -z 9de1360b4718fc762e6ffab46827c5e4672a77d797aa608b31c132d1ad8138e7a64ba1f4278a07a6088f8cec9a01ea9bc1427c55241433c5 - -###-------------------------------------------------------------------------- -test xdh - -## These are taken from RFC7748. - -k 3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3 -X 06fce640fa3487bfda5f6cf2d5263f8aad88334cbd07437f020f08f9814dc031ddbdc38c19c6da2583fa5429db94ada18aa7a7fb4ef8a086 -Z ce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239fe14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f - -k 203d494428b8399352665ddca42f9de8fef600908e0d461cb021f8c538345dd77c3e4806e25f46d3315c44e0a5b4371282dd2c8d5be3095f -X 0fbcc2f993cd56d3305b0b7d9e55d4c1a8fb5dbb52f8e9a1e9b6201b165d015894e56c4d3570bee52fe205e28a78b91cdfbde71ce8d157db -Z 884a02576239ff7a2f2f63b2db6a9ff37047ac13568e1e30fe63c4a7ad1b3ee3a5700df34321d62077e63633c575c1c954514e99da7c179d - - -k 9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b -X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -Z 9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0 - -k 1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d -X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -Z 3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609 - -k 9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b -X 3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609 -Z 07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d - -k 1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d -X 9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0 -Z 07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d - -###-------------------------------------------------------------------------- -test xdh-mct - -## These are taken from RFC7748. - -k 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -n 1 -Z 3f482c8a9f19b01e6c46ee9711d9dc14fd4bf67af30765c2ae2b846a4d23a8cd0db897086239492caf350b51f833868b9bc2b3bca9cf4113 - -k 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -n 1000 -Z aa3b4749d55b9daf1e5b00288826c467274ce3ebbdd5c17b975e09d4af6c67cf10d087202db88286e2b79fceea3ec353ef54faa26e219f38 - -## This one takes aaaaages. -##k 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -##X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -##n 1000000 -##Z 077f453681caca3693198420bbe515cae0002472519b3e67661a7e89cab94695c8f4bcd66e61b9b9c946da8d524de3d69bd9d9d66b997e37 diff --git a/x448.c b/x448.c deleted file mode 100644 index c58335a..0000000 --- a/x448.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * x448.c: Hamburg's X448 key-exchange function - */ -/* - * 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 . - * - * * Remove the test rig code: a replacement is in a separate source file. - * - * * Strip out the key-management definitions. - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * The X448 key-agreement algorithm - * - * (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. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "fake-mLib-bits.h" - -#include "montladder.h" -#include "fgoldi.h" -#include "x448.h" - -/*----- Important constants -----------------------------------------------*/ - -const octet x448_base[56] = { 5, 0, /* ... */ }; - -#define A0 39081 - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @x448@ --- * - * - * Arguments: @octet zz[X448_OUTSZ]@ = where to put the result - * @const octet k[X448_KEYSZ]@ = pointer to private key - * @const octet qx[X448_PUBSZ]@ = pointer to public value - * - * Returns: --- - * - * Use: Calculates X448 of @k@ and @qx@. - */ - -void x448(octet zz[X448_OUTSZ], - const octet k[X448_KEYSZ], - const octet qx[X448_PUBSZ]) -{ - uint32 kw[14]; - fgoldi x1; - unsigned i; - - /* Load and clamp the key. The low bits are cleared to kill the small - * subgroups on the curve and its twist, and a high bit is set to guard - * against careless implementations, though this isn't one of those. - */ - for (i = 0; i < 14; i++) kw[i] = LOAD32_L(k + 4*i); - kw[0] &= 0xfffffffc; kw[13] |= 0x80000000; - - /* And run the ladder. */ - fgoldi_load(&x1, qx); -#define MULA0(z, x) do { fgoldi_mulconst((z), (x), A0); } while (0) - MONT_LADDER(fgoldi, MULA0, kw, 14, 32, &x1, &x1); -#undef MULA0 - fgoldi_store(zz, &x1); -} - -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -#include -#include -#include - -static int vrf_x448(dstr dv[]) -{ - dstr dz = DSTR_INIT; - int ok = 1; - - if (dv[0].len != 56) die(1, "bad key length"); - if (dv[1].len != 56) die(1, "bad public length"); - if (dv[2].len != 56) die(1, "bad result length"); - - dstr_ensure(&dz, 56); dz.len = 56; - x448((octet *)dz.buf, - (const octet *)dv[0].buf, - (const octet *)dv[1].buf); - if (memcmp(dz.buf, dv[2].buf, 56) != 0) { - ok = 0; - fprintf(stderr, "failed!"); - fprintf(stderr, "\n\t k = "); type_hex.dump(&dv[0], stderr); - fprintf(stderr, "\n\t p = "); type_hex.dump(&dv[1], stderr); - fprintf(stderr, "\n\twant = "); type_hex.dump(&dv[2], stderr); - fprintf(stderr, "\n\tcalc = "); type_hex.dump(&dz, stderr); - fprintf(stderr, "\n"); - } - - dstr_destroy(&dz); - return (ok); -} - -static int vrf_mct(dstr dv[]) -{ - octet b0[56], b1[56], *k = b0, *x = b1, *t; - unsigned long i, niter; - dstr d = DSTR_INIT; - int ok = 1; - - if (dv[0].len != sizeof(b0)) { fprintf(stderr, "k len\n"); exit(2); } - if (dv[1].len != sizeof(b1)) { fprintf(stderr, "x len\n"); exit(2); } - if (dv[3].len != sizeof(b0)) { fprintf(stderr, "result len\n"); exit(2); } - memcpy(b0, dv[0].buf, sizeof(b0)); - memcpy(b1, dv[1].buf, sizeof(b1)); - niter = *(unsigned long *)dv[2].buf; - dstr_ensure(&d, 56); d.len = 56; t = (octet *)d.buf; - - for (i = 0; i < niter; i++) { - x448(x, k, x); - t = x; x = k; k = t; - } - memcpy(d.buf, k, d.len); - - if (memcmp(d.buf, dv[3].buf, d.len) != 0) { - ok = 0; - fprintf(stderr, "failed..."); - fprintf(stderr, "\n\tinitial k = "); type_hex.dump(&dv[0], stderr); - fprintf(stderr, "\n\tinitial x = "); type_hex.dump(&dv[1], stderr); - fprintf(stderr, "\n\titerations = %lu", niter); - fprintf(stderr, "\n\texpected = "); type_hex.dump(&dv[3], stderr); - fprintf(stderr, "\n\tcalculated = "); type_hex.dump(&d, stderr); - fputc('\n', stderr); - } - - dstr_destroy(&d); - return (ok); -} - -static test_chunk tests[] = { - { "x448", vrf_x448, { &type_hex, &type_hex, &type_hex } }, - { "x448-mct", vrf_mct, - { &type_hex, &type_hex, &type_ulong, &type_hex } }, - { 0, 0, { 0 } } -}; - -int main(int argc, char *argv[]) -{ - test_run(argc, argv, tests, SRCDIR "/t/x448"); - return (0); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/x448.h b/x448.h deleted file mode 100644 index ae1672f..0000000 --- a/x448.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * x448.h: Hamburg's X448 key-exchange function - */ -/* - * 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 . - * - * * Strip out the key-management definitions. - * - * The file's original comment headers are preserved below. - */ -/* -*-c-*- - * - * The X448 key-agreement algorithm - * - * (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_X448_H -#define CATACOMB_X448_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Notes on the X448 key-agreement algorithm -------------------------* - * - * This is X448, as described in RFC7748, based on the elliptic curve defined - * in Mike Hamburg, `Ed448-Goldilocks, a new elliptic curve', EUROCRYPT 2016, - * https://eprint.iacr.org/2015/625/. - * - * The RFC-specified operation is simpler than the Diffie--Hellman function - * described in Hamburg's paper, since it doesn't involve the `Decaf' - * cofactor elimination procedure. Indeed, it looks very much like X25519 - * with Hamburg's curve slotted in in place of Bernstein's. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "fake-mLib-bits.h" - -/*----- Important constants -----------------------------------------------*/ - -#define X448_KEYSZ 56 -#define X448_PUBSZ 56 -#define X448_OUTSZ 56 - -extern const octet x448_base[56]; - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @x448@ --- * - * - * Arguments: @octet zz[X448_OUTSZ]@ = where to put the result - * @const octet k[X448_KEYSZ]@ = pointer to private key - * @const octet qx[X448_PUBSZ]@ = pointer to public value - * - * Returns: --- - * - * Use: Calculates X448 of @k@ and @qx@. - */ - -extern void x448(octet /*zz*/[X448_OUTSZ], - const octet /*k*/[X448_KEYSZ], - const octet /*qx*/[X448_PUBSZ]); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif -- 2.11.0