mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-02 12:02:47 -05:00
Move a few stray header files into the crypto subdir.
sshblowf.h (as was) is 100% internal to that directory. And mpint_i.h and ecc.h are specialist enough that it's reasonable to ask clients outside the crypto directory to include them with a subdirectory path, to hint that it's an unusual thing to be doing.
This commit is contained in:
@ -9,7 +9,7 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "ssh.h"
|
||||
#include "sshblowf.h"
|
||||
#include "blowfish.h"
|
||||
|
||||
BlowfishContext *bcrypt_setup(const unsigned char *key, int keybytes,
|
||||
const unsigned char *salt, int saltbytes)
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "ssh.h"
|
||||
#include "sshblowf.h"
|
||||
#include "blowfish.h"
|
||||
|
||||
struct BlowfishContext {
|
||||
uint32_t S0[256], S1[256], S2[256], S3[256], P[18];
|
||||
|
14
crypto/blowfish.h
Normal file
14
crypto/blowfish.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Header file shared between sshblowf.c and sshbcrypt.c. Exposes the
|
||||
* internal Blowfish routines needed by bcrypt.
|
||||
*/
|
||||
|
||||
typedef struct BlowfishContext BlowfishContext;
|
||||
|
||||
BlowfishContext *blowfish_make_context(void);
|
||||
void blowfish_free_context(BlowfishContext *ctx);
|
||||
void blowfish_initkey(BlowfishContext *ctx);
|
||||
void blowfish_expandkey(BlowfishContext *ctx,
|
||||
const void *key, short keybytes,
|
||||
const void *salt, short saltbytes);
|
||||
void blowfish_lsb_encrypt_ecb(void *blk, int len, BlowfishContext *ctx);
|
243
crypto/ecc.h
Normal file
243
crypto/ecc.h
Normal file
@ -0,0 +1,243 @@
|
||||
#ifndef PUTTY_ECC_H
|
||||
#define PUTTY_ECC_H
|
||||
|
||||
/*
|
||||
* Arithmetic functions for the various kinds of elliptic curves used
|
||||
* by PuTTY's public-key cryptography.
|
||||
*
|
||||
* All of these elliptic curves are over the finite field whose order
|
||||
* is a large prime p. (Elliptic curves over a field of order 2^n are
|
||||
* also known, but PuTTY currently has no need of them.)
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Weierstrass curves (or rather, 'short form' Weierstrass curves).
|
||||
*
|
||||
* A curve in this form is defined by two parameters a,b, and the
|
||||
* non-identity points on the curve are represented by (x,y) (the
|
||||
* 'affine coordinates') such that y^2 = x^3 + ax + b.
|
||||
*
|
||||
* The identity element of the curve's group is an additional 'point
|
||||
* at infinity', which is considered to be the third point on the
|
||||
* intersection of the curve with any vertical line. Hence, the
|
||||
* inverse of the point (x,y) is (x,-y).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create and destroy Weierstrass curve data structures. The mandatory
|
||||
* parameters to the constructor are the prime modulus p, and the
|
||||
* curve parameters a,b.
|
||||
*
|
||||
* 'nonsquare_mod_p' is an optional extra parameter, only needed by
|
||||
* ecc_edwards_point_new_from_y which has to take a modular square
|
||||
* root. You can pass it as NULL if you don't need that function.
|
||||
*/
|
||||
WeierstrassCurve *ecc_weierstrass_curve(
|
||||
mp_int *p, mp_int *a, mp_int *b, mp_int *nonsquare_mod_p);
|
||||
void ecc_weierstrass_curve_free(WeierstrassCurve *);
|
||||
|
||||
/*
|
||||
* Create points on a Weierstrass curve, given the curve.
|
||||
*
|
||||
* point_new_identity returns the special identity point.
|
||||
* point_new(x,y) returns the non-identity point with the given affine
|
||||
* coordinates.
|
||||
*
|
||||
* point_new_from_x constructs a non-identity point given only the
|
||||
* x-coordinate, by using the curve equation to work out what y has to
|
||||
* be. Of course the equation only tells you y^2, so it only
|
||||
* determines y up to sign; the parameter desired_y_parity controls
|
||||
* which of the two values of y you get, by saying whether you'd like
|
||||
* its minimal non-negative residue mod p to be even or odd. (Of
|
||||
* course, since p itself is odd, exactly one of y and p-y is odd.)
|
||||
* This function has to take a modular square root, so it will only
|
||||
* work if you passed in a non-square mod p when constructing the
|
||||
* curve.
|
||||
*/
|
||||
WeierstrassPoint *ecc_weierstrass_point_new_identity(WeierstrassCurve *curve);
|
||||
WeierstrassPoint *ecc_weierstrass_point_new(
|
||||
WeierstrassCurve *curve, mp_int *x, mp_int *y);
|
||||
WeierstrassPoint *ecc_weierstrass_point_new_from_x(
|
||||
WeierstrassCurve *curve, mp_int *x, unsigned desired_y_parity);
|
||||
|
||||
/* Memory management: copy and free points. */
|
||||
void ecc_weierstrass_point_copy_into(
|
||||
WeierstrassPoint *dest, WeierstrassPoint *src);
|
||||
WeierstrassPoint *ecc_weierstrass_point_copy(WeierstrassPoint *wc);
|
||||
void ecc_weierstrass_point_free(WeierstrassPoint *point);
|
||||
|
||||
/* Check whether a point is actually on the curve. */
|
||||
unsigned ecc_weierstrass_point_valid(WeierstrassPoint *);
|
||||
|
||||
/*
|
||||
* Add two points and return their sum. This function is fully
|
||||
* general: it should do the right thing if the two inputs are the
|
||||
* same, or if either (or both) of the input points is the identity,
|
||||
* or if the two input points are inverses so the output is the
|
||||
* identity. However, it pays for that generality by being slower than
|
||||
* the special-purpose functions below..
|
||||
*/
|
||||
WeierstrassPoint *ecc_weierstrass_add_general(
|
||||
WeierstrassPoint *, WeierstrassPoint *);
|
||||
|
||||
/*
|
||||
* Fast but less general arithmetic functions: add two points on the
|
||||
* condition that they are not equal and neither is the identity, and
|
||||
* add a point to itself.
|
||||
*/
|
||||
WeierstrassPoint *ecc_weierstrass_add(WeierstrassPoint *, WeierstrassPoint *);
|
||||
WeierstrassPoint *ecc_weierstrass_double(WeierstrassPoint *);
|
||||
|
||||
/*
|
||||
* Compute an integer multiple of a point. Not guaranteed to work
|
||||
* unless the integer argument is less than the order of the point in
|
||||
* the group (because it won't cope if an identity element shows up in
|
||||
* any intermediate product).
|
||||
*/
|
||||
WeierstrassPoint *ecc_weierstrass_multiply(WeierstrassPoint *, mp_int *);
|
||||
|
||||
/*
|
||||
* Query functions to get the value of a point back out. is_identity
|
||||
* tells you whether the point is the identity; if it isn't, then
|
||||
* get_affine will retrieve one or both of its affine coordinates.
|
||||
* (You can pass NULL as either output pointer, if you don't need that
|
||||
* coordinate as output.)
|
||||
*/
|
||||
unsigned ecc_weierstrass_is_identity(WeierstrassPoint *wp);
|
||||
void ecc_weierstrass_get_affine(WeierstrassPoint *wp, mp_int **x, mp_int **y);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Montgomery curves.
|
||||
*
|
||||
* A curve in this form is defined by two parameters a,b, and the
|
||||
* curve equation is by^2 = x^3 + ax^2 + x.
|
||||
*
|
||||
* As with Weierstrass curves, there's an additional point at infinity
|
||||
* that is the identity element, and the inverse of (x,y) is (x,-y).
|
||||
*
|
||||
* However, we don't actually work with full (x,y) pairs. We just
|
||||
* store the x-coordinate (so what we're really representing is not a
|
||||
* specific point on the curve but a two-point set {P,-P}). This means
|
||||
* you can't quite do point addition, because if you're given {P,-P}
|
||||
* and {Q,-Q} as input, you can work out a pair of x-coordinates that
|
||||
* are those of P-Q and P+Q, but you don't know which is which.
|
||||
*
|
||||
* Instead, the basic operation is 'differential addition', in which
|
||||
* you are given three parameters P, Q and P-Q and you return P+Q. (As
|
||||
* well as disambiguating which of the possible answers you want, that
|
||||
* extra input also enables a fast formulae for computing it. This
|
||||
* fast formula is more or less why Montgomery curves are useful in
|
||||
* the first place.)
|
||||
*
|
||||
* Doubling a point is still possible to do unambiguously, so you can
|
||||
* still compute an integer multiple of P if you start by making 2P
|
||||
* and then doing a series of differential additions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create and destroy Montgomery curve data structures.
|
||||
*/
|
||||
MontgomeryCurve *ecc_montgomery_curve(mp_int *p, mp_int *a, mp_int *b);
|
||||
void ecc_montgomery_curve_free(MontgomeryCurve *);
|
||||
|
||||
/*
|
||||
* Create, copy and free points on the curve. We don't need to
|
||||
* explicitly represent the identity for this application.
|
||||
*/
|
||||
MontgomeryPoint *ecc_montgomery_point_new(MontgomeryCurve *mc, mp_int *x);
|
||||
void ecc_montgomery_point_copy_into(
|
||||
MontgomeryPoint *dest, MontgomeryPoint *src);
|
||||
MontgomeryPoint *ecc_montgomery_point_copy(MontgomeryPoint *orig);
|
||||
void ecc_montgomery_point_free(MontgomeryPoint *mp);
|
||||
|
||||
/*
|
||||
* Basic arithmetic routines: differential addition and point-
|
||||
* doubling. Each of these assumes that no special cases come up - no
|
||||
* input or output point should be the identity, and in diff_add, P
|
||||
* and Q shouldn't be the same.
|
||||
*/
|
||||
MontgomeryPoint *ecc_montgomery_diff_add(
|
||||
MontgomeryPoint *P, MontgomeryPoint *Q, MontgomeryPoint *PminusQ);
|
||||
MontgomeryPoint *ecc_montgomery_double(MontgomeryPoint *P);
|
||||
|
||||
/*
|
||||
* Compute an integer multiple of a point.
|
||||
*/
|
||||
MontgomeryPoint *ecc_montgomery_multiply(MontgomeryPoint *, mp_int *);
|
||||
|
||||
/*
|
||||
* Return the affine x-coordinate of a point.
|
||||
*/
|
||||
void ecc_montgomery_get_affine(MontgomeryPoint *mp, mp_int **x);
|
||||
|
||||
/*
|
||||
* Test whether a point is the curve identity.
|
||||
*/
|
||||
unsigned ecc_montgomery_is_identity(MontgomeryPoint *mp);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Twisted Edwards curves.
|
||||
*
|
||||
* A curve in this form is defined by two parameters d,a, and the
|
||||
* curve equation is a x^2 + y^2 = 1 + d x^2 y^2.
|
||||
*
|
||||
* Apparently if you ask a proper algebraic geometer they'll tell you
|
||||
* that this is technically not an actual elliptic curve. Certainly it
|
||||
* doesn't work quite the same way as the other kinds: in this form,
|
||||
* there is no need for a point at infinity, because the identity
|
||||
* element is represented by the affine coordinates (0,1). And you
|
||||
* invert a point by negating its x rather than y coordinate: the
|
||||
* inverse of (x,y) is (-x,y).
|
||||
*
|
||||
* The usefulness of this representation is that the addition formula
|
||||
* is 'strongly unified', meaning that the same formula works for any
|
||||
* input and output points, without needing special cases for the
|
||||
* identity or for doubling.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create and destroy Edwards curve data structures.
|
||||
*
|
||||
* Similarly to ecc_weierstrass_curve, you don't have to provide
|
||||
* nonsquare_mod_p if you don't need ecc_edwards_point_new_from_y.
|
||||
*/
|
||||
EdwardsCurve *ecc_edwards_curve(
|
||||
mp_int *p, mp_int *d, mp_int *a, mp_int *nonsquare_mod_p);
|
||||
void ecc_edwards_curve_free(EdwardsCurve *);
|
||||
|
||||
/*
|
||||
* Create points.
|
||||
*
|
||||
* There's no need to have a separate function to create the identity
|
||||
* point, because you can just pass x=0 and y=1 to the usual function.
|
||||
*
|
||||
* Similarly to the Weierstrass curve, ecc_edwards_point_new_from_y
|
||||
* creates a point given only its y-coordinate and the desired parity
|
||||
* of its x-coordinate, and you can only call it if you provided the
|
||||
* optional nonsquare_mod_p argument when creating the curve.
|
||||
*/
|
||||
EdwardsPoint *ecc_edwards_point_new(
|
||||
EdwardsCurve *curve, mp_int *x, mp_int *y);
|
||||
EdwardsPoint *ecc_edwards_point_new_from_y(
|
||||
EdwardsCurve *curve, mp_int *y, unsigned desired_x_parity);
|
||||
|
||||
/* Copy and free points. */
|
||||
void ecc_edwards_point_copy_into(EdwardsPoint *dest, EdwardsPoint *src);
|
||||
EdwardsPoint *ecc_edwards_point_copy(EdwardsPoint *ec);
|
||||
void ecc_edwards_point_free(EdwardsPoint *point);
|
||||
|
||||
/*
|
||||
* Arithmetic: add two points, and calculate an integer multiple of a
|
||||
* point.
|
||||
*/
|
||||
EdwardsPoint *ecc_edwards_add(EdwardsPoint *, EdwardsPoint *);
|
||||
EdwardsPoint *ecc_edwards_multiply(EdwardsPoint *, mp_int *);
|
||||
|
||||
/*
|
||||
* Query functions: compare two points for equality, and return the
|
||||
* affine coordinates of a point.
|
||||
*/
|
||||
unsigned ecc_edwards_eq(EdwardsPoint *, EdwardsPoint *);
|
||||
void ecc_edwards_get_affine(EdwardsPoint *wp, mp_int **x, mp_int **y);
|
||||
|
||||
#endif /* PUTTY_ECC_H */
|
324
crypto/mpint_i.h
Normal file
324
crypto/mpint_i.h
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
* mpint_i.h: definitions used internally by the bignum code, and
|
||||
* also a few other vaguely-bignum-like places.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* The assorted conditional definitions of BignumInt and multiply
|
||||
* macros used throughout the bignum code to treat numbers as arrays
|
||||
* of the most conveniently sized word for the target machine.
|
||||
* Exported so that other code (e.g. poly1305) can use it too.
|
||||
*
|
||||
* This code must export, in whatever ifdef branch it ends up in:
|
||||
*
|
||||
* - two types: 'BignumInt' and 'BignumCarry'. BignumInt is an
|
||||
* unsigned integer type which will be used as the base word size
|
||||
* for all bignum operations. BignumCarry is an unsigned integer
|
||||
* type used to hold the carry flag taken as input and output by
|
||||
* the BignumADC macro (see below).
|
||||
*
|
||||
* - five constant macros:
|
||||
* + BIGNUM_INT_BITS, the number of bits in BignumInt,
|
||||
* + BIGNUM_INT_BYTES, the number of bytes that works out to
|
||||
* + BIGNUM_TOP_BIT, the BignumInt value consisting of only the top bit
|
||||
* + BIGNUM_INT_MASK, the BignumInt value with all bits set
|
||||
* + BIGNUM_INT_BITS_BITS, log to the base 2 of BIGNUM_INT_BITS.
|
||||
*
|
||||
* - four statement macros: BignumADC, BignumMUL, BignumMULADD,
|
||||
* BignumMULADD2. These do various kinds of multi-word arithmetic,
|
||||
* and all produce two output values.
|
||||
* * BignumADC(ret,retc,a,b,c) takes input BignumInt values a,b
|
||||
* and a BignumCarry c, and outputs a BignumInt ret = a+b+c and
|
||||
* a BignumCarry retc which is the carry off the top of that
|
||||
* addition.
|
||||
* * BignumMUL(rh,rl,a,b) returns the two halves of the
|
||||
* double-width product a*b.
|
||||
* * BignumMULADD(rh,rl,a,b,addend) returns the two halves of the
|
||||
* double-width value a*b + addend.
|
||||
* * BignumMULADD2(rh,rl,a,b,addend1,addend2) returns the two
|
||||
* halves of the double-width value a*b + addend1 + addend2.
|
||||
*
|
||||
* Every branch of the main ifdef below defines the type BignumInt and
|
||||
* the value BIGNUM_INT_BITS_BITS. The other constant macros are
|
||||
* filled in by common code further down.
|
||||
*
|
||||
* Most branches also define a macro DEFINE_BIGNUMDBLINT containing a
|
||||
* typedef statement which declares a type _twice_ the length of a
|
||||
* BignumInt. This causes the common code further down to produce a
|
||||
* default implementation of the four statement macros in terms of
|
||||
* that double-width type, and also to defined BignumCarry to be
|
||||
* BignumInt.
|
||||
*
|
||||
* However, if a particular compile target does not have a type twice
|
||||
* the length of the BignumInt you want to use but it does provide
|
||||
* some alternative means of doing add-with-carry and double-word
|
||||
* multiply, then the ifdef branch in question can just define
|
||||
* BignumCarry and the four statement macros itself, and that's fine
|
||||
* too.
|
||||
*/
|
||||
|
||||
/* You can lower the BignumInt size by defining BIGNUM_OVERRIDE on the
|
||||
* command line to be your chosen max value of BIGNUM_INT_BITS_BITS */
|
||||
#if defined BIGNUM_OVERRIDE
|
||||
#define BB_OK(b) ((b) <= BIGNUM_OVERRIDE)
|
||||
#else
|
||||
#define BB_OK(b) (1)
|
||||
#endif
|
||||
|
||||
#if defined __SIZEOF_INT128__ && BB_OK(6)
|
||||
|
||||
/*
|
||||
* 64-bit BignumInt using gcc/clang style 128-bit BignumDblInt.
|
||||
*
|
||||
* gcc and clang both provide a __uint128_t type on 64-bit targets
|
||||
* (and, when they do, indicate its presence by the above macro),
|
||||
* using the same 'two machine registers' kind of code generation
|
||||
* that 32-bit targets use for 64-bit ints.
|
||||
*/
|
||||
|
||||
typedef unsigned long long BignumInt;
|
||||
#define BIGNUM_INT_BITS_BITS 6
|
||||
#define DEFINE_BIGNUMDBLINT typedef __uint128_t BignumDblInt
|
||||
|
||||
#elif defined _MSC_VER && defined _M_AMD64 && BB_OK(6)
|
||||
|
||||
/*
|
||||
* 64-bit BignumInt, using Visual Studio x86-64 compiler intrinsics.
|
||||
*
|
||||
* 64-bit Visual Studio doesn't provide very much in the way of help
|
||||
* here: there's no int128 type, and also no inline assembler giving
|
||||
* us direct access to the x86-64 MUL or ADC instructions. However,
|
||||
* there are compiler intrinsics giving us that access, so we can
|
||||
* use those - though it turns out we have to be a little careful,
|
||||
* since they seem to generate wrong code if their pointer-typed
|
||||
* output parameters alias their inputs. Hence all the internal temp
|
||||
* variables inside the macros.
|
||||
*/
|
||||
|
||||
#include <intrin.h>
|
||||
typedef unsigned char BignumCarry; /* the type _addcarry_u64 likes to use */
|
||||
typedef unsigned __int64 BignumInt;
|
||||
#define BIGNUM_INT_BITS_BITS 6
|
||||
#define BignumADC(ret, retc, a, b, c) do \
|
||||
{ \
|
||||
BignumInt ADC_tmp; \
|
||||
(retc) = _addcarry_u64(c, a, b, &ADC_tmp); \
|
||||
(ret) = ADC_tmp; \
|
||||
} while (0)
|
||||
#define BignumMUL(rh, rl, a, b) do \
|
||||
{ \
|
||||
BignumInt MULADD_hi; \
|
||||
(rl) = _umul128(a, b, &MULADD_hi); \
|
||||
(rh) = MULADD_hi; \
|
||||
} while (0)
|
||||
#define BignumMULADD(rh, rl, a, b, addend) do \
|
||||
{ \
|
||||
BignumInt MULADD_lo, MULADD_hi; \
|
||||
MULADD_lo = _umul128(a, b, &MULADD_hi); \
|
||||
MULADD_hi += _addcarry_u64(0, MULADD_lo, (addend), &(rl)); \
|
||||
(rh) = MULADD_hi; \
|
||||
} while (0)
|
||||
#define BignumMULADD2(rh, rl, a, b, addend1, addend2) do \
|
||||
{ \
|
||||
BignumInt MULADD_lo1, MULADD_lo2, MULADD_hi; \
|
||||
MULADD_lo1 = _umul128(a, b, &MULADD_hi); \
|
||||
MULADD_hi += _addcarry_u64(0, MULADD_lo1, (addend1), &MULADD_lo2); \
|
||||
MULADD_hi += _addcarry_u64(0, MULADD_lo2, (addend2), &(rl)); \
|
||||
(rh) = MULADD_hi; \
|
||||
} while (0)
|
||||
|
||||
#elif (defined __GNUC__ || defined _LLP64 || __STDC__ >= 199901L) && BB_OK(5)
|
||||
|
||||
/* 32-bit BignumInt, using C99 unsigned long long as BignumDblInt */
|
||||
|
||||
typedef unsigned int BignumInt;
|
||||
#define BIGNUM_INT_BITS_BITS 5
|
||||
#define DEFINE_BIGNUMDBLINT typedef unsigned long long BignumDblInt
|
||||
|
||||
#elif defined _MSC_VER && BB_OK(5)
|
||||
|
||||
/* 32-bit BignumInt, using Visual Studio __int64 as BignumDblInt */
|
||||
|
||||
typedef unsigned int BignumInt;
|
||||
#define BIGNUM_INT_BITS_BITS 5
|
||||
#define DEFINE_BIGNUMDBLINT typedef unsigned __int64 BignumDblInt
|
||||
|
||||
#elif defined _LP64 && BB_OK(5)
|
||||
|
||||
/*
|
||||
* 32-bit BignumInt, using unsigned long itself as BignumDblInt.
|
||||
*
|
||||
* Only for platforms where long is 64 bits, of course.
|
||||
*/
|
||||
|
||||
typedef unsigned int BignumInt;
|
||||
#define BIGNUM_INT_BITS_BITS 5
|
||||
#define DEFINE_BIGNUMDBLINT typedef unsigned long BignumDblInt
|
||||
|
||||
#elif BB_OK(4)
|
||||
|
||||
/*
|
||||
* 16-bit BignumInt, using unsigned long as BignumDblInt.
|
||||
*
|
||||
* This is the final fallback for real emergencies: C89 guarantees
|
||||
* unsigned short/long to be at least the required sizes, so this
|
||||
* should work on any C implementation at all. But it'll be
|
||||
* noticeably slow, so if you find yourself in this case you
|
||||
* probably want to move heaven and earth to find an alternative!
|
||||
*/
|
||||
|
||||
typedef unsigned short BignumInt;
|
||||
#define BIGNUM_INT_BITS_BITS 4
|
||||
#define DEFINE_BIGNUMDBLINT typedef unsigned long BignumDblInt
|
||||
|
||||
#else
|
||||
|
||||
/* Should only get here if BB_OK(4) evaluated false, i.e. the
|
||||
* command line defined BIGNUM_OVERRIDE to an absurdly small
|
||||
* value. */
|
||||
#error Must define BIGNUM_OVERRIDE to at least 4
|
||||
|
||||
#endif
|
||||
|
||||
#undef BB_OK
|
||||
|
||||
/*
|
||||
* Common code across all branches of that ifdef: define all the
|
||||
* easy constant macros in terms of BIGNUM_INT_BITS_BITS.
|
||||
*/
|
||||
#define BIGNUM_INT_BITS (1 << BIGNUM_INT_BITS_BITS)
|
||||
#define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8)
|
||||
#define BIGNUM_TOP_BIT (((BignumInt)1) << (BIGNUM_INT_BITS-1))
|
||||
#define BIGNUM_INT_MASK (BIGNUM_TOP_BIT | (BIGNUM_TOP_BIT-1))
|
||||
|
||||
/*
|
||||
* Just occasionally, we might need a GET_nnBIT_xSB_FIRST macro to
|
||||
* operate on whatever BignumInt is.
|
||||
*/
|
||||
#if BIGNUM_INT_BITS_BITS == 4
|
||||
#define GET_BIGNUMINT_MSB_FIRST GET_16BIT_MSB_FIRST
|
||||
#define GET_BIGNUMINT_LSB_FIRST GET_16BIT_LSB_FIRST
|
||||
#define PUT_BIGNUMINT_MSB_FIRST PUT_16BIT_MSB_FIRST
|
||||
#define PUT_BIGNUMINT_LSB_FIRST PUT_16BIT_LSB_FIRST
|
||||
#elif BIGNUM_INT_BITS_BITS == 5
|
||||
#define GET_BIGNUMINT_MSB_FIRST GET_32BIT_MSB_FIRST
|
||||
#define GET_BIGNUMINT_LSB_FIRST GET_32BIT_LSB_FIRST
|
||||
#define PUT_BIGNUMINT_MSB_FIRST PUT_32BIT_MSB_FIRST
|
||||
#define PUT_BIGNUMINT_LSB_FIRST PUT_32BIT_LSB_FIRST
|
||||
#elif BIGNUM_INT_BITS_BITS == 6
|
||||
#define GET_BIGNUMINT_MSB_FIRST GET_64BIT_MSB_FIRST
|
||||
#define GET_BIGNUMINT_LSB_FIRST GET_64BIT_LSB_FIRST
|
||||
#define PUT_BIGNUMINT_MSB_FIRST PUT_64BIT_MSB_FIRST
|
||||
#define PUT_BIGNUMINT_LSB_FIRST PUT_64BIT_LSB_FIRST
|
||||
#else
|
||||
#error Ran out of options for GET_BIGNUMINT_xSB_FIRST
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Common code across _most_ branches of the ifdef: define a set of
|
||||
* statement macros in terms of the BignumDblInt type provided. In
|
||||
* this case, we also define BignumCarry to be the same thing as
|
||||
* BignumInt, for simplicity.
|
||||
*/
|
||||
#ifdef DEFINE_BIGNUMDBLINT
|
||||
|
||||
typedef BignumInt BignumCarry;
|
||||
#define BignumADC(ret, retc, a, b, c) do \
|
||||
{ \
|
||||
DEFINE_BIGNUMDBLINT; \
|
||||
BignumDblInt ADC_temp = (BignumInt)(a); \
|
||||
ADC_temp += (BignumInt)(b); \
|
||||
ADC_temp += (c); \
|
||||
(ret) = (BignumInt)ADC_temp; \
|
||||
(retc) = (BignumCarry)(ADC_temp >> BIGNUM_INT_BITS); \
|
||||
} while (0)
|
||||
|
||||
#define BignumMUL(rh, rl, a, b) do \
|
||||
{ \
|
||||
DEFINE_BIGNUMDBLINT; \
|
||||
BignumDblInt MUL_temp = (BignumInt)(a); \
|
||||
MUL_temp *= (BignumInt)(b); \
|
||||
(rh) = (BignumInt)(MUL_temp >> BIGNUM_INT_BITS); \
|
||||
(rl) = (BignumInt)(MUL_temp); \
|
||||
} while (0)
|
||||
|
||||
#define BignumMULADD(rh, rl, a, b, addend) do \
|
||||
{ \
|
||||
DEFINE_BIGNUMDBLINT; \
|
||||
BignumDblInt MUL_temp = (BignumInt)(a); \
|
||||
MUL_temp *= (BignumInt)(b); \
|
||||
MUL_temp += (BignumInt)(addend); \
|
||||
(rh) = (BignumInt)(MUL_temp >> BIGNUM_INT_BITS); \
|
||||
(rl) = (BignumInt)(MUL_temp); \
|
||||
} while (0)
|
||||
|
||||
#define BignumMULADD2(rh, rl, a, b, addend1, addend2) do \
|
||||
{ \
|
||||
DEFINE_BIGNUMDBLINT; \
|
||||
BignumDblInt MUL_temp = (BignumInt)(a); \
|
||||
MUL_temp *= (BignumInt)(b); \
|
||||
MUL_temp += (BignumInt)(addend1); \
|
||||
MUL_temp += (BignumInt)(addend2); \
|
||||
(rh) = (BignumInt)(MUL_temp >> BIGNUM_INT_BITS); \
|
||||
(rl) = (BignumInt)(MUL_temp); \
|
||||
} while (0)
|
||||
|
||||
#endif /* DEFINE_BIGNUMDBLINT */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Data structures used inside bignum.c.
|
||||
*/
|
||||
|
||||
struct mp_int {
|
||||
size_t nw;
|
||||
BignumInt *w;
|
||||
};
|
||||
|
||||
struct MontyContext {
|
||||
/*
|
||||
* The actual modulus.
|
||||
*/
|
||||
mp_int *m;
|
||||
|
||||
/*
|
||||
* Montgomery multiplication works by selecting a value r > m,
|
||||
* coprime to m, which is really easy to divide by. In binary
|
||||
* arithmetic, that means making it a power of 2; in fact we make
|
||||
* it a whole number of BignumInt.
|
||||
*
|
||||
* We don't store r directly as an mp_int (there's no need). But
|
||||
* its value is 2^rbits; we also store rw = rbits/BIGNUM_INT_BITS
|
||||
* (the corresponding word offset within an mp_int).
|
||||
*
|
||||
* pw is the number of words needed to store an mp_int you're
|
||||
* doing reduction on: it has to be big enough to hold the sum of
|
||||
* an input value up to m^2 plus an extra addend up to m*r.
|
||||
*/
|
||||
size_t rbits, rw, pw;
|
||||
|
||||
/*
|
||||
* The key step in Montgomery reduction requires the inverse of -m
|
||||
* mod r.
|
||||
*/
|
||||
mp_int *minus_minv_mod_r;
|
||||
|
||||
/*
|
||||
* r^1, r^2 and r^3 mod m, which are used for various purposes.
|
||||
*
|
||||
* (Annoyingly, this is one of the rare cases where it would have
|
||||
* been nicer to have a Pascal-style 1-indexed array. I couldn't
|
||||
* _quite_ bring myself to put a gratuitous zero element in here.
|
||||
* So you just have to live with getting r^k by taking the [k-1]th
|
||||
* element of this array.)
|
||||
*/
|
||||
mp_int *powers_of_r_mod_m[3];
|
||||
|
||||
/*
|
||||
* Persistent scratch space from which monty_* functions can
|
||||
* allocate storage for intermediate values.
|
||||
*/
|
||||
mp_int *scratch;
|
||||
};
|
||||
|
||||
/* Functions shared between mpint.c and mpunsafe.c */
|
||||
mp_int *mp_make_sized(size_t nw);
|
Reference in New Issue
Block a user