.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* mpi.h - Multi Precision Integers |
---|
2 | 3 | * Copyright (C) 1994, 1996, 1998, 1999, |
---|
3 | 4 | * 2000, 2001 Free Software Foundation, Inc. |
---|
4 | 5 | * |
---|
5 | 6 | * This file is part of GNUPG. |
---|
6 | | - * |
---|
7 | | - * GNUPG is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License as published by |
---|
9 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
10 | | - * (at your option) any later version. |
---|
11 | | - * |
---|
12 | | - * GNUPG is distributed in the hope that it will be useful, |
---|
13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | | - * GNU General Public License for more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License |
---|
18 | | - * along with this program; if not, write to the Free Software |
---|
19 | | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
---|
20 | 7 | * |
---|
21 | 8 | * Note: This code is heavily based on the GNU MP Library. |
---|
22 | 9 | * Actually it's the same code with only minor changes in the |
---|
.. | .. |
---|
53 | 40 | typedef struct gcry_mpi *MPI; |
---|
54 | 41 | |
---|
55 | 42 | #define mpi_get_nlimbs(a) ((a)->nlimbs) |
---|
| 43 | +#define mpi_has_sign(a) ((a)->sign) |
---|
56 | 44 | |
---|
57 | 45 | /*-- mpiutil.c --*/ |
---|
58 | 46 | MPI mpi_alloc(unsigned nlimbs); |
---|
| 47 | +void mpi_clear(MPI a); |
---|
59 | 48 | void mpi_free(MPI a); |
---|
60 | 49 | int mpi_resize(MPI a, unsigned nlimbs); |
---|
61 | 50 | |
---|
| 51 | +static inline MPI mpi_new(unsigned int nbits) |
---|
| 52 | +{ |
---|
| 53 | + return mpi_alloc((nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB); |
---|
| 54 | +} |
---|
| 55 | + |
---|
| 56 | +MPI mpi_copy(MPI a); |
---|
| 57 | +MPI mpi_alloc_like(MPI a); |
---|
| 58 | +void mpi_snatch(MPI w, MPI u); |
---|
| 59 | +MPI mpi_set(MPI w, MPI u); |
---|
| 60 | +MPI mpi_set_ui(MPI w, unsigned long u); |
---|
| 61 | +MPI mpi_alloc_set_ui(unsigned long u); |
---|
| 62 | +void mpi_swap_cond(MPI a, MPI b, unsigned long swap); |
---|
| 63 | + |
---|
| 64 | +/* Constants used to return constant MPIs. See mpi_init if you |
---|
| 65 | + * want to add more constants. |
---|
| 66 | + */ |
---|
| 67 | +#define MPI_NUMBER_OF_CONSTANTS 6 |
---|
| 68 | +enum gcry_mpi_constants { |
---|
| 69 | + MPI_C_ZERO, |
---|
| 70 | + MPI_C_ONE, |
---|
| 71 | + MPI_C_TWO, |
---|
| 72 | + MPI_C_THREE, |
---|
| 73 | + MPI_C_FOUR, |
---|
| 74 | + MPI_C_EIGHT |
---|
| 75 | +}; |
---|
| 76 | + |
---|
| 77 | +MPI mpi_const(enum gcry_mpi_constants no); |
---|
| 78 | + |
---|
62 | 79 | /*-- mpicoder.c --*/ |
---|
| 80 | + |
---|
| 81 | +/* Different formats of external big integer representation. */ |
---|
| 82 | +enum gcry_mpi_format { |
---|
| 83 | + GCRYMPI_FMT_NONE = 0, |
---|
| 84 | + GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */ |
---|
| 85 | + GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */ |
---|
| 86 | + GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */ |
---|
| 87 | + GCRYMPI_FMT_HEX = 4, /* Hex format. */ |
---|
| 88 | + GCRYMPI_FMT_USG = 5, /* Like STD but unsigned. */ |
---|
| 89 | + GCRYMPI_FMT_OPAQUE = 8 /* Opaque format (some functions only). */ |
---|
| 90 | +}; |
---|
| 91 | + |
---|
63 | 92 | MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes); |
---|
64 | 93 | MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread); |
---|
| 94 | +int mpi_fromstr(MPI val, const char *str); |
---|
| 95 | +MPI mpi_scanval(const char *string); |
---|
65 | 96 | MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int len); |
---|
66 | 97 | void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign); |
---|
67 | 98 | int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes, |
---|
68 | 99 | int *sign); |
---|
69 | 100 | int mpi_write_to_sgl(MPI a, struct scatterlist *sg, unsigned nbytes, |
---|
70 | 101 | int *sign); |
---|
| 102 | +int mpi_print(enum gcry_mpi_format format, unsigned char *buffer, |
---|
| 103 | + size_t buflen, size_t *nwritten, MPI a); |
---|
| 104 | + |
---|
| 105 | +/*-- mpi-mod.c --*/ |
---|
| 106 | +void mpi_mod(MPI rem, MPI dividend, MPI divisor); |
---|
| 107 | + |
---|
| 108 | +/* Context used with Barrett reduction. */ |
---|
| 109 | +struct barrett_ctx_s; |
---|
| 110 | +typedef struct barrett_ctx_s *mpi_barrett_t; |
---|
| 111 | + |
---|
| 112 | +mpi_barrett_t mpi_barrett_init(MPI m, int copy); |
---|
| 113 | +void mpi_barrett_free(mpi_barrett_t ctx); |
---|
| 114 | +void mpi_mod_barrett(MPI r, MPI x, mpi_barrett_t ctx); |
---|
| 115 | +void mpi_mul_barrett(MPI w, MPI u, MPI v, mpi_barrett_t ctx); |
---|
71 | 116 | |
---|
72 | 117 | /*-- mpi-pow.c --*/ |
---|
73 | 118 | int mpi_powm(MPI res, MPI base, MPI exp, MPI mod); |
---|
.. | .. |
---|
75 | 120 | /*-- mpi-cmp.c --*/ |
---|
76 | 121 | int mpi_cmp_ui(MPI u, ulong v); |
---|
77 | 122 | int mpi_cmp(MPI u, MPI v); |
---|
| 123 | +int mpi_cmpabs(MPI u, MPI v); |
---|
| 124 | + |
---|
| 125 | +/*-- mpi-sub-ui.c --*/ |
---|
| 126 | +int mpi_sub_ui(MPI w, MPI u, unsigned long vval); |
---|
78 | 127 | |
---|
79 | 128 | /*-- mpi-bit.c --*/ |
---|
80 | 129 | void mpi_normalize(MPI a); |
---|
81 | 130 | unsigned mpi_get_nbits(MPI a); |
---|
| 131 | +int mpi_test_bit(MPI a, unsigned int n); |
---|
| 132 | +void mpi_set_bit(MPI a, unsigned int n); |
---|
| 133 | +void mpi_set_highbit(MPI a, unsigned int n); |
---|
| 134 | +void mpi_clear_highbit(MPI a, unsigned int n); |
---|
| 135 | +void mpi_clear_bit(MPI a, unsigned int n); |
---|
| 136 | +void mpi_rshift_limbs(MPI a, unsigned int count); |
---|
| 137 | +void mpi_rshift(MPI x, MPI a, unsigned int n); |
---|
| 138 | +void mpi_lshift_limbs(MPI a, unsigned int count); |
---|
| 139 | +void mpi_lshift(MPI x, MPI a, unsigned int n); |
---|
| 140 | + |
---|
| 141 | +/*-- mpi-add.c --*/ |
---|
| 142 | +void mpi_add_ui(MPI w, MPI u, unsigned long v); |
---|
| 143 | +void mpi_add(MPI w, MPI u, MPI v); |
---|
| 144 | +void mpi_sub(MPI w, MPI u, MPI v); |
---|
| 145 | +void mpi_addm(MPI w, MPI u, MPI v, MPI m); |
---|
| 146 | +void mpi_subm(MPI w, MPI u, MPI v, MPI m); |
---|
| 147 | + |
---|
| 148 | +/*-- mpi-mul.c --*/ |
---|
| 149 | +void mpi_mul(MPI w, MPI u, MPI v); |
---|
| 150 | +void mpi_mulm(MPI w, MPI u, MPI v, MPI m); |
---|
| 151 | + |
---|
| 152 | +/*-- mpi-div.c --*/ |
---|
| 153 | +void mpi_tdiv_r(MPI rem, MPI num, MPI den); |
---|
| 154 | +void mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor); |
---|
| 155 | +void mpi_fdiv_q(MPI quot, MPI dividend, MPI divisor); |
---|
| 156 | + |
---|
| 157 | +/*-- mpi-inv.c --*/ |
---|
| 158 | +int mpi_invm(MPI x, MPI a, MPI n); |
---|
| 159 | + |
---|
| 160 | +/*-- ec.c --*/ |
---|
| 161 | + |
---|
| 162 | +/* Object to represent a point in projective coordinates */ |
---|
| 163 | +struct gcry_mpi_point { |
---|
| 164 | + MPI x; |
---|
| 165 | + MPI y; |
---|
| 166 | + MPI z; |
---|
| 167 | +}; |
---|
| 168 | + |
---|
| 169 | +typedef struct gcry_mpi_point *MPI_POINT; |
---|
| 170 | + |
---|
| 171 | +/* Models describing an elliptic curve */ |
---|
| 172 | +enum gcry_mpi_ec_models { |
---|
| 173 | + /* The Short Weierstrass equation is |
---|
| 174 | + * y^2 = x^3 + ax + b |
---|
| 175 | + */ |
---|
| 176 | + MPI_EC_WEIERSTRASS = 0, |
---|
| 177 | + /* The Montgomery equation is |
---|
| 178 | + * by^2 = x^3 + ax^2 + x |
---|
| 179 | + */ |
---|
| 180 | + MPI_EC_MONTGOMERY, |
---|
| 181 | + /* The Twisted Edwards equation is |
---|
| 182 | + * ax^2 + y^2 = 1 + bx^2y^2 |
---|
| 183 | + * Note that we use 'b' instead of the commonly used 'd'. |
---|
| 184 | + */ |
---|
| 185 | + MPI_EC_EDWARDS |
---|
| 186 | +}; |
---|
| 187 | + |
---|
| 188 | +/* Dialects used with elliptic curves */ |
---|
| 189 | +enum ecc_dialects { |
---|
| 190 | + ECC_DIALECT_STANDARD = 0, |
---|
| 191 | + ECC_DIALECT_ED25519, |
---|
| 192 | + ECC_DIALECT_SAFECURVE |
---|
| 193 | +}; |
---|
| 194 | + |
---|
| 195 | +/* This context is used with all our EC functions. */ |
---|
| 196 | +struct mpi_ec_ctx { |
---|
| 197 | + enum gcry_mpi_ec_models model; /* The model describing this curve. */ |
---|
| 198 | + enum ecc_dialects dialect; /* The ECC dialect used with the curve. */ |
---|
| 199 | + int flags; /* Public key flags (not always used). */ |
---|
| 200 | + unsigned int nbits; /* Number of bits. */ |
---|
| 201 | + |
---|
| 202 | + /* Domain parameters. Note that they may not all be set and if set |
---|
| 203 | + * the MPIs may be flaged as constant. |
---|
| 204 | + */ |
---|
| 205 | + MPI p; /* Prime specifying the field GF(p). */ |
---|
| 206 | + MPI a; /* First coefficient of the Weierstrass equation. */ |
---|
| 207 | + MPI b; /* Second coefficient of the Weierstrass equation. */ |
---|
| 208 | + MPI_POINT G; /* Base point (generator). */ |
---|
| 209 | + MPI n; /* Order of G. */ |
---|
| 210 | + unsigned int h; /* Cofactor. */ |
---|
| 211 | + |
---|
| 212 | + /* The actual key. May not be set. */ |
---|
| 213 | + MPI_POINT Q; /* Public key. */ |
---|
| 214 | + MPI d; /* Private key. */ |
---|
| 215 | + |
---|
| 216 | + const char *name; /* Name of the curve. */ |
---|
| 217 | + |
---|
| 218 | + /* This structure is private to mpi/ec.c! */ |
---|
| 219 | + struct { |
---|
| 220 | + struct { |
---|
| 221 | + unsigned int a_is_pminus3:1; |
---|
| 222 | + unsigned int two_inv_p:1; |
---|
| 223 | + } valid; /* Flags to help setting the helper vars below. */ |
---|
| 224 | + |
---|
| 225 | + int a_is_pminus3; /* True if A = P - 3. */ |
---|
| 226 | + |
---|
| 227 | + MPI two_inv_p; |
---|
| 228 | + |
---|
| 229 | + mpi_barrett_t p_barrett; |
---|
| 230 | + |
---|
| 231 | + /* Scratch variables. */ |
---|
| 232 | + MPI scratch[11]; |
---|
| 233 | + |
---|
| 234 | + /* Helper for fast reduction. */ |
---|
| 235 | + /* int nist_nbits; /\* If this is a NIST curve, the # of bits. *\/ */ |
---|
| 236 | + /* MPI s[10]; */ |
---|
| 237 | + /* MPI c; */ |
---|
| 238 | + } t; |
---|
| 239 | + |
---|
| 240 | + /* Curve specific computation routines for the field. */ |
---|
| 241 | + void (*addm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx); |
---|
| 242 | + void (*subm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ec); |
---|
| 243 | + void (*mulm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx); |
---|
| 244 | + void (*pow2)(MPI w, const MPI b, struct mpi_ec_ctx *ctx); |
---|
| 245 | + void (*mul2)(MPI w, MPI u, struct mpi_ec_ctx *ctx); |
---|
| 246 | +}; |
---|
| 247 | + |
---|
| 248 | +void mpi_ec_init(struct mpi_ec_ctx *ctx, enum gcry_mpi_ec_models model, |
---|
| 249 | + enum ecc_dialects dialect, |
---|
| 250 | + int flags, MPI p, MPI a, MPI b); |
---|
| 251 | +void mpi_ec_deinit(struct mpi_ec_ctx *ctx); |
---|
| 252 | +MPI_POINT mpi_point_new(unsigned int nbits); |
---|
| 253 | +void mpi_point_release(MPI_POINT p); |
---|
| 254 | +void mpi_point_init(MPI_POINT p); |
---|
| 255 | +void mpi_point_free_parts(MPI_POINT p); |
---|
| 256 | +int mpi_ec_get_affine(MPI x, MPI y, MPI_POINT point, struct mpi_ec_ctx *ctx); |
---|
| 257 | +void mpi_ec_add_points(MPI_POINT result, |
---|
| 258 | + MPI_POINT p1, MPI_POINT p2, |
---|
| 259 | + struct mpi_ec_ctx *ctx); |
---|
| 260 | +void mpi_ec_mul_point(MPI_POINT result, |
---|
| 261 | + MPI scalar, MPI_POINT point, |
---|
| 262 | + struct mpi_ec_ctx *ctx); |
---|
| 263 | +int mpi_ec_curve_point(MPI_POINT point, struct mpi_ec_ctx *ctx); |
---|
82 | 264 | |
---|
83 | 265 | /* inline functions */ |
---|
84 | 266 | |
---|