Coverage Report

Created: 2024-11-21 06:47

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