/src/libgcrypt/mpi/mpi-cmp.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
26 | | int |
27 | | _gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v) |
28 | 30.7k | { |
29 | 30.7k | mpi_limb_t limb = v; |
30 | | |
31 | 30.7k | _gcry_mpi_normalize (u); |
32 | | |
33 | | /* Handle the case that U contains no limb. */ |
34 | 30.7k | if (u->nlimbs == 0) |
35 | 0 | return -(limb != 0); |
36 | | |
37 | | /* Handle the case that U is negative. */ |
38 | 30.7k | if (u->sign) |
39 | 0 | return -1; |
40 | | |
41 | 30.7k | if (u->nlimbs == 1) |
42 | 5.77k | { |
43 | | /* Handle the case that U contains exactly one limb. */ |
44 | | |
45 | 5.77k | if (u->d[0] > limb) |
46 | 2.89k | return 1; |
47 | 2.88k | if (u->d[0] < limb) |
48 | 0 | return -1; |
49 | 2.88k | return 0; |
50 | 2.88k | } |
51 | 24.9k | else |
52 | | /* Handle the case that U contains more than one limb. */ |
53 | 24.9k | return 1; |
54 | 30.7k | } |
55 | | |
56 | | |
57 | | /* Helper for _gcry_mpi_cmp and _gcry_mpi_cmpabs. */ |
58 | | static int |
59 | | do_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v, int absmode) |
60 | 3.12k | { |
61 | 3.12k | mpi_size_t usize; |
62 | 3.12k | mpi_size_t vsize; |
63 | 3.12k | int usign; |
64 | 3.12k | int vsign; |
65 | 3.12k | int cmp; |
66 | | |
67 | 3.12k | if (mpi_is_opaque (u) || mpi_is_opaque (v)) |
68 | 42 | { |
69 | | /* We have no signan and thus ABSMODE has no efeect here. */ |
70 | 42 | if (mpi_is_opaque (u) && !mpi_is_opaque (v)) |
71 | 0 | return -1; |
72 | 42 | if (!mpi_is_opaque (u) && mpi_is_opaque (v)) |
73 | 0 | return 1; |
74 | 42 | if (!u->sign && !v->sign) |
75 | 0 | return 0; /* Empty buffers are identical. */ |
76 | 42 | if (u->sign < v->sign) |
77 | 0 | return -1; |
78 | 42 | if (u->sign > v->sign) |
79 | 28 | return 1; |
80 | 14 | return memcmp (u->d, v->d, (u->sign+7)/8); |
81 | 42 | } |
82 | 3.08k | else |
83 | 3.08k | { |
84 | 3.08k | _gcry_mpi_normalize (u); |
85 | 3.08k | _gcry_mpi_normalize (v); |
86 | | |
87 | 3.08k | usize = u->nlimbs; |
88 | 3.08k | vsize = v->nlimbs; |
89 | 3.08k | usign = absmode? 0 : u->sign; |
90 | 3.08k | vsign = absmode? 0 : v->sign; |
91 | | |
92 | | /* Special treatment for +0 == -0 */ |
93 | 3.08k | if (!usize && !vsize) |
94 | 0 | return 0; |
95 | | |
96 | | /* Compare sign bits. */ |
97 | 3.08k | if (!usign && vsign) |
98 | 0 | return 1; |
99 | 3.08k | if (usign && !vsign) |
100 | 0 | return -1; |
101 | | |
102 | | /* U and V are either both positive or both negative. */ |
103 | | |
104 | 3.08k | if (usize != vsize && !usign && !vsign) |
105 | 48 | return usize - vsize; |
106 | 3.03k | if (usize != vsize && usign && vsign) |
107 | 0 | return vsize + usize; |
108 | 3.03k | if (!usize ) |
109 | 0 | return 0; |
110 | 3.03k | if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize))) |
111 | 93 | return 0; |
112 | 2.94k | if ((cmp < 0?1:0) == (usign?1:0)) |
113 | 1.69k | return 1; |
114 | 2.94k | } |
115 | 1.24k | return -1; |
116 | 3.12k | } |
117 | | |
118 | | |
119 | | int |
120 | | _gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) |
121 | 3.07k | { |
122 | 3.07k | return do_mpi_cmp (u, v, 0); |
123 | 3.07k | } |
124 | | |
125 | | /* Compare only the absolute values. */ |
126 | | int |
127 | | _gcry_mpi_cmpabs (gcry_mpi_t u, gcry_mpi_t v) |
128 | 48 | { |
129 | 48 | return do_mpi_cmp (u, v, 1); |
130 | 48 | } |