Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:09

0001 // simon.h - written and placed in the public domain by Jeffrey Walton

0002 
0003 /// \file simon.h

0004 /// \brief Classes for the Simon block cipher

0005 /// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,

0006 ///  Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.

0007 /// \sa <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK Families of

0008 ///  Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/">

0009 ///  The Simon and Speck GitHub</A> and <A HREF="https://www.cryptopp.com/wiki/SIMON">

0010 ///  SIMON</A> on the Crypto++ wiki.

0011 /// \since Crypto++ 6.0

0012 
0013 #ifndef CRYPTOPP_SIMON_H
0014 #define CRYPTOPP_SIMON_H
0015 
0016 #include "config.h"
0017 #include "seckey.h"
0018 #include "secblock.h"
0019 
0020 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || \
0021     CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 || \
0022     CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
0023 # ifndef CRYPTOPP_DISABLE_SIMON_SIMD
0024 #  define CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS 1
0025 # endif
0026 #endif
0027 
0028 // Yet another SunStudio/SunCC workaround. Failed self tests

0029 // in SSE code paths on i386 for SunStudio 12.3 and below.

0030 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120)
0031 # undef CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
0032 #endif
0033 
0034 NAMESPACE_BEGIN(CryptoPP)
0035 
0036 /// \brief SIMON block cipher information

0037 /// \tparam L block size of the cipher, in bytes

0038 /// \tparam D default key length, in bytes

0039 /// \tparam N minimum key length, in bytes

0040 /// \tparam M maximum key length, in bytes

0041 /// \since Crypto++ 6.0

0042 template <unsigned int L, unsigned int D, unsigned int N, unsigned int M>
0043 struct SIMON_Info : public FixedBlockSize<L>, VariableKeyLength<D, N, M>
0044 {
0045     /// \brief The algorithm name

0046     /// \return the algorithm name

0047     /// \details StaticAlgorithmName returns the algorithm's name as a static

0048     ///  member function.

0049     static const std::string StaticAlgorithmName()
0050     {
0051         // Format is Cipher-Blocksize(Keylength)

0052         return "SIMON-" + IntToString(L*8);
0053     }
0054 };
0055 
0056 /// \brief SIMON block cipher base class

0057 /// \tparam W the word type

0058 /// \details User code should use SIMON64 or SIMON128

0059 /// \sa SIMON64, SIMON128, <a href="http://www.cryptopp.com/wiki/SIMON">SIMON</a> on the Crypto++ wiki

0060 /// \since Crypto++ 6.0

0061 template <class W>
0062 struct SIMON_Base
0063 {
0064     virtual ~SIMON_Base() {}
0065     SIMON_Base() : m_kwords(0), m_rounds(0) {}
0066 
0067     typedef SecBlock<W, AllocatorWithCleanup<W, true> > AlignedSecBlock;
0068     mutable AlignedSecBlock m_wspace;  // workspace

0069     AlignedSecBlock         m_rkeys;   // round keys

0070     unsigned int            m_kwords;  // number of key words

0071     unsigned int            m_rounds;  // number of rounds

0072 };
0073 
0074 /// \brief SIMON 64-bit block cipher

0075 /// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,

0076 ///  Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.

0077 /// \details SIMON64 provides 64-bit block size. The valid key sizes are 96-bit and 128-bit.

0078 /// \sa SIMON64, SIMON128,  <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SIMON

0079 ///  Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/">

0080 ///  The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SIMON">SIMON</a> on the

0081 ///  Crypto++ wiki

0082 /// \since Crypto++ 6.0

0083 class CRYPTOPP_NO_VTABLE SIMON64 : public SIMON_Info<8, 12, 12, 16>, public BlockCipherDocumentation
0084 {
0085 public:
0086     /// \brief SIMON64 block cipher base implementation

0087     /// \details Provides implementation common to encryption and decryption

0088     /// \since Crypto++ 6.0

0089     class CRYPTOPP_NO_VTABLE Base : protected SIMON_Base<word32>, public BlockCipherImpl<SIMON_Info<8, 12, 12, 16> >
0090     {
0091     public:
0092         /// \brief The algorithm name

0093         /// \return the algorithm name

0094         /// \details AlgorithmName returns the algorithm's name as a

0095         ///  member function.

0096         std::string AlgorithmName() const {
0097             return StaticAlgorithmName() + (m_kwords == 0 ? "" :
0098                 "(" + IntToString(m_kwords*sizeof(word32)*8) + ")");
0099         }
0100 
0101         std::string AlgorithmProvider() const;
0102 
0103         /// \brief Provides input and output data alignment for optimal performance.

0104         /// \return the input data alignment that provides optimal performance

0105         /// \sa GetAlignment() and OptimalBlockSize()

0106         unsigned int OptimalDataAlignment() const;
0107 
0108     protected:
0109         void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params);
0110     };
0111 
0112     /// \brief SIMON64 encryption transformation

0113     /// \details Enc provides the encryption transformation.

0114     ///  All key sizes are supported.

0115     /// \since Crypto++ 6.0

0116     class CRYPTOPP_NO_VTABLE Enc : public Base
0117     {
0118     public:
0119         void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
0120     };
0121 
0122     /// \brief SIMON64 decryption transformation

0123     /// \details Dec provides the decryption transformation.

0124     ///  All key sizes are supported.

0125     /// \since Crypto++ 6.0

0126     class CRYPTOPP_NO_VTABLE Dec : public Base
0127     {
0128     public:
0129         void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
0130     };
0131 
0132     typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
0133     typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
0134 };
0135 
0136 /// \brief SIMON 128-bit block cipher

0137 /// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,

0138 ///  Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.

0139 /// \details SIMON128 provides 128-bit block size. The valid key sizes are 128-bit, 192-bit and 256-bit.

0140 /// \sa SIMON64, SIMON128,  <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SIMON

0141 ///  Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/">

0142 ///  The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SIMON">SIMON</a> on the

0143 ///  Crypto++ wiki

0144 /// \since Crypto++ 6.0

0145 class CRYPTOPP_NO_VTABLE SIMON128 : public SIMON_Info<16, 16, 16, 32>, public BlockCipherDocumentation
0146 {
0147 public:
0148     /// \brief SIMON128 block cipher base implementation

0149     /// \details Provides implementation common to encryption and decryption

0150     /// \since Crypto++ 6.0

0151     class CRYPTOPP_NO_VTABLE Base : protected SIMON_Base<word64>, public BlockCipherImpl<SIMON_Info<16, 16, 16, 32> >
0152     {
0153     public:
0154         /// \brief The algorithm name

0155         /// \return the algorithm name

0156         /// \details AlgorithmName returns the algorithm's name as a

0157         ///  member function.

0158         std::string AlgorithmName() const {
0159             return StaticAlgorithmName() + (m_kwords == 0 ? "" :
0160                 "(" + IntToString(m_kwords*sizeof(word64)*8) + ")");
0161         }
0162 
0163         std::string AlgorithmProvider() const;
0164 
0165         /// \brief Provides input and output data alignment for optimal performance.

0166         /// \return the input data alignment that provides optimal performance

0167         /// \sa GetAlignment() and OptimalBlockSize()

0168         unsigned int OptimalDataAlignment() const;
0169 
0170     protected:
0171         void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params);
0172     };
0173 
0174     /// \brief SIMON128 encryption transformation

0175     /// \details Enc provides the encryption transformation.

0176     ///  All key sizes are supported.

0177     /// \since Crypto++ 6.0

0178     class CRYPTOPP_NO_VTABLE Enc : public Base
0179     {
0180     public:
0181         void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
0182 #if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
0183         size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
0184 #endif
0185     };
0186 
0187     /// \brief SIMON128 decryption transformation

0188     /// \details Dec provides the decryption transformation.

0189     ///  All key sizes are supported.

0190     /// \since Crypto++ 6.0

0191     class CRYPTOPP_NO_VTABLE Dec : public Base
0192     {
0193     public:
0194         void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
0195 #if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
0196         size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
0197 #endif
0198     };
0199 
0200     typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
0201     typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
0202 };
0203 
0204 NAMESPACE_END
0205 
0206 #endif  // CRYPTOPP_SIMON_H