initially checkin
[gnupg.git] / mpi / mpih-shift.c
1 /* mpihelp-shift.c  -  MPI helper functions
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * G10 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "mpi-internal.h"
25
26 /* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
27  * and store the USIZE least significant digits of the result at WP.
28  * Return the bits shifted out from the most significant digit.
29  *
30  * Argument constraints:
31  * 1. 0 < CNT < BITS_PER_MP_LIMB
32  * 2. If the result is to be written over the input, WP must be >= UP.
33  */
34
35 mpi_limb_t
36 mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
37                                             unsigned int cnt)
38 {
39     mpi_limb_t high_limb, low_limb;
40     unsigned sh_1, sh_2;
41     mpi_size_t i;
42     mpi_limb_t retval;
43
44     sh_1 = cnt;
45     wp += 1;
46     sh_2 = BITS_PER_MPI_LIMB - sh_1;
47     i = usize - 1;
48     low_limb = up[i];
49     retval = low_limb >> sh_2;
50     high_limb = low_limb;
51     while( --i >= 0 ) {
52         low_limb = up[i];
53         wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
54         high_limb = low_limb;
55     }
56     wp[i] = high_limb << sh_1;
57
58     return retval;
59 }
60
61
62 /* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
63  * and store the USIZE least significant limbs of the result at WP.
64  * The bits shifted out to the right are returned.
65  *
66  * Argument constraints:
67  * 1. 0 < CNT < BITS_PER_MP_LIMB
68  * 2. If the result is to be written over the input, WP must be <= UP.
69  */
70
71 mpi_limb_t
72 mpihelp_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
73 {
74     mpi_limb_t high_limb, low_limb;
75     unsigned sh_1, sh_2;
76     mpi_size_t i;
77     mpi_limb_t retval;
78
79     sh_1 = cnt;
80     wp -= 1;
81     sh_2 = BITS_PER_MPI_LIMB - sh_1;
82     high_limb = up[0];
83     retval = high_limb << sh_2;
84     low_limb = high_limb;
85     for( i=1; i < usize; i++) {
86         high_limb = up[i];
87         wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
88         low_limb = high_limb;
89     }
90     wp[i] = low_limb >> sh_1;
91
92     return retval;
93 }
94