Coverage Report

Created: 2025-03-09 06:52

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