Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/simeck.cpp
Line
Count
Source (jump to first uncovered line)
1
// simeck.cpp - written and placed in the public domain by Gangqiang Yang and Jeffrey Walton.
2
//              Based on "The Simeck Family of Lightweight Block Ciphers" by Gangqiang Yang,
3
//              Bo Zhu, Valentin Suder, Mark D. Aagaard, and Guang Gong
4
5
#include "pch.h"
6
#include "config.h"
7
8
#include "simeck.h"
9
#include "misc.h"
10
#include "cpu.h"
11
12
ANONYMOUS_NAMESPACE_BEGIN
13
14
using CryptoPP::rotlConstant;
15
using CryptoPP::rotrConstant;
16
17
/// \brief SIMECK encryption round
18
/// \tparam T word type
19
/// \param key the key for the round or iteration
20
/// \param left the first value
21
/// \param right the second value
22
/// \details SIMECK_Encryption serves as the key schedule, encryption and
23
///   decryption functions.
24
template <class T>
25
inline void SIMECK_Encryption(const T key, T& left, T& right)
26
137k
{
27
137k
    const T temp = left;
28
137k
    left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key;
29
137k
    right = temp;
30
137k
}
simeck.cpp:void (anonymous namespace)::SIMECK_Encryption<unsigned short>(unsigned short, unsigned short&, unsigned short&)
Line
Count
Source
26
352
{
27
352
    const T temp = left;
28
352
    left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key;
29
352
    right = temp;
30
352
}
simeck.cpp:void (anonymous namespace)::SIMECK_Encryption<unsigned int>(unsigned int, unsigned int&, unsigned int&)
Line
Count
Source
26
137k
{
27
137k
    const T temp = left;
28
137k
    left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key;
29
137k
    right = temp;
30
137k
}
31
32
ANONYMOUS_NAMESPACE_END
33
34
NAMESPACE_BEGIN(CryptoPP)
35
36
std::string SIMECK32::Base::AlgorithmProvider() const
37
0
{
38
0
    return "C++";
39
0
}
40
41
void SIMECK32::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
42
3
{
43
3
    CRYPTOPP_UNUSED(params);
44
3
    CRYPTOPP_UNUSED(keyLength);
45
46
3
    GetBlock<word16, BigEndian> kblock(userKey);
47
3
    kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
48
49
3
    word16 constant = 0xFFFC;
50
3
    word32 sequence = 0x9A42BB1F;
51
99
    for (unsigned int i = 0; i < ROUNDS; ++i)
52
96
    {
53
96
        m_rk[i] = m_t[0];
54
55
96
        constant &= 0xFFFC;
56
96
        constant |= sequence & 1;
57
96
        sequence >>= 1;
58
59
96
        SIMECK_Encryption(static_cast<word16>(constant), m_t[1], m_t[0]);
60
61
        // rotate the LFSR of m_t
62
96
        m_t[4] = m_t[1];
63
96
        m_t[1] = m_t[2];
64
96
        m_t[2] = m_t[3];
65
96
        m_t[3] = m_t[4];
66
96
    }
67
3
}
68
69
void SIMECK32::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
70
0
{
71
    // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
72
0
    GetBlock<word16, BigEndian> iblock(inBlock);
73
0
    iblock(m_t[1])(m_t[0]);
74
75
0
    for (int idx = 0; idx < ROUNDS; ++idx)
76
0
        SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
77
78
0
    PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
79
0
    oblock(m_t[1])(m_t[0]);
80
0
}
81
82
void SIMECK32::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
83
8
{
84
    // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
85
8
    GetBlock<word16, BigEndian> iblock(inBlock);
86
8
    iblock(m_t[0])(m_t[1]);
87
88
264
    for (int idx = ROUNDS - 1; idx >= 0; --idx)
89
256
        SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
90
91
8
    PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
92
8
    oblock(m_t[0])(m_t[1]);
93
8
}
94
95
std::string SIMECK64::Base::AlgorithmProvider() const
96
0
{
97
0
    return "C++";
98
0
}
99
100
void SIMECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
101
3
{
102
3
    CRYPTOPP_UNUSED(params);
103
3
    CRYPTOPP_UNUSED(keyLength);
104
105
3
    GetBlock<word32, BigEndian> kblock(userKey);
106
3
    kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
107
108
3
    word64 constant = W64LIT(0xFFFFFFFC);
109
3
    word64 sequence = W64LIT(0x938BCA3083F);
110
135
    for (unsigned int i = 0; i < ROUNDS; ++i)
111
132
    {
112
132
        m_rk[i] = m_t[0];
113
114
132
        constant &= W64LIT(0xFFFFFFFC);
115
132
        constant |= sequence & 1;
116
132
        sequence >>= 1;
117
118
132
        SIMECK_Encryption(static_cast<word32>(constant), m_t[1], m_t[0]);
119
120
        // rotate the LFSR of m_t
121
132
        m_t[4] = m_t[1];
122
132
        m_t[1] = m_t[2];
123
132
        m_t[2] = m_t[3];
124
132
        m_t[3] = m_t[4];
125
132
    }
126
3
}
127
128
void SIMECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
129
3.11k
{
130
    // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
131
3.11k
    GetBlock<word32, BigEndian> iblock(inBlock);
132
3.11k
    iblock(m_t[1])(m_t[0]);
133
134
139k
    for (int idx = 0; idx < ROUNDS; ++idx)
135
136k
        SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
136
137
3.11k
    PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
138
3.11k
    oblock(m_t[1])(m_t[0]);
139
3.11k
}
140
141
void SIMECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
142
0
{
143
    // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
144
0
    GetBlock<word32, BigEndian> iblock(inBlock);
145
0
    iblock(m_t[0])(m_t[1]);
146
147
0
    for (int idx = ROUNDS - 1; idx >= 0; --idx)
148
0
        SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
149
150
0
    PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
151
0
    oblock(m_t[0])(m_t[1]);
152
0
}
153
154
NAMESPACE_END