Coverage Report

Created: 2024-06-28 06:19

/src/gmp-6.2.1/mpz/powm_sec.c
Line
Count
Source (jump to first uncovered line)
1
/* mpz_powm_sec(res,base,exp,mod) -- Set R to (U^E) mod M.
2
3
   Contributed to the GNU project by Torbjorn Granlund.
4
5
Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2008, 2009,
6
2012, 2015 Free Software Foundation, Inc.
7
8
This file is part of the GNU MP Library.
9
10
The GNU MP Library is free software; you can redistribute it and/or modify
11
it under the terms of either:
12
13
  * the GNU Lesser General Public License as published by the Free
14
    Software Foundation; either version 3 of the License, or (at your
15
    option) any later version.
16
17
or
18
19
  * the GNU General Public License as published by the Free Software
20
    Foundation; either version 2 of the License, or (at your option) any
21
    later version.
22
23
or both in parallel, as here.
24
25
The GNU MP Library is distributed in the hope that it will be useful, but
26
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
28
for more details.
29
30
You should have received copies of the GNU General Public License and the
31
GNU Lesser General Public License along with the GNU MP Library.  If not,
32
see https://www.gnu.org/licenses/.  */
33
34
35
#include "gmp-impl.h"
36
37
38
void
39
mpz_powm_sec (mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m)
40
114
{
41
114
  mp_size_t n;
42
114
  mp_ptr rp, tp;
43
114
  mp_srcptr bp, ep, mp;
44
114
  mp_size_t rn, bn, es, en;
45
114
  TMP_DECL;
46
47
114
  n = ABSIZ(m);
48
49
114
  mp = PTR(m);
50
51
114
  if (UNLIKELY ((n == 0) || (mp[0] % 2 == 0)))
52
0
    DIVIDE_BY_ZERO;
53
54
114
  es = SIZ(e);
55
114
  if (UNLIKELY (es <= 0))
56
0
    {
57
0
      if (es == 0)
58
0
  {
59
    /* b^0 mod m,  b is anything and m is non-zero.
60
       Result is 1 mod m, i.e., 1 or 0 depending on if m = 1.  */
61
0
    SIZ(r) = n != 1 || mp[0] != 1;
62
0
    MPZ_NEWALLOC (r, 1)[0] = 1;
63
0
    return;
64
0
  }
65
0
      DIVIDE_BY_ZERO;
66
0
    }
67
114
  en = es;
68
69
114
  bn = ABSIZ(b);
70
71
114
  if (UNLIKELY (bn == 0))
72
1
    {
73
1
      SIZ(r) = 0;
74
1
      return;
75
1
    }
76
77
113
  TMP_MARK;
78
113
  TMP_ALLOC_LIMBS_2 (rp, n,
79
113
         tp, mpn_sec_powm_itch (bn, en * GMP_NUMB_BITS, n));
80
81
113
  bp = PTR(b);
82
113
  ep = PTR(e);
83
84
113
  mpn_sec_powm (rp, bp, bn, ep, en * GMP_NUMB_BITS, mp, n, tp);
85
86
113
  rn = n;
87
88
113
  MPN_NORMALIZE (rp, rn);
89
90
113
  if ((ep[0] & 1) && SIZ(b) < 0 && rn != 0)
91
0
    {
92
0
      mpn_sub (rp, PTR(m), n, rp, rn);
93
0
      rn = n;
94
0
      MPN_NORMALIZE (rp, rn);
95
0
    }
96
97
113
  MPZ_NEWALLOC (r, rn);
98
113
  SIZ(r) = rn;
99
113
  MPN_COPY (PTR(r), rp, rn);
100
101
113
  TMP_FREE;
102
113
}