Coverage Report

Created: 2025-07-11 06:15

/src/rnp/src/lib/crypto/dilithium.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2023, [MTG AG](https://www.mtg.de).
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1.  Redistributions of source code must retain the above copyright notice,
9
 *     this list of conditions and the following disclaimer.
10
 *
11
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
12
 *     this list of conditions and the following disclaimer in the documentation
13
 *     and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "dilithium.h"
28
#include <cassert>
29
30
namespace {
31
32
Botan::DilithiumMode
33
rnp_dilithium_param_to_botan_dimension(dilithium_parameter_e mode)
34
0
{
35
0
    Botan::DilithiumMode result = Botan::DilithiumMode::Dilithium8x7;
36
0
    if (mode == dilithium_parameter_e::dilithium_L3) {
37
0
        result = Botan::DilithiumMode::Dilithium6x5;
38
0
    }
39
0
    return result;
40
0
}
41
42
} // namespace
43
44
std::vector<uint8_t>
45
pgp_dilithium_private_key_t::sign(rnp::RNG *rng, const uint8_t *msg, size_t msg_len) const
46
0
{
47
0
    assert(is_initialized_);
48
0
    auto priv_key = botan_key();
49
50
0
    auto                 signer = Botan::PK_Signer(priv_key, *rng->obj(), "");
51
0
    std::vector<uint8_t> signature = signer.sign_message(msg, msg_len, *rng->obj());
52
    // std::vector<uint8_t> signature;
53
54
0
    return signature;
55
0
}
56
57
Botan::Dilithium_PublicKey
58
pgp_dilithium_public_key_t::botan_key() const
59
0
{
60
0
    return Botan::Dilithium_PublicKey(
61
0
      key_encoded_, rnp_dilithium_param_to_botan_dimension(dilithium_param_));
62
0
}
63
64
Botan::Dilithium_PrivateKey
65
pgp_dilithium_private_key_t::botan_key() const
66
0
{
67
0
    Botan::secure_vector<uint8_t> priv_sv(key_encoded_.data(),
68
0
                                          key_encoded_.data() + key_encoded_.size());
69
0
    return Botan::Dilithium_PrivateKey(
70
0
      priv_sv, rnp_dilithium_param_to_botan_dimension(this->dilithium_param_));
71
0
}
72
73
bool
74
pgp_dilithium_public_key_t::verify_signature(const uint8_t *msg,
75
                                             size_t         msg_len,
76
                                             const uint8_t *signature,
77
                                             size_t         signature_len) const
78
0
{
79
0
    assert(is_initialized_);
80
0
    auto pub_key = botan_key();
81
82
0
    auto verificator = Botan::PK_Verifier(pub_key, "");
83
0
    return verificator.verify_message(msg, msg_len, signature, signature_len);
84
0
}
85
86
std::pair<pgp_dilithium_public_key_t, pgp_dilithium_private_key_t>
87
dilithium_generate_keypair(rnp::RNG *rng, dilithium_parameter_e dilithium_param)
88
0
{
89
0
    Botan::Dilithium_PrivateKey priv_key(
90
0
      *rng->obj(), rnp_dilithium_param_to_botan_dimension(dilithium_param));
91
92
0
    std::unique_ptr<Botan::Public_Key> pub_key = priv_key.public_key();
93
0
    Botan::secure_vector<uint8_t>      priv_bits = priv_key.private_key_bits();
94
0
    return std::make_pair(
95
0
      pgp_dilithium_public_key_t(pub_key->public_key_bits(), dilithium_param),
96
0
      pgp_dilithium_private_key_t(priv_bits.data(), priv_bits.size(), dilithium_param));
97
0
}
98
99
bool
100
pgp_dilithium_public_key_t::is_valid(rnp::RNG *rng) const
101
0
{
102
0
    if (!is_initialized_) {
103
0
        return false;
104
0
    }
105
106
0
    auto key = botan_key();
107
0
    return key.check_key(*(rng->obj()), false);
108
0
}
109
110
bool
111
pgp_dilithium_private_key_t::is_valid(rnp::RNG *rng) const
112
0
{
113
0
    if (!is_initialized_) {
114
0
        return false;
115
0
    }
116
117
0
    auto key = botan_key();
118
0
    return key.check_key(*(rng->obj()), false);
119
0
}
120
121
bool
122
dilithium_hash_allowed(pgp_hash_alg_t hash_alg)
123
0
{
124
0
    switch (hash_alg) {
125
0
    case PGP_HASH_SHA3_256:
126
0
    case PGP_HASH_SHA3_512:
127
0
        return true;
128
0
    default:
129
0
        return false;
130
0
    }
131
0
}
132
133
pgp_hash_alg_t
134
dilithium_default_hash_alg()
135
0
{
136
0
    return PGP_HASH_SHA3_256;
137
0
}