Coverage Report

Created: 2025-10-10 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Botan-3.4.0/src/lib/math/mp/mp_monty.cpp
Line
Count
Source
1
/*
2
* Montgomery Reduction
3
* (C) 1999-2011 Jack Lloyd
4
*     2006 Luca Piccarreta
5
*     2016 Matthias Gierlings
6
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9
10
#include <botan/internal/mp_core.h>
11
12
#include <botan/assert.h>
13
#include <botan/exceptn.h>
14
#include <botan/mem_ops.h>
15
#include <botan/internal/ct_utils.h>
16
17
namespace Botan {
18
19
/*
20
* Montgomery reduction - product scanning form
21
*
22
* Algorithm 5 from "Energy-Efficient Software Implementation of Long
23
* Integer Modular Arithmetic"
24
* (https://www.iacr.org/archive/ches2005/006.pdf)
25
*
26
* See also
27
*
28
* https://eprint.iacr.org/2013/882.pdf
29
* https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf
30
*/
31
2.15M
void bigint_monty_redc_generic(word z[], size_t z_size, const word p[], size_t p_size, word p_dash, word ws[]) {
32
2.15M
   BOTAN_ARG_CHECK(z_size >= 2 * p_size && p_size > 0, "Invalid sizes for bigint_monty_redc_generic");
33
34
2.15M
   word w2 = 0, w1 = 0, w0 = 0;
35
36
2.15M
   w0 = z[0];
37
38
2.15M
   ws[0] = w0 * p_dash;
39
40
2.15M
   word3_muladd(&w2, &w1, &w0, ws[0], p[0]);
41
42
2.15M
   w0 = w1;
43
2.15M
   w1 = w2;
44
2.15M
   w2 = 0;
45
46
50.4M
   for(size_t i = 1; i != p_size; ++i) {
47
932M
      for(size_t j = 0; j < i; ++j) {
48
884M
         word3_muladd(&w2, &w1, &w0, ws[j], p[i - j]);
49
884M
      }
50
51
48.2M
      word3_add(&w2, &w1, &w0, z[i]);
52
53
48.2M
      ws[i] = w0 * p_dash;
54
55
48.2M
      word3_muladd(&w2, &w1, &w0, ws[i], p[0]);
56
57
48.2M
      w0 = w1;
58
48.2M
      w1 = w2;
59
48.2M
      w2 = 0;
60
48.2M
   }
61
62
50.4M
   for(size_t i = 0; i != p_size - 1; ++i) {
63
932M
      for(size_t j = i + 1; j != p_size; ++j) {
64
884M
         word3_muladd(&w2, &w1, &w0, ws[j], p[p_size + i - j]);
65
884M
      }
66
67
48.2M
      word3_add(&w2, &w1, &w0, z[p_size + i]);
68
69
48.2M
      ws[i] = w0;
70
71
48.2M
      w0 = w1;
72
48.2M
      w1 = w2;
73
48.2M
      w2 = 0;
74
48.2M
   }
75
76
2.15M
   word3_add(&w2, &w1, &w0, z[2 * p_size - 1]);
77
78
2.15M
   ws[p_size - 1] = w0;
79
   // w1 is the final part, which is not stored in the workspace
80
81
   /*
82
   * The result might need to be reduced mod p. To avoid a timing
83
   * channel, always perform the subtraction. If in the compution
84
   * of x - p a borrow is required then x was already < p.
85
   *
86
   * x starts at ws[0] and is p_size bytes long plus a possible high
87
   * digit left over in w1.
88
   *
89
   * x - p starts at z[0] and is also p_size bytes long
90
   *
91
   * If borrow was set after the subtraction, then x was already less
92
   * than p and the subtraction was not needed. In that case overwrite
93
   * z[0:p_size] with the original x in ws[0:p_size].
94
   *
95
   * We only copy out p_size in the final step because we know
96
   * the Montgomery result is < P
97
   */
98
99
2.15M
   bigint_monty_maybe_sub(p_size, z, w1, ws, p);
100
101
   // Clear the high words that contain the original input
102
2.15M
   clear_mem(z + p_size, z_size - p_size);
103
2.15M
}
104
105
}  // namespace Botan