1/* mpi-cmp.c - MPI functions 2 * Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. 3 * 4 * This file is part of Libgcrypt. 5 * 6 * Libgcrypt is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as 8 * published by the Free Software Foundation; either version 2.1 of 9 * the License, or (at your option) any later version. 10 * 11 * Libgcrypt 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 Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License 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 26int 27gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v) 28{ 29 mpi_limb_t limb = v; 30 31 _gcry_mpi_normalize (u); 32 33 /* Handle the case that U contains no limb. */ 34 if (u->nlimbs == 0) 35 return -(limb != 0); 36 37 /* Handle the case that U is negative. */ 38 if (u->sign) 39 return -1; 40 41 if (u->nlimbs == 1) 42 { 43 /* Handle the case that U contains exactly one limb. */ 44 45 if (u->d[0] > limb) 46 return 1; 47 if (u->d[0] < limb) 48 return -1; 49 return 0; 50 } 51 else 52 /* Handle the case that U contains more than one limb. */ 53 return 1; 54} 55 56 57int 58gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) 59{ 60 mpi_size_t usize; 61 mpi_size_t vsize; 62 int cmp; 63 64 if (mpi_is_opaque (u) || mpi_is_opaque (v)) 65 { 66 if (mpi_is_opaque (u) && !mpi_is_opaque (v)) 67 return -1; 68 if (!mpi_is_opaque (u) && mpi_is_opaque (v)) 69 return 1; 70 if (!u->sign && !v->sign) 71 return 0; /* Empty buffers are identical. */ 72 if (u->sign < v->sign) 73 return -1; 74 if (u->sign > v->sign) 75 return 1; 76 return memcmp (u->d, v->d, (u->sign+7)/8); 77 } 78 else 79 { 80 _gcry_mpi_normalize (u); 81 _gcry_mpi_normalize (v); 82 83 usize = u->nlimbs; 84 vsize = v->nlimbs; 85 86 /* Compare sign bits. */ 87 88 if (!u->sign && v->sign) 89 return 1; 90 if (u->sign && !v->sign) 91 return -1; 92 93 /* U and V are either both positive or both negative. */ 94 95 if (usize != vsize && !u->sign && !v->sign) 96 return usize - vsize; 97 if (usize != vsize && u->sign && v->sign) 98 return vsize + usize; 99 if (!usize ) 100 return 0; 101 if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize))) 102 return 0; 103 if ((cmp < 0?1:0) == (u->sign?1:0)) 104 return 1; 105 } 106 return -1; 107} 108