0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef G10_MPI_H
0018 #define G10_MPI_H
0019
0020 #include <linux/types.h>
0021 #include <linux/scatterlist.h>
0022
0023 #define BYTES_PER_MPI_LIMB (BITS_PER_LONG / 8)
0024 #define BITS_PER_MPI_LIMB BITS_PER_LONG
0025
0026 typedef unsigned long int mpi_limb_t;
0027 typedef signed long int mpi_limb_signed_t;
0028
0029 struct gcry_mpi {
0030 int alloced;
0031 int nlimbs;
0032 int nbits;
0033 int sign;
0034 unsigned flags;
0035
0036
0037 mpi_limb_t *d;
0038 };
0039
0040 typedef struct gcry_mpi *MPI;
0041
0042 #define mpi_get_nlimbs(a) ((a)->nlimbs)
0043 #define mpi_has_sign(a) ((a)->sign)
0044
0045
0046 MPI mpi_alloc(unsigned nlimbs);
0047 void mpi_clear(MPI a);
0048 void mpi_free(MPI a);
0049 int mpi_resize(MPI a, unsigned nlimbs);
0050
0051 static inline MPI mpi_new(unsigned int nbits)
0052 {
0053 return mpi_alloc((nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB);
0054 }
0055
0056 MPI mpi_copy(MPI a);
0057 MPI mpi_alloc_like(MPI a);
0058 void mpi_snatch(MPI w, MPI u);
0059 MPI mpi_set(MPI w, MPI u);
0060 MPI mpi_set_ui(MPI w, unsigned long u);
0061 MPI mpi_alloc_set_ui(unsigned long u);
0062 void mpi_swap_cond(MPI a, MPI b, unsigned long swap);
0063
0064
0065
0066
0067 #define MPI_NUMBER_OF_CONSTANTS 6
0068 enum gcry_mpi_constants {
0069 MPI_C_ZERO,
0070 MPI_C_ONE,
0071 MPI_C_TWO,
0072 MPI_C_THREE,
0073 MPI_C_FOUR,
0074 MPI_C_EIGHT
0075 };
0076
0077 MPI mpi_const(enum gcry_mpi_constants no);
0078
0079
0080
0081
0082 enum gcry_mpi_format {
0083 GCRYMPI_FMT_NONE = 0,
0084 GCRYMPI_FMT_STD = 1,
0085 GCRYMPI_FMT_PGP = 2,
0086 GCRYMPI_FMT_SSH = 3,
0087 GCRYMPI_FMT_HEX = 4,
0088 GCRYMPI_FMT_USG = 5,
0089 GCRYMPI_FMT_OPAQUE = 8
0090 };
0091
0092 MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes);
0093 MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
0094 int mpi_fromstr(MPI val, const char *str);
0095 MPI mpi_scanval(const char *string);
0096 MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int len);
0097 void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign);
0098 int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
0099 int *sign);
0100 int mpi_write_to_sgl(MPI a, struct scatterlist *sg, unsigned nbytes,
0101 int *sign);
0102 int mpi_print(enum gcry_mpi_format format, unsigned char *buffer,
0103 size_t buflen, size_t *nwritten, MPI a);
0104
0105
0106 void mpi_mod(MPI rem, MPI dividend, MPI divisor);
0107
0108
0109 struct barrett_ctx_s;
0110 typedef struct barrett_ctx_s *mpi_barrett_t;
0111
0112 mpi_barrett_t mpi_barrett_init(MPI m, int copy);
0113 void mpi_barrett_free(mpi_barrett_t ctx);
0114 void mpi_mod_barrett(MPI r, MPI x, mpi_barrett_t ctx);
0115 void mpi_mul_barrett(MPI w, MPI u, MPI v, mpi_barrett_t ctx);
0116
0117
0118 int mpi_powm(MPI res, MPI base, MPI exp, MPI mod);
0119
0120
0121 int mpi_cmp_ui(MPI u, ulong v);
0122 int mpi_cmp(MPI u, MPI v);
0123 int mpi_cmpabs(MPI u, MPI v);
0124
0125
0126 int mpi_sub_ui(MPI w, MPI u, unsigned long vval);
0127
0128
0129 void mpi_normalize(MPI a);
0130 unsigned mpi_get_nbits(MPI a);
0131 int mpi_test_bit(MPI a, unsigned int n);
0132 void mpi_set_bit(MPI a, unsigned int n);
0133 void mpi_set_highbit(MPI a, unsigned int n);
0134 void mpi_clear_highbit(MPI a, unsigned int n);
0135 void mpi_clear_bit(MPI a, unsigned int n);
0136 void mpi_rshift_limbs(MPI a, unsigned int count);
0137 void mpi_rshift(MPI x, MPI a, unsigned int n);
0138 void mpi_lshift_limbs(MPI a, unsigned int count);
0139 void mpi_lshift(MPI x, MPI a, unsigned int n);
0140
0141
0142 void mpi_add_ui(MPI w, MPI u, unsigned long v);
0143 void mpi_add(MPI w, MPI u, MPI v);
0144 void mpi_sub(MPI w, MPI u, MPI v);
0145 void mpi_addm(MPI w, MPI u, MPI v, MPI m);
0146 void mpi_subm(MPI w, MPI u, MPI v, MPI m);
0147
0148
0149 void mpi_mul(MPI w, MPI u, MPI v);
0150 void mpi_mulm(MPI w, MPI u, MPI v, MPI m);
0151
0152
0153 void mpi_tdiv_r(MPI rem, MPI num, MPI den);
0154 void mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor);
0155 void mpi_fdiv_q(MPI quot, MPI dividend, MPI divisor);
0156
0157
0158 int mpi_invm(MPI x, MPI a, MPI n);
0159
0160
0161
0162
0163 struct gcry_mpi_point {
0164 MPI x;
0165 MPI y;
0166 MPI z;
0167 };
0168
0169 typedef struct gcry_mpi_point *MPI_POINT;
0170
0171
0172 enum gcry_mpi_ec_models {
0173
0174
0175
0176 MPI_EC_WEIERSTRASS = 0,
0177
0178
0179
0180 MPI_EC_MONTGOMERY,
0181
0182
0183
0184
0185 MPI_EC_EDWARDS
0186 };
0187
0188
0189 enum ecc_dialects {
0190 ECC_DIALECT_STANDARD = 0,
0191 ECC_DIALECT_ED25519,
0192 ECC_DIALECT_SAFECURVE
0193 };
0194
0195
0196 struct mpi_ec_ctx {
0197 enum gcry_mpi_ec_models model;
0198 enum ecc_dialects dialect;
0199 int flags;
0200 unsigned int nbits;
0201
0202
0203
0204
0205 MPI p;
0206 MPI a;
0207 MPI b;
0208 MPI_POINT G;
0209 MPI n;
0210 unsigned int h;
0211
0212
0213 MPI_POINT Q;
0214 MPI d;
0215
0216 const char *name;
0217
0218
0219 struct {
0220 struct {
0221 unsigned int a_is_pminus3:1;
0222 unsigned int two_inv_p:1;
0223 } valid;
0224
0225 int a_is_pminus3;
0226
0227 MPI two_inv_p;
0228
0229 mpi_barrett_t p_barrett;
0230
0231
0232 MPI scratch[11];
0233
0234
0235
0236
0237
0238 } t;
0239
0240
0241 void (*addm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx);
0242 void (*subm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ec);
0243 void (*mulm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx);
0244 void (*pow2)(MPI w, const MPI b, struct mpi_ec_ctx *ctx);
0245 void (*mul2)(MPI w, MPI u, struct mpi_ec_ctx *ctx);
0246 };
0247
0248 void mpi_ec_init(struct mpi_ec_ctx *ctx, enum gcry_mpi_ec_models model,
0249 enum ecc_dialects dialect,
0250 int flags, MPI p, MPI a, MPI b);
0251 void mpi_ec_deinit(struct mpi_ec_ctx *ctx);
0252 MPI_POINT mpi_point_new(unsigned int nbits);
0253 void mpi_point_release(MPI_POINT p);
0254 void mpi_point_init(MPI_POINT p);
0255 void mpi_point_free_parts(MPI_POINT p);
0256 int mpi_ec_get_affine(MPI x, MPI y, MPI_POINT point, struct mpi_ec_ctx *ctx);
0257 void mpi_ec_add_points(MPI_POINT result,
0258 MPI_POINT p1, MPI_POINT p2,
0259 struct mpi_ec_ctx *ctx);
0260 void mpi_ec_mul_point(MPI_POINT result,
0261 MPI scalar, MPI_POINT point,
0262 struct mpi_ec_ctx *ctx);
0263 int mpi_ec_curve_point(MPI_POINT point, struct mpi_ec_ctx *ctx);
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 static inline unsigned int mpi_get_size(MPI a)
0275 {
0276 return a->nlimbs * BYTES_PER_MPI_LIMB;
0277 }
0278 #endif