brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 980b6b9 Raw
110 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/* mpi-inline.h  -  Internal to the Multi Precision Integers3 *	Copyright (C) 1994, 1996, 1998, 1999 Free Software Foundation, Inc.4 *5 * This file is part of GnuPG.6 *7 * Note: This code is heavily based on the GNU MP Library.8 *	 Actually it's the same code with only minor changes in the9 *	 way the data is stored; this is to support the abstraction10 *	 of an optional secure memory allocation which may be used11 *	 to avoid revealing of sensitive data due to paging etc.12 *	 The GNU MP Library itself is published under the LGPL;13 *	 however I decided to publish this code under the plain GPL.14 */15 16#ifndef G10_MPI_INLINE_H17#define G10_MPI_INLINE_H18 19#ifndef G10_MPI_INLINE_DECL20#define G10_MPI_INLINE_DECL  static inline21#endif22 23G10_MPI_INLINE_DECL mpi_limb_t24mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,25	      mpi_size_t s1_size, mpi_limb_t s2_limb)26{27	mpi_limb_t x;28 29	x = *s1_ptr++;30	s2_limb += x;31	*res_ptr++ = s2_limb;32	if (s2_limb < x) {	/* sum is less than the left operand: handle carry */33		while (--s1_size) {34			x = *s1_ptr++ + 1;	/* add carry */35			*res_ptr++ = x;	/* and store */36			if (x)	/* not 0 (no overflow): we can stop */37				goto leave;38		}39		return 1;	/* return carry (size of s1 to small) */40	}41 42leave:43	if (res_ptr != s1_ptr) {	/* not the same variable */44		mpi_size_t i;	/* copy the rest */45		for (i = 0; i < s1_size - 1; i++)46			res_ptr[i] = s1_ptr[i];47	}48	return 0;		/* no carry */49}50 51G10_MPI_INLINE_DECL mpi_limb_t52mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,53	    mpi_ptr_t s2_ptr, mpi_size_t s2_size)54{55	mpi_limb_t cy = 0;56 57	if (s2_size)58		cy = mpihelp_add_n(res_ptr, s1_ptr, s2_ptr, s2_size);59 60	if (s1_size - s2_size)61		cy = mpihelp_add_1(res_ptr + s2_size, s1_ptr + s2_size,62				   s1_size - s2_size, cy);63	return cy;64}65 66G10_MPI_INLINE_DECL mpi_limb_t67mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,68	      mpi_size_t s1_size, mpi_limb_t s2_limb)69{70	mpi_limb_t x;71 72	x = *s1_ptr++;73	s2_limb = x - s2_limb;74	*res_ptr++ = s2_limb;75	if (s2_limb > x) {76		while (--s1_size) {77			x = *s1_ptr++;78			*res_ptr++ = x - 1;79			if (x)80				goto leave;81		}82		return 1;83	}84 85leave:86	if (res_ptr != s1_ptr) {87		mpi_size_t i;88		for (i = 0; i < s1_size - 1; i++)89			res_ptr[i] = s1_ptr[i];90	}91	return 0;92}93 94G10_MPI_INLINE_DECL mpi_limb_t95mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,96	    mpi_ptr_t s2_ptr, mpi_size_t s2_size)97{98	mpi_limb_t cy = 0;99 100	if (s2_size)101		cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);102 103	if (s1_size - s2_size)104		cy = mpihelp_sub_1(res_ptr + s2_size, s1_ptr + s2_size,105				   s1_size - s2_size, cy);106	return cy;107}108 109#endif /*G10_MPI_INLINE_H */110