| /** |
| * Internal bignum functions |
| * |
| * Copyright The Mbed TLS Contributors |
| * SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| * not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "common.h" |
| |
| #if defined(MBEDTLS_BIGNUM_C) |
| |
| #include "mbedtls/error.h" |
| #include "mbedtls/bignum.h" |
| #include "bignum_mod.h" |
| |
| #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ |
| #define biL (ciL << 3) /* bits in limb */ |
| #define biH (ciL << 2) /* half limb size */ |
| |
| /* |
| * Convert between bits/chars and number of limbs |
| * Divide first in order to avoid potential overflows |
| */ |
| #define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) |
| #define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) |
| |
| /* |
| * Count leading zero bits in a given integer |
| */ |
| static size_t mpi_clz( const mbedtls_mpi_uint x ) |
| { |
| size_t j; |
| mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); |
| |
| for( j = 0; j < biL; j++ ) |
| { |
| if( x & mask ) break; |
| |
| mask >>= 1; |
| } |
| |
| return j; |
| } |
| |
| /* |
| * Return the number of bits |
| */ |
| static size_t mpi_bitlen( const mbedtls_mpi_uint *X, size_t nx ) |
| { |
| size_t i, j; |
| |
| if( nx == 0 ) |
| return( 0 ); |
| |
| for( i = nx - 1; i > 0; i-- ) |
| if( X[i] != 0 ) |
| break; |
| |
| j = biL - mpi_clz( X[i] ); |
| |
| return( ( i * biL ) + j ); |
| } |
| |
| void mbedtls_mpi_mod_residue_release( mbedtls_mpi_mod_residue *r ) |
| { |
| if ( r == NULL ) |
| return; |
| |
| r->n = 0; |
| r->p = NULL; |
| } |
| |
| int mbedtls_mpi_mod_residue_setup( mbedtls_mpi_mod_residue *r, |
| mbedtls_mpi_mod_modulus *m, |
| mbedtls_mpi_uint *X ) |
| { |
| if( X == NULL || m == NULL || r == NULL || X >= m->p) |
| return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
| |
| r->n = m->n; |
| r->p = X; |
| |
| return( 0 ); |
| } |
| |
| void mbedtls_mpi_mod_modulus_init( mbedtls_mpi_mod_modulus *m ) |
| { |
| if ( m == NULL ) |
| return; |
| |
| m->rep.mont = 0; |
| } |
| |
| void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m ) |
| { |
| if ( m == NULL ) |
| return; |
| |
| m->p = NULL; |
| m->n = 0; |
| m->plen = 0; |
| m->ext_rep = 0; |
| m->int_rep = 0; |
| m->rep.mont = NULL; |
| m->rep.ored = NULL; |
| } |
| |
| int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m, |
| mbedtls_mpi_uint *X, |
| size_t nx, |
| int ext_rep, |
| int int_rep ) |
| { |
| if ( X == NULL || m == NULL ) |
| return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
| |
| m->p = X; |
| m->n = nx; |
| m->ext_rep = ext_rep; |
| m->int_rep = int_rep; |
| m->plen = mpi_bitlen( X, nx ); |
| |
| return( 0 ); |
| } |
| |
| #endif /* MBEDTLS_BIGNUM_C */ |