162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* mpihelp-lshift.c - MPI helper functions 362306a36Sopenharmony_ci * Copyright (C) 1994, 1996, 1998, 2001 Free Software Foundation, Inc. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This file is part of GnuPG. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Note: This code is heavily based on the GNU MP Library. 862306a36Sopenharmony_ci * Actually it's the same code with only minor changes in the 962306a36Sopenharmony_ci * way the data is stored; this is to support the abstraction 1062306a36Sopenharmony_ci * of an optional secure memory allocation which may be used 1162306a36Sopenharmony_ci * to avoid revealing of sensitive data due to paging etc. 1262306a36Sopenharmony_ci * The GNU MP Library itself is published under the LGPL; 1362306a36Sopenharmony_ci * however I decided to publish this code under the plain GPL. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "mpi-internal.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left 1962306a36Sopenharmony_ci * and store the USIZE least significant digits of the result at WP. 2062306a36Sopenharmony_ci * Return the bits shifted out from the most significant digit. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Argument constraints: 2362306a36Sopenharmony_ci * 1. 0 < CNT < BITS_PER_MP_LIMB 2462306a36Sopenharmony_ci * 2. If the result is to be written over the input, WP must be >= UP. 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cimpi_limb_t 2862306a36Sopenharmony_cimpihelp_lshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned int cnt) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci mpi_limb_t high_limb, low_limb; 3162306a36Sopenharmony_ci unsigned sh_1, sh_2; 3262306a36Sopenharmony_ci mpi_size_t i; 3362306a36Sopenharmony_ci mpi_limb_t retval; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci sh_1 = cnt; 3662306a36Sopenharmony_ci wp += 1; 3762306a36Sopenharmony_ci sh_2 = BITS_PER_MPI_LIMB - sh_1; 3862306a36Sopenharmony_ci i = usize - 1; 3962306a36Sopenharmony_ci low_limb = up[i]; 4062306a36Sopenharmony_ci retval = low_limb >> sh_2; 4162306a36Sopenharmony_ci high_limb = low_limb; 4262306a36Sopenharmony_ci while (--i >= 0) { 4362306a36Sopenharmony_ci low_limb = up[i]; 4462306a36Sopenharmony_ci wp[i] = (high_limb << sh_1) | (low_limb >> sh_2); 4562306a36Sopenharmony_ci high_limb = low_limb; 4662306a36Sopenharmony_ci } 4762306a36Sopenharmony_ci wp[i] = high_limb << sh_1; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci return retval; 5062306a36Sopenharmony_ci} 51