^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* mpiutil.ac - Utility functions for MPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is part of GnuPG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * GnuPG is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * GnuPG is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "mpi-internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* Constants allocated right away at startup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static MPI constants[MPI_NUMBER_OF_CONSTANTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Initialize the MPI subsystem. This is called early and allows to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * do some initialization without taking care of threading issues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int __init mpi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) for (idx = 0; idx < MPI_NUMBER_OF_CONSTANTS; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) switch (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) case MPI_C_ZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) case MPI_C_ONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) value = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) case MPI_C_TWO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) value = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) case MPI_C_THREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) value = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) case MPI_C_FOUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) value = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) case MPI_C_EIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) value = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) pr_err("MPI: invalid mpi_const selector %d\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) constants[idx] = mpi_alloc_set_ui(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) constants[idx]->flags = (16|32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) postcore_initcall(mpi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Return a constant MPI descripbed by NO which is one of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * MPI_C_xxx macros. There is no need to copy this returned value; it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * may be used directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) MPI mpi_const(enum gcry_mpi_constants no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) pr_err("MPI: invalid mpi_const selector %d\n", no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (!constants[no])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) pr_err("MPI: MPI subsystem not initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return constants[no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) EXPORT_SYMBOL_GPL(mpi_const);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Note: It was a bad idea to use the number of limbs to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * because on a alpha the limbs are large but we normally need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * integers of n bits - So we should chnage this to bits (or bytes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * But mpi_alloc is used in a lot of places :-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MPI mpi_alloc(unsigned nlimbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MPI a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) a = kmalloc(sizeof *a, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (nlimbs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) a->d = mpi_alloc_limb_space(nlimbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!a->d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) kfree(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) a->d = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) a->alloced = nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) a->nlimbs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) a->sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) a->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) a->nbits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) EXPORT_SYMBOL_GPL(mpi_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) size_t len = nlimbs * sizeof(mpi_limb_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return kmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void mpi_free_limb_space(mpi_ptr_t a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) kfree_sensitive(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) mpi_free_limb_space(a->d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) a->d = ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) a->alloced = nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Resize the array of A to NLIMBS. the additional space is cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * (set to 0) [done by m_realloc()]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int mpi_resize(MPI a, unsigned nlimbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (nlimbs <= a->alloced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0; /* no need to do it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (a->d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) p = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) kfree_sensitive(a->d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) a->d = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) a->d = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!a->d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) a->alloced = nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) void mpi_clear(MPI a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (!a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) a->nlimbs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) a->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) EXPORT_SYMBOL_GPL(mpi_clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) void mpi_free(MPI a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (a->flags & 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) kfree_sensitive(a->d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mpi_free_limb_space(a->d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (a->flags & ~7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) pr_info("invalid flag value in mpi\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) kfree(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL_GPL(mpi_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Note: This copy function should not interpret the MPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * but copy it transparently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) MPI mpi_copy(MPI a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) MPI b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) b = mpi_alloc(a->nlimbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) b->nlimbs = a->nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) b->sign = a->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) b->flags = a->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) for (i = 0; i < b->nlimbs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) b->d[i] = a->d[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) b = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * This function allocates an MPI which is optimized to hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * a value as large as the one given in the argument and allocates it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * with the same flags as A.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) MPI mpi_alloc_like(MPI a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) MPI b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) b = mpi_alloc(a->nlimbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) b->nlimbs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) b->sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) b->flags = a->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) b = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* Set U into W and release U. If W is NULL only U will be released. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) void mpi_snatch(MPI w, MPI u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (w) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mpi_assign_limb_space(w, u->d, u->alloced);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) w->nlimbs = u->nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) w->sign = u->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) w->flags = u->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u->alloced = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u->nlimbs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u->d = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) mpi_free(u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) MPI mpi_set(MPI w, MPI u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mpi_ptr_t wp, up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mpi_size_t usize = u->nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int usign = u->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) w = mpi_alloc(mpi_get_nlimbs(u));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) RESIZE_IF_NEEDED(w, usize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) wp = w->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) up = u->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) MPN_COPY(wp, up, usize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) w->nlimbs = usize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) w->flags = u->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) w->flags &= ~(16|32); /* Reset the immutable and constant flags. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) w->sign = usign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) EXPORT_SYMBOL_GPL(mpi_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) MPI mpi_set_ui(MPI w, unsigned long u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) w = mpi_alloc(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* FIXME: If U is 0 we have no need to resize and thus possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * allocating the the limbs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) RESIZE_IF_NEEDED(w, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) w->d[0] = u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) w->nlimbs = u ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) w->sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) w->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) EXPORT_SYMBOL_GPL(mpi_set_ui);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) MPI mpi_alloc_set_ui(unsigned long u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) MPI w = mpi_alloc(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) w->d[0] = u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) w->nlimbs = u ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) w->sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * Swap the value of A and B, when SWAP is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * Leave the value when SWAP is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * This implementation should be constant-time regardless of SWAP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) void mpi_swap_cond(MPI a, MPI b, unsigned long swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) mpi_size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mpi_size_t nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) mpi_limb_t mask = ((mpi_limb_t)0) - swap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) mpi_limb_t x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (a->alloced > b->alloced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) nlimbs = b->alloced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) nlimbs = a->alloced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (a->nlimbs > nlimbs || b->nlimbs > nlimbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) for (i = 0; i < nlimbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) x = mask & (a->d[i] ^ b->d[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) a->d[i] = a->d[i] ^ x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) b->d[i] = b->d[i] ^ x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) x = mask & (a->nlimbs ^ b->nlimbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) a->nlimbs = a->nlimbs ^ x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) b->nlimbs = b->nlimbs ^ x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) x = mask & (a->sign ^ b->sign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) a->sign = a->sign ^ x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) b->sign = b->sign ^ x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) MODULE_DESCRIPTION("Multiprecision maths library");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) MODULE_LICENSE("GPL");