Coverage Report

Created: 2024-06-28 06:19

/src/botan/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
1.36M
void bigint_monty_redc_generic(word z[], size_t z_size, const word p[], size_t p_size, word p_dash, word ws[]) {
32
1.36M
   BOTAN_ARG_CHECK(z_size >= 2 * p_size && p_size > 0, "Invalid sizes for bigint_monty_redc_generic");
33
34
1.36M
   word3<word> accum;
35
36
1.36M
   accum.add(z[0]);
37
38
1.36M
   ws[0] = accum.monty_step(p[0], p_dash);
39
40
4.55M
   for(size_t i = 1; i != p_size; ++i) {
41
27.2M
      for(size_t j = 0; j < i; ++j) {
42
24.0M
         accum.mul(ws[j], p[i - j]);
43
24.0M
      }
44
45
3.19M
      accum.add(z[i]);
46
3.19M
      ws[i] = accum.monty_step(p[0], p_dash);
47
3.19M
   }
48
49
4.55M
   for(size_t i = 0; i != p_size - 1; ++i) {
50
27.2M
      for(size_t j = i + 1; j != p_size; ++j) {
51
24.0M
         accum.mul(ws[j], p[p_size + i - j]);
52
24.0M
      }
53
54
3.19M
      accum.add(z[p_size + i]);
55
3.19M
      ws[i] = accum.extract();
56
3.19M
   }
57
58
1.36M
   accum.add(z[2 * p_size - 1]);
59
60
1.36M
   ws[p_size - 1] = accum.extract();
61
   // w1 is the final part, which is not stored in the workspace
62
1.36M
   const word w1 = accum.extract();
63
64
   /*
65
   * The result might need to be reduced mod p. To avoid a timing
66
   * channel, always perform the subtraction. If in the compution
67
   * of x - p a borrow is required then x was already < p.
68
   *
69
   * x starts at ws[0] and is p_size bytes long plus a possible high
70
   * digit left over in w1.
71
   *
72
   * x - p starts at z[0] and is also p_size bytes long
73
   *
74
   * If borrow was set after the subtraction, then x was already less
75
   * than p and the subtraction was not needed. In that case overwrite
76
   * z[0:p_size] with the original x in ws[0:p_size].
77
   *
78
   * We only copy out p_size in the final step because we know
79
   * the Montgomery result is < P
80
   */
81
82
1.36M
   bigint_monty_maybe_sub(p_size, z, w1, ws, p);
83
84
   // Clear the high words that contain the original input
85
1.36M
   clear_mem(z + p_size, z_size - p_size);
86
1.36M
}
87
88
}  // namespace Botan