/src/botan/src/lib/pubkey/xmss/xmss_wots_publickey.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * XMSS WOTS Public Key |
3 | | * A Winternitz One Time Signature public key for use with Extended Hash-Based |
4 | | * Signatures. |
5 | | * |
6 | | * (C) 2016,2017,2018 Matthias Gierlings |
7 | | * |
8 | | * Botan is released under the Simplified BSD License (see license.txt) |
9 | | **/ |
10 | | |
11 | | #include <botan/xmss_wots.h> |
12 | | #include <botan/internal/xmss_address.h> |
13 | | |
14 | | namespace Botan { |
15 | | |
16 | | void |
17 | | XMSS_WOTS_PublicKey::chain(secure_vector<uint8_t>& result, |
18 | | size_t start_idx, |
19 | | size_t steps, |
20 | | XMSS_Address& adrs, |
21 | | const secure_vector<uint8_t>& seed, |
22 | | XMSS_Hash& hash) |
23 | 0 | { |
24 | 0 | BOTAN_ASSERT_NOMSG(start_idx + steps < m_wots_params.wots_parameter()); |
25 | 0 | secure_vector<uint8_t> prf_output(hash.output_length()); |
26 | | |
27 | | // Note that RFC 8391 defines this algorithm recursively (building up the |
28 | | // iterations before any calculation) using 'steps' as the iterator and a |
29 | | // recursion base with 'steps == 0'. |
30 | | // Instead, we implement it iteratively using 'i' as iterator. This makes |
31 | | // 'adrs.set_hash_address(i)' equivalent to 'ADRS.setHashAddress(i + s - 1)'. |
32 | 0 | for(size_t i = start_idx; |
33 | 0 | i < (start_idx + steps) && i < m_wots_params.wots_parameter(); |
34 | 0 | i++) |
35 | 0 | { |
36 | 0 | adrs.set_hash_address(static_cast<uint32_t>(i)); |
37 | | |
38 | | // Calculate tmp XOR bitmask |
39 | 0 | adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Mask_Mode); |
40 | 0 | hash.prf(prf_output, seed, adrs.bytes()); |
41 | 0 | xor_buf(result, prf_output, result.size()); |
42 | | |
43 | | // Calculate key |
44 | 0 | adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Key_Mode); |
45 | | |
46 | | // Calculate f(key, tmp XOR bitmask) |
47 | 0 | hash.prf(prf_output, seed, adrs.bytes()); |
48 | 0 | hash.f(result, prf_output, result); |
49 | 0 | } |
50 | 0 | } |
51 | | |
52 | | wots_keysig_t |
53 | | XMSS_WOTS_PublicKey::pub_key_from_signature(const secure_vector<uint8_t>& msg, |
54 | | const wots_keysig_t& sig, |
55 | | XMSS_Address& adrs, |
56 | | const secure_vector<uint8_t>& seed) |
57 | 0 | { |
58 | 0 | secure_vector<uint8_t> msg_digest |
59 | 0 | { |
60 | 0 | m_wots_params.base_w(msg, m_wots_params.len_1()) |
61 | 0 | }; |
62 | |
|
63 | 0 | m_wots_params.append_checksum(msg_digest); |
64 | 0 | wots_keysig_t result(sig); |
65 | |
|
66 | 0 | for(size_t i = 0; i < m_wots_params.len(); i++) |
67 | 0 | { |
68 | 0 | adrs.set_chain_address(static_cast<uint32_t>(i)); |
69 | 0 | chain(result[i], |
70 | 0 | msg_digest[i], |
71 | 0 | m_wots_params.wots_parameter() - 1 - msg_digest[i], |
72 | 0 | adrs, |
73 | 0 | seed); |
74 | 0 | } |
75 | 0 | return result; |
76 | 0 | } |
77 | | |
78 | | } |