Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/shark.cpp
Line
Count
Source
1
// shark.cpp - originally written and placed in the public domain by Wei Dai
2
3
#include "pch.h"
4
#include "shark.h"
5
#include "misc.h"
6
#include "modes.h"
7
#include "gf256.h"
8
9
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
10
# pragma GCC diagnostic ignored "-Wmissing-braces"
11
#endif
12
13
NAMESPACE_BEGIN(CryptoPP)
14
15
static word64 SHARKTransform(word64 a)
16
675
{
17
675
  static const byte iG[8][8] = {
18
675
    {0xe7, 0x30, 0x90, 0x85, 0xd0, 0x4b, 0x91, 0x41},
19
675
    {0x53, 0x95, 0x9b, 0xa5, 0x96, 0xbc, 0xa1, 0x68},
20
675
    {0x02, 0x45, 0xf7, 0x65, 0x5c, 0x1f, 0xb6, 0x52},
21
675
    {0xa2, 0xca, 0x22, 0x94, 0x44, 0x63, 0x2a, 0xa2},
22
675
    {0xfc, 0x67, 0x8e, 0x10, 0x29, 0x75, 0x85, 0x71},
23
675
    {0x24, 0x45, 0xa2, 0xcf, 0x2f, 0x22, 0xc1, 0x0e},
24
675
    {0xa1, 0xf1, 0x71, 0x40, 0x91, 0x27, 0x18, 0xa5},
25
675
    {0x56, 0xf4, 0xaf, 0x32, 0xd2, 0xa4, 0xdc, 0x71}
26
675
  };
27
28
675
  word64 result=0;
29
675
  GF256 gf256(0xf5);
30
6.07k
  for (unsigned int i=0; i<8; i++)
31
48.6k
    for(unsigned int j=0; j<8; j++)
32
43.2k
      result ^= word64(gf256.Multiply(iG[i][j], GF256::Element(a>>(56-8*j)))) << (56-8*i);
33
675
  return result;
34
675
}
35
36
void SHARK::Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs &params)
37
150
{
38
150
  AssertValidKeyLength(keyLen);
39
40
150
  m_rounds = GetRoundsAndThrowIfInvalid(params, this);
41
150
  m_roundKeys.New(m_rounds+1);
42
43
  // concatenate key enough times to fill a
44
8.55k
  for (unsigned int i=0; i<(m_rounds+1)*8; i++)
45
8.40k
    ((byte *)m_roundKeys.begin())[i] = key[i%keyLen];
46
47
150
  SHARK::Encryption e;
48
150
  e.InitForKeySetup();
49
150
  byte IV[8] = {0,0,0,0,0,0,0,0};
50
150
  CFB_Mode_ExternalCipher::Encryption cfb(e, IV);
51
52
150
  cfb.ProcessString((byte *)m_roundKeys.begin(), (m_rounds+1)*8);
53
54
150
  ConditionalByteReverse(BIG_ENDIAN_ORDER, m_roundKeys.begin(), m_roundKeys.begin(), (m_rounds+1)*8);
55
56
150
  m_roundKeys[m_rounds] = SHARKTransform(m_roundKeys[m_rounds]);
57
58
150
  if (!IsForwardTransformation())
59
75
  {
60
75
    unsigned int i;
61
62
    // transform encryption round keys into decryption round keys
63
300
    for (i=0; i<m_rounds/2; i++)
64
225
      std::swap(m_roundKeys[i], m_roundKeys[m_rounds-i]);
65
66
450
    for (i=1; i<m_rounds; i++)
67
375
      m_roundKeys[i] = SHARKTransform(m_roundKeys[i]);
68
75
  }
69
70
150
#if (CRYPTOPP_LITTLE_ENDIAN)
71
150
  m_roundKeys[0] = ByteReverse(m_roundKeys[0]);
72
150
  m_roundKeys[m_rounds] = ByteReverse(m_roundKeys[m_rounds]);
73
150
#endif
74
150
}
75
76
// construct an SHARK_Enc object with fixed round keys, to be used to initialize actual round keys
77
void SHARK::Enc::InitForKeySetup()
78
150
{
79
150
  m_rounds = DEFAULT_ROUNDS;
80
150
  m_roundKeys.New(DEFAULT_ROUNDS+1);
81
82
1.05k
  for (unsigned int i=0; i<DEFAULT_ROUNDS; i++)
83
900
    m_roundKeys[i] = cbox[0][i];
84
85
150
  m_roundKeys[DEFAULT_ROUNDS] = SHARKTransform(cbox[0][DEFAULT_ROUNDS]);
86
87
150
#if (CRYPTOPP_LITTLE_ENDIAN)
88
150
  m_roundKeys[0] = ByteReverse(m_roundKeys[0]);
89
150
  m_roundKeys[m_rounds] = ByteReverse(m_roundKeys[m_rounds]);
90
150
#endif
91
150
}
92
93
void SHARK::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
94
1.19k
{
95
1.19k
  CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf<word64>()));
96
1.19k
  word64 tmp = *(word64 *)(void *)inBlock ^ m_roundKeys[0];
97
98
1.19k
  ByteOrder order = GetNativeByteOrder();
99
1.19k
  tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)]
100
1.19k
    ^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)]
101
1.19k
    ^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)]
102
1.19k
    ^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)]
103
1.19k
    ^ m_roundKeys[1];
104
105
5.99k
  for(unsigned int i=2; i<m_rounds; i++)
106
4.79k
  {
107
4.79k
    tmp = cbox[0][GETBYTE(tmp, 7)] ^ cbox[1][GETBYTE(tmp, 6)]
108
4.79k
      ^ cbox[2][GETBYTE(tmp, 5)] ^ cbox[3][GETBYTE(tmp, 4)]
109
4.79k
      ^ cbox[4][GETBYTE(tmp, 3)] ^ cbox[5][GETBYTE(tmp, 2)]
110
4.79k
      ^ cbox[6][GETBYTE(tmp, 1)] ^ cbox[7][GETBYTE(tmp, 0)]
111
4.79k
      ^ m_roundKeys[i];
112
4.79k
  }
113
114
1.19k
  PutBlock<byte, BigEndian>(xorBlock, outBlock)
115
1.19k
    (sbox[GETBYTE(tmp, 7)])
116
1.19k
    (sbox[GETBYTE(tmp, 6)])
117
1.19k
    (sbox[GETBYTE(tmp, 5)])
118
1.19k
    (sbox[GETBYTE(tmp, 4)])
119
1.19k
    (sbox[GETBYTE(tmp, 3)])
120
1.19k
    (sbox[GETBYTE(tmp, 2)])
121
1.19k
    (sbox[GETBYTE(tmp, 1)])
122
1.19k
    (sbox[GETBYTE(tmp, 0)]);
123
124
1.19k
  CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf<word64>()));
125
1.19k
  *(word64 *)(void *)outBlock ^= m_roundKeys[m_rounds];
126
1.19k
}
127
128
void SHARK::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
129
150
{
130
150
  CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf<word64>()));
131
150
  word64 tmp = *(word64 *)(void *)inBlock ^ m_roundKeys[0];
132
133
150
  ByteOrder order = GetNativeByteOrder();
134
150
  tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)]
135
150
    ^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)]
136
150
    ^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)]
137
150
    ^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)]
138
150
    ^ m_roundKeys[1];
139
140
750
  for(unsigned int i=2; i<m_rounds; i++)
141
600
  {
142
600
    tmp = cbox[0][GETBYTE(tmp, 7)] ^ cbox[1][GETBYTE(tmp, 6)]
143
600
      ^ cbox[2][GETBYTE(tmp, 5)] ^ cbox[3][GETBYTE(tmp, 4)]
144
600
      ^ cbox[4][GETBYTE(tmp, 3)] ^ cbox[5][GETBYTE(tmp, 2)]
145
600
      ^ cbox[6][GETBYTE(tmp, 1)] ^ cbox[7][GETBYTE(tmp, 0)]
146
600
      ^ m_roundKeys[i];
147
600
  }
148
149
150
  PutBlock<byte, BigEndian>(xorBlock, outBlock)
150
150
    (sbox[GETBYTE(tmp, 7)])
151
150
    (sbox[GETBYTE(tmp, 6)])
152
150
    (sbox[GETBYTE(tmp, 5)])
153
150
    (sbox[GETBYTE(tmp, 4)])
154
150
    (sbox[GETBYTE(tmp, 3)])
155
150
    (sbox[GETBYTE(tmp, 2)])
156
150
    (sbox[GETBYTE(tmp, 1)])
157
150
    (sbox[GETBYTE(tmp, 0)]);
158
159
150
  CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf<word64>()));
160
150
  *(word64 *)(void *)outBlock ^= m_roundKeys[m_rounds];
161
150
}
162
163
NAMESPACE_END