eme_pkcs.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020 Mikhail Komarov <nemo@nil.foundation>
3 //
4 // MIT License
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23 //---------------------------------------------------------------------------//
24 
25 #ifndef CRYPTO3_EME_PKCS1_HPP
26 #define CRYPTO3_EME_PKCS1_HPP
27 
29 
30 namespace nil {
31  namespace crypto3 {
32  namespace pubkey {
33  namespace padding {
37  template<typename Scheme, typename Hash>
38  class eme_pkcs1v15 : public eme<Scheme, Hash> {
39  public:
40  template<typename UniformRandomBitGenerator, typename RandomNumberDistribution,
41  typename InputIterator, typename OutputIterator>
42  OutputIterator pad(InputIterator first, InputIterator last, OutputIterator out,
43  std::size_t key_length, UniformRandomBitGenerator rand,
44  RandomNumberDistribution dist) {
45  std::ptrdiff_t distance = std::distance(first, last);
46 
47  if (distance > maximum_input_size(key_length)) {
48  throw std::invalid_argument("PKCS1: Input is too large");
49  }
50 
51  key_length /= 8;
52 
53  secure_vector<uint8_t> out(key_length);
54 
55  out[0] = 0x02;
56  rand.randomize(out.data() + 1, (key_length - distance - 2));
57 
58  for (size_t j = 1; j != key_length - distance - 1; ++j) {
59  if (out[j] == 0) {
60  out[j] = rand.next_nonzero_byte();
61  }
62  }
63 
64  buffer_insert(out, key_length - distance, in, distance);
65 
66  return out;
67  }
68 
69  template<typename InputIterator, typename OutputIterator>
70  OutputIterator unpad(InputIterator first, InputIterator last, OutputIterator out) {
71  std::ptrdiff_t distance = std::distance(first, last);
72 
73  if (distance < 2) {
74  throw std::invalid_argument("");
75  }
76 
77  ct::poison(in, distance);
78 
79  uint8_t bad_input_m = 0;
80  uint8_t seen_zero_m = 0;
81  size_t delim_idx = 0;
82 
83  bad_input_m |= ~ct::is_equal<uint8_t>(*first, 0);
84  bad_input_m |= ~ct::is_equal<uint8_t>(*(first + 1), 2);
85 
86  for (size_t i = 2; i < distance; ++i) {
87  const uint8_t is_zero_m = ct::is_zero<uint8_t>(in[i]);
88 
89  delim_idx += ct::select<uint8_t>(~seen_zero_m, 1, 0);
90 
91  bad_input_m |= is_zero_m & ct::expand_mask<uint8_t>(i < 10);
92  seen_zero_m |= is_zero_m;
93  }
94 
95  bad_input_m |= ~seen_zero_m;
96  bad_input_m |= ct::is_less<size_t>(delim_idx, 8);
97 
98  ct::unpoison(in, distance);
99  ct::unpoison(bad_input_m);
100  ct::unpoison(delim_idx);
101 
102  secure_vector<uint8_t> output(&in[delim_idx + 2], &in[distance]);
103  ct::cond_zero_mem(bad_input_m, output.data(), output.size());
104 
105  return out;
106  }
107 
108  virtual size_t maximum_input_size(std::size_t key_bits) const override {
109  if (key_bits / 8 > 10) {
110  return ((key_bits / 8) - 10);
111  } else {
112  return 0;
113  }
114  }
115  };
116  } // namespace padding
117  } // namespace pubkey
118  } // namespace crypto3
119 } // namespace nil
120 
121 #endif
EME from PKCS #1 v1.5.
Definition: eme_pkcs.hpp:38
OutputIterator pad(InputIterator first, InputIterator last, OutputIterator out, std::size_t key_length, UniformRandomBitGenerator rand, RandomNumberDistribution dist)
Definition: eme_pkcs.hpp:42
virtual size_t maximum_input_size(std::size_t key_bits) const override
Definition: eme_pkcs.hpp:108
OutputIterator unpad(InputIterator first, InputIterator last, OutputIterator out)
Definition: eme_pkcs.hpp:70
boost::mpl::apply< AccumulatorSet, tag::pubkey< ProcessingMode > >::type::result_type pubkey(const AccumulatorSet &acc)
Definition: accumulators/pubkey.hpp:106
Definition: pair.hpp:31
Encoding Method for Encryption.
Definition: eme.hpp:38