-
+ F8B433355F471B6EA164813B4927B36D389177AF169F39E25C04B3A043DE367A88B8F07A6FE6EB92C851B9E20FA1B8EE0D1EC25E53A9F51477914F1A38EC1D5B
eucrypt/mpi/mpi-bit.c
(0 . 0)(1 . 258)
2947 /* mpi-bit.c - MPI bit level fucntions
2948 * Modified by No Such Labs. (C) 2015. See README.
2949 *
2950 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
2951 * SHA256(gnupg-1.4.10.tar.gz):
2952 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
2953 * (C) 1994-2005 Free Software Foundation, Inc.
2954 *
2955 * This program is free software: you can redistribute it and/or modify
2956 * it under the terms of the GNU General Public License as published by
2957 * the Free Software Foundation, either version 3 of the License, or
2958 * (at your option) any later version.
2959 *
2960 * This program is distributed in the hope that it will be useful,
2961 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2962 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2963 * GNU General Public License for more details.
2964 *
2965 * You should have received a copy of the GNU General Public License
2966 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2967 */
2968
2969 #include <stdio.h>
2970 #include <stdlib.h>
2971 #include <assert.h>
2972
2973 #include "knobs.h"
2974 #include "mpi-internal.h"
2975 #include "longlong.h"
2976
2977
2978 #ifdef MPI_INTERNAL_NEED_CLZ_TAB
2979 #ifdef __STDC__
2980 const
2981 #endif
2982 unsigned char
2983 __clz_tab[] =
2984 {
2985 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
2986 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
2987 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
2988 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
2989 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
2990 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
2991 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
2992 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
2993 };
2994 #endif
2995
2996
2997 #define A_LIMB_1 ((mpi_limb_t)1)
2998
2999
3000 /****************
3001 * Sometimes we have MSL (most significant limbs) which are 0;
3002 * this is for some reasons not good, so this function removes them.
3003 */
3004 void
3005 mpi_normalize( MPI a )
3006 {
3007 if( mpi_is_opaque (a) )
3008 return;
3009
3010 for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
3011 ;
3012 }
3013
3014
3015
3016 /****************
3017 * Return the number of bits in A.
3018 */
3019 unsigned
3020 mpi_get_nbits( MPI a )
3021 {
3022 unsigned n;
3023
3024 mpi_normalize( a );
3025 if( a->nlimbs ) {
3026 mpi_limb_t alimb = a->d[a->nlimbs-1];
3027 if( alimb )
3028 count_leading_zeros( n, alimb );
3029 else
3030 n = BITS_PER_MPI_LIMB;
3031 n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
3032 }
3033 else
3034 n = 0;
3035 return n;
3036 }
3037
3038
3039 /****************
3040 * Test whether bit N is set.
3041 */
3042 int
3043 mpi_test_bit( MPI a, unsigned n )
3044 {
3045 unsigned limbno, bitno;
3046 mpi_limb_t limb;
3047
3048 limbno = n / BITS_PER_MPI_LIMB;
3049 bitno = n % BITS_PER_MPI_LIMB;
3050
3051 if( limbno >= a->nlimbs )
3052 return 0; /* too far left: this is a 0 */
3053 limb = a->d[limbno];
3054 return (limb & (A_LIMB_1 << bitno))? 1: 0;
3055 }
3056
3057
3058 /****************
3059 * Set bit N of A.
3060 */
3061 void
3062 mpi_set_bit( MPI a, unsigned n )
3063 {
3064 unsigned limbno, bitno;
3065
3066 limbno = n / BITS_PER_MPI_LIMB;
3067 bitno = n % BITS_PER_MPI_LIMB;
3068
3069 if( limbno >= a->nlimbs ) { /* resize */
3070 if( a->alloced >= limbno )
3071 mpi_resize(a, limbno+1 );
3072 a->nlimbs = limbno+1;
3073 }
3074 a->d[limbno] |= (A_LIMB_1<<bitno);
3075 }
3076
3077 /****************
3078 * Set bit N of A. and clear all bits above
3079 */
3080 void
3081 mpi_set_highbit( MPI a, unsigned n )
3082 {
3083 unsigned limbno, bitno;
3084
3085 limbno = n / BITS_PER_MPI_LIMB;
3086 bitno = n % BITS_PER_MPI_LIMB;
3087
3088 if( limbno >= a->nlimbs ) { /* resize */
3089 if( a->alloced >= limbno )
3090 mpi_resize(a, limbno+1 );
3091 a->nlimbs = limbno+1;
3092 }
3093 a->d[limbno] |= (A_LIMB_1<<bitno);
3094 for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
3095 a->d[limbno] &= ~(A_LIMB_1 << bitno);
3096 a->nlimbs = limbno+1;
3097 }
3098
3099 /****************
3100 * clear bit N of A and all bits above
3101 */
3102 void
3103 mpi_clear_highbit( MPI a, unsigned n )
3104 {
3105 unsigned limbno, bitno;
3106
3107 limbno = n / BITS_PER_MPI_LIMB;
3108 bitno = n % BITS_PER_MPI_LIMB;
3109
3110 if( limbno >= a->nlimbs )
3111 return; /* not allocated, so need to clear bits :-) */
3112
3113 for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
3114 a->d[limbno] &= ~(A_LIMB_1 << bitno);
3115 a->nlimbs = limbno+1;
3116 }
3117
3118 /****************
3119 * Clear bit N of A.
3120 */
3121 void
3122 mpi_clear_bit( MPI a, unsigned n )
3123 {
3124 unsigned limbno, bitno;
3125
3126 limbno = n / BITS_PER_MPI_LIMB;
3127 bitno = n % BITS_PER_MPI_LIMB;
3128
3129 if( limbno >= a->nlimbs )
3130 return; /* don't need to clear this bit, it's to far to left */
3131 a->d[limbno] &= ~(A_LIMB_1 << bitno);
3132 }
3133
3134
3135 /****************
3136 * Shift A by N bits to the right
3137 * FIXME: should use alloc_limb if X and A are same.
3138 */
3139 void
3140 mpi_rshift( MPI x, MPI a, unsigned n )
3141 {
3142 mpi_ptr_t xp;
3143 mpi_size_t xsize;
3144
3145 xsize = a->nlimbs;
3146 x->sign = a->sign;
3147 RESIZE_IF_NEEDED(x, xsize);
3148 xp = x->d;
3149
3150 if( xsize ) {
3151 mpihelp_rshift( xp, a->d, xsize, n);
3152 MPN_NORMALIZE( xp, xsize);
3153 }
3154 x->nlimbs = xsize;
3155 }
3156
3157
3158 /****************
3159 * Shift A by COUNT limbs to the left
3160 * This is used only within the MPI library
3161 */
3162 void
3163 mpi_lshift_limbs( MPI a, unsigned int count )
3164 {
3165 mpi_ptr_t ap = a->d;
3166 int n = a->nlimbs;
3167 int i;
3168
3169 if( !count || !n )
3170 return;
3171
3172 RESIZE_IF_NEEDED( a, n+count );
3173
3174 for( i = n-1; i >= 0; i-- )
3175 ap[i+count] = ap[i];
3176 for(i=0; i < count; i++ )
3177 ap[i] = 0;
3178 a->nlimbs += count;
3179 }
3180
3181
3182 /****************
3183 * Shift A by COUNT limbs to the right
3184 * This is used only within the MPI library
3185 */
3186 void
3187 mpi_rshift_limbs( MPI a, unsigned int count )
3188 {
3189 mpi_ptr_t ap = a->d;
3190 mpi_size_t n = a->nlimbs;
3191 unsigned int i;
3192
3193 if( count >= n ) {
3194 a->nlimbs = 0;
3195 return;
3196 }
3197
3198 for( i = 0; i < n - count; i++ )
3199 ap[i] = ap[i+count];
3200 ap[i] = 0;
3201 a->nlimbs -= count;
3202 }
3203
3204