Coverage Report

Created: 2025-04-11 06:45

/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
190
{
41
190
  mp_size_t n;
42
190
  mp_ptr rp, tp;
43
190
  mp_srcptr bp, ep, mp;
44
190
  mp_size_t rn, bn, es, en;
45
190
  TMP_DECL;
46
47
190
  n = ABSIZ(m);
48
49
190
  mp = PTR(m);
50
51
190
  if (UNLIKELY ((n == 0) || (mp[0] % 2 == 0)))
52
0
    DIVIDE_BY_ZERO;
53
54
190
  es = SIZ(e);
55
190
  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
190
  en = es;
68
69
190
  bn = ABSIZ(b);
70
71
190
  if (UNLIKELY (bn == 0))
72
4
    {
73
4
      SIZ(r) = 0;
74
4
      return;
75
4
    }
76
77
186
  TMP_MARK;
78
186
  TMP_ALLOC_LIMBS_2 (rp, n,
79
186
         tp, mpn_sec_powm_itch (bn, en * GMP_NUMB_BITS, n));
80
81
186
  bp = PTR(b);
82
186
  ep = PTR(e);
83
84
186
  mpn_sec_powm (rp, bp, bn, ep, en * GMP_NUMB_BITS, mp, n, tp);
85
86
186
  rn = n;
87
88
186
  MPN_NORMALIZE (rp, rn);
89
90
186
  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
186
  MPZ_NEWALLOC (r, rn);
98
186
  SIZ(r) = rn;
99
186
  MPN_COPY (PTR(r), rp, rn);
100
101
186
  TMP_FREE;
102
186
}