~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/lib/pubkey/xmss/xmss_verification_operation.cpp

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * XMSS Verification Operation
 
3
 * Provides signature verification capabilities for Extended Hash-Based
 
4
 * Signatures (XMSS).
 
5
 *
 
6
 * (C) 2016,2017 Matthias Gierlings
 
7
 *
 
8
 * Botan is released under the Simplified BSD License (see license.txt)
 
9
 **/
 
10
 
 
11
#include <botan/internal/xmss_verification_operation.h>
 
12
 
 
13
namespace Botan {
 
14
 
 
15
XMSS_Verification_Operation::XMSS_Verification_Operation(
 
16
   const XMSS_PublicKey& public_key)
 
17
   : XMSS_Common_Ops(public_key.xmss_oid()),
 
18
     m_pub_key(public_key),
 
19
     m_msg_buf(0)
 
20
   {
 
21
   }
 
22
 
 
23
secure_vector<uint8_t>
 
24
XMSS_Verification_Operation::root_from_signature(const XMSS_Signature& sig,
 
25
      const secure_vector<uint8_t>& msg,
 
26
      XMSS_Address& adrs,
 
27
      const secure_vector<uint8_t>& seed)
 
28
   {
 
29
   adrs.set_type(XMSS_Address::Type::OTS_Hash_Address);
 
30
   adrs.set_ots_address(sig.unused_leaf_index());
 
31
 
 
32
   XMSS_WOTS_PublicKey pub_key_ots(m_pub_key.wots_parameters().oid(),
 
33
                                   msg,
 
34
                                   sig.tree().ots_signature(),
 
35
                                   adrs,
 
36
                                   seed);
 
37
 
 
38
   adrs.set_type(XMSS_Address::Type::LTree_Address);
 
39
   adrs.set_ltree_address(sig.unused_leaf_index());
 
40
 
 
41
   std::array<secure_vector<uint8_t>, 2> node;
 
42
   create_l_tree(node[0], pub_key_ots, adrs, seed);
 
43
 
 
44
   adrs.set_type(XMSS_Address::Type::Hash_Tree_Address);
 
45
   adrs.set_tree_index(sig.unused_leaf_index());
 
46
 
 
47
   for(size_t k = 0; k < m_xmss_params.tree_height(); k++)
 
48
      {
 
49
      adrs.set_tree_height(k);
 
50
      if(((sig.unused_leaf_index() / (1 << k)) & 0x01) == 0)
 
51
         {
 
52
         adrs.set_tree_index(adrs.get_tree_index() >> 1);
 
53
         randomize_tree_hash(node[1],
 
54
                             node[0],
 
55
                             sig.tree().authentication_path()[k],
 
56
                             adrs,
 
57
                             seed);
 
58
         }
 
59
      else
 
60
         {
 
61
         adrs.set_tree_index((adrs.get_tree_index() - 1) >> 1);
 
62
         randomize_tree_hash(node[1],
 
63
                             sig.tree().authentication_path()[k],
 
64
                             node[0],
 
65
                             adrs,
 
66
                             seed);
 
67
         }
 
68
      node[0] = node[1];
 
69
      }
 
70
   return node[0];
 
71
   }
 
72
 
 
73
bool
 
74
XMSS_Verification_Operation::verify(const XMSS_Signature& sig,
 
75
                                    const secure_vector<uint8_t>& msg,
 
76
                                    const XMSS_PublicKey& public_key)
 
77
   {
 
78
   XMSS_Address adrs;
 
79
   secure_vector<uint8_t> index_bytes;
 
80
   XMSS_Tools::concat(index_bytes,
 
81
                      sig.unused_leaf_index(),
 
82
                      m_xmss_params.element_size());
 
83
   secure_vector<uint8_t> msg_digest =
 
84
      m_hash.h_msg(sig.randomness(),
 
85
                   public_key.root(),
 
86
                   index_bytes,
 
87
                   msg);
 
88
 
 
89
   secure_vector<uint8_t> node = root_from_signature(sig,
 
90
                                 msg_digest,
 
91
                                 adrs,
 
92
                                 public_key.public_seed());
 
93
 
 
94
   return (node == public_key.root());
 
95
   }
 
96
 
 
97
// FIXME: XMSS signature verification requires the "randomness" parameter out
 
98
// of the XMSS signature, which is part of the prefix that is hashed before
 
99
// msg. Since the signature is unknown till sign() is called all message
 
100
// content has to be buffered. For large messages this can be inconvenient or
 
101
// impossible.
 
102
// Possible solution: Change PK_Ops::Verification interface to take the
 
103
// signature as constructor argument, make sign a parameterless member call.
 
104
void XMSS_Verification_Operation::update(const uint8_t msg[], size_t msg_len)
 
105
   {
 
106
   std::copy(msg, msg + msg_len, std::back_inserter(m_msg_buf));
 
107
   }
 
108
 
 
109
bool XMSS_Verification_Operation::is_valid_signature(const uint8_t sig[],
 
110
      size_t sig_len)
 
111
   {
 
112
   try
 
113
      {
 
114
      XMSS_Signature signature(m_pub_key.xmss_parameters().oid(),
 
115
                               secure_vector<uint8_t>(sig, sig + sig_len));
 
116
      bool result = verify(signature, m_msg_buf, m_pub_key);
 
117
      m_msg_buf.clear();
 
118
      return result;
 
119
      }
 
120
   catch(Integrity_Failure&)
 
121
      {
 
122
      m_msg_buf.clear();
 
123
      return false;
 
124
      }
 
125
   }
 
126
 
 
127
}
 
128