Crypto++ Library
Crypto++[1] is a free, open-source C++ library for cryptographic schemes originally written by Wei Dai and includes ciphers, message authentication codes, one-way hash functions, public-key cryptosystems, key agreement schemes, and deflate compression[2]. The library is now maintained by several team members and the community. This library offers implementations for well-known and lesser-known schemes and algorithms.
Below is a small list of well-known systems[2].
- Diffie-Hellman Key Agreement
- Advanced Encryption Standard
- RSA Cryptography
- Elliptic Curve Cryptography
- Digital Signature Algorithm
- ElGamal Cryptosystem
- x25519 Key Agreement
- ed25519 Signature Scheme
- ChaCha20 Stream Cipher
List of supported algorithms of Crypto++ version 8.8 as per[1] :
- Authenticated encryption schemes: GCM, CCM, EAX, ChaCha20Poly1305 and XChaCha20Poly1305
- High speed stream ciphers : ChaCha (8/12/20), ChaCha (IETF), Panama, Salsa20, Sosemanuk, XSalsa20, XChaCha20
- AES and AES candidates: AES (Rijndael), RC6, MARS, Twofish, Serpent,CAST-256ARIA
- Other block ciphers: Blowfish, Camellia, CHAM, HIGHT, IDEA, Kalyna (128/256/512), LEA, SEED, RC5, SHACAL-2, SIMON (64/128), Skipjack, SPECK (64/128), Simeck, SM4, Threefish (256/512/1024), Triple-DES (DES-EDE2 and DES-EDE3), TEA, XTEA
- block cipher modes of operation: ECB, CBC, CBC ciphertext stealing (CTS), CFB, OFB, counter mode (CTR), XTS
- Message authentication codes: BLAKE2s, BLAKE2b, CMAC, CBC-MAC, DMAC, GMAC, HMAC, Poly1305, Poly1305 (IETF), SipHash, Two-Track-MAC, VMAC
- Hash functions: BLAKE2s, BLAKE2b, Keccack (F1600), LSH (256/512), SHA-1, SHA-2 (224/256/384/512), SHA-3 (224/256), SHA-3 (384/512), SHAKE (128/256), SipHash, SM3, Tiger, RIPEMD (128/160/256/320), WHIRLPOOL
- Public-key cryptography: RSA, DSA, Deterministic DSA, ElGamal, Nyberg-Rueppel (NR), Rabin-Williams (RW), LUC, LUCELG, EC-based German Digital Signature (ECGDSA),DLIES (variants of DHAES), ESIGN
- Padding schemes for public-key: PKCS#1 v2.0, OAEP, PSS, PSSR, IEEE P1363 systems EMSA2 and EMSA5
- Key agreement schemes: Diffie-Hellman (DH), Unified Diffie-Hellman (DH2), Menezes-Qu-Vanstone (MQV), Hashed MQV (HMQV), Fully Hashed MQV (FHMQV), LUCDIF, XTR-DH
- Elliptic curve cryptography: ECDSA, Deterministic ECDSA, ed25519, ECNR, ECIES, ECDH, ECMQV, x25519
- Insecure or obsolescent algorithms retained for backwards compatibility and historical value: MD2, MD4, MD5, Panama Hash, DES, ARC4, SEAL 3.0, WAKE-OFB, DESX (DES-XEX3), RC2, SAFER, 3-WAY, GOST, SHARK, CAST-128, Square
The list of other features of Crypto++ as presented in [1]:
- Pseudo random number generators (PRNG): ANSI X9.17 appendix C, RandomPool, DARN, VIA Padlock, RDRAND, RDSEED, NIST Hash and HMAC DRBGs
- Password based key derivation functions: PBKDF1 and PBKDF2 from PKCS #5,PBKDF from PKCS #12 appendix B, HKDF from RFC 5869, Scrypt from RFC 7914
- Shamir’s secret sharing scheme and Rabin’s information dispersal algorithm
(IDA) - Fast multi-precision integer (bignum) and polynomial operations
- Finite field arithmetics, including GF(p) and GF(2^n)
- Prime number generation and verification
- Useful non-cryptographic algorithms+ DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and
zlib (RFC 1950) format support
+ Hex, base-32, base-64, URL safe base-64 encoding and decoding
+ 32-bit CRC, CRC-C and Adler32 checksum - class wrappers for these platform and operating system features (optional):
+ high resolution timers on Windows, Unix, and Mac OS
+ /dev/random, /dev/urandom, /dev/srandom
+ Microsoft’s CryptGenRandom or BCryptGenRandom on Windows - A high level interface for most of the above, using a filter/pipeline
metaphor - Benchmarks and validation testing
- x86, x64 (x86-64), x32 (ILP32), ARM-32, Aarch32, Aarch64 and Power8 in-core code for the commonly used algorithms
+ run-time CPU feature detection and code selection
+ supports GCC-style and MSVC-style inline assembly, and MASM for x64
+ x86, x64 (x86-64), x32 provides MMX, SSE2, and SSE4 implementations
+ ARM-32, Aarch32 and Aarch64 provides NEON, ASIMD and ARMv8 implementations
+ Power8 provides in-core AES using NX Crypto Acceleration
You can read the following article and learn to setup and use the Crypto++ library.
Installing and Using Cryptography under Linux using Crypto++ Library
Note: The above article only explains the way of installing the Crypto++ library under Linux using the source version as well as the binary version of that library. After installing this library we can use it in our ns-3 simulations to do cryptography-related Network related research. Even it is possible to do modifications in the source version of the library for doing new research work related to cryptography and validating it with ns-3 simulations.
The above article explained two ways of installing the Crypto++ library one may try to use their preferred way with respect to their need for ns-3 simulation research. Whatever the way you have installed Crypto++ library, you have to test for its good working before proceeding to use it under ns-3.
So, first, test the working Crypto++ library installation by compiling a sample program as follows:
Testing the good working of Crypto++
After installing Crypto++, before trying to use it with ns-3, we have to test the good working status of the library installation by using it in a simple CPP program.
The following “ecctest.cpp” is one such sample program provided at [7]. It will perform curve operations directly. The j following code from[7] shows you how to exponentiate, multiply and add using the lower-level primitives over secp256r1.
#include "integer.h" #include "eccrypto.h" #include "osrng.h" #include "oids.h" #include#include int main(int argc, char* argv[]) { using namespace CryptoPP; typedef DL_GroupParameters_EC GroupParameters; typedef DL_GroupParameters_EC ::Element Element; AutoSeededRandomPool prng; GroupParameters group; group.Initialize(ASN1::secp256r1()); // private key Integer x(prng, Integer::One(), group.GetMaxExponent()); std::cout << "Private exponent:" << std::endl; std::cout << " " << std::hex << x << std::endl; // public key Element y = group.ExponentiateBase(x); std::cout << "Public element:" << std::endl; std::cout << " " << std::hex << y.x << std::endl; std::cout << " " << std::hex << y.y << std::endl; // element addition Element u = group.GetCurve().Add(y, ECP::Point(2,3)); std::cout << "Add:" << std::endl; std::cout << " " << std::hex << u.x << std::endl; std::cout << " " << std::hex << u.y << std::endl; // scalar multiplication Element v = group.GetCurve().ScalarMultiply(u, Integer::Two()); std::cout << "Mult:" << std::endl; std::cout << " " << std::hex << v.x << std::endl; std::cout << " " << std::hex << v.y << std::endl; return 0; }
If you compile the code using gcc or g++, then you may end up with an error like the following one:
To successfully run the code, you have to do the following :
Now we can run the compiled ecc test program.
It will produce a output like this:
In fact, using ‘waf’ based ns-3 compile, we can easily add an external library and use it in our ns-3 simulations. Doing the same under CMake is a little bit different thing. This article shows a simple ‘waf ‘based compile as well as an easy unique way of doing that in CMake-based ns-3 compile process that uses an external Crypto++ library along with ns-3-dev version.
Using an External Crypto++ Library under the earlier ‘waf’ based ns-3 systems
If you search the internet, then you may find different ways of compiling ns-3 with an external library. The following procedure from [4] by Ing. Miralem Mehić, Ph.D. is one such way of doing this using ‘wscript’ of the ‘waf’ based compile system.
To integrate libcrypto in ns3, open the script file wscript in your ns3 root directory and find “env = conf.env” code. In the next line add the following code:
conf.env[‘lpp’]
crypto= conf.check(mandatory=True, lib=’cryptopp’, uselib_store=’cryptopp’)
conf.env.append_value(‘CXXDEFINES’, ‘ENABLE_CRYPTOPP’)
conf.env.append_value(‘CCDEFINES’, ‘ENABLE_CRYPTOPP’)
Then find the code “if program.env[‘ENABLE_STATIC_NS3’]:”
then edit the following lines
if program.env[‘ENABLE_STATIC_NS3’]:
if sys.platform == ‘darwin’:
program.env.STLIB_MARKER = ‘-Wl,-all_load’
else:
program.env.STLIB_MARKER = ‘-Wl,-Bstatic,–whole-archive’
program.env.SHLIB_MARKER = ‘-Wl,-Bdynamic,–no-whole-archive’
else:
if program.env.DEST_BINFMT == ‘elf’:
# All ELF platforms are impacted but only the gcc compiler has a flag to fix it.
if ‘gcc’ in (program.env.CXX_NAME, program.env.CC_NAME):
program.env.append_value (‘SHLIB_MARKER’, ‘-Wl,–no-as-needed’)
return program
as
if program.env[‘ENABLE_STATIC_NS3’]:
if sys.platform == ‘darwin’:
program.env.STLIB_MARKER = ‘-Wl,-all_load,-lcryptopp’
else:
program.env.STLIB_MARKER = ‘-Wl,-Bstatic,–whole-archive,-lcryptopp’
program.env.SHLIB_MARKER = ‘-Wl,-Bdynamic,–no-whole-archive,-lcryptopp’
else:
if program.env.DEST_BINFMT == ‘elf’:
# All ELF platforms are impacted but only the gcc compiler has a flag to fix it.
if ‘gcc’ in (program.env.CXX_NAME, program.env.CC_NAME):
program.env.append_value (‘SHLIB_MARKER’, ‘-Wl,–no-as-needed,-lcryptopp’)
return program
Then find lines with code “obj.install_path = None”, there should be two such lines and after both of them add “obj.uselib = ‘CRYPTOPP’”. It should look like this:
if os.path.isdir(os.path.join(“scratch”, filename)):
obj = bld.create_ns3_program(filename, all_modules)
obj.path = obj.path.find_dir(‘scratch’).find_dir(filename)
obj.source = obj.path.ant_glob(‘*.cc’)
obj.target = filename
obj.name = obj.target
obj.install_path = None
obj.uselib = ‘CRYPTOPP’
elif filename.endswith(“.cc”):
name = filename[:-len(“.cc”)]
obj = bld.create_ns3_program(name, all_modules)
obj.path = obj.path.find_dir(‘scratch’)
obj.source = filename
obj.target = name
obj.name = obj.target
obj.install_path = None
obj.uselib = ‘CRYPTOPP’
Finally, reconfigure your ns3
sudo ./waf distclean sudo ./waf configure (with any other options that you normally would add) sudo ./waf
If you successfully compile ns-3, then you can use crypto++ in our your simulation scripts simply include the required library such as:
#include; #include ; #include ;
So, the above additions to a typical “wscript” that we found on the root directory of ns-3 will ‘theoretically’ enable accessing crypto++ from any module of ns-3.
Using an External Library under the new ‘CMake’ based ns-3 systems
The following are some of the ways that I found on the internet to use an external library using CMake-based system under ns-3.
The ns-3 manual page [9] explains the general way of using CMake with ns-3. It is somewhat complex to understand. At ns-3 user group[10], there was a discussion to use an external library with ns-3 in CMake-based compile- that was also complex to understand.
In another ns-3 user group discussion[12], Gabriel highlighted four different way of using CMake to integrate and use an external library under ns-3. The following is just a cut and paste from Gabriel’s answer :
The 3 easy ways:
1) Find libraries with CMake’s FindPackage()
>find_package(SomeExternalLibrary QUIET)
>if(${SomeExternalLibrary_FOUND})
>include_directories(${SomeExternalLibrary_INCLUDE_DIRS})
>set(external_libraries ${SomeExternalLibrary_LIBRARIES})
>endif()
>…
>set(libraries_to_link
>${libcore}
>${external_libraries}
>)
2) Find libraries with PkgConfig
>include(FindPkgConfig)
>if(PKG_CONFIG_FOUND)
>pkg_check_modules(EXTERNAL_LIBRARY libexternallibrary)
>endif()
>
>if(PKG_CONFIG_FOUND AND EXTERNAL_LIBRARY_FOUND)
>include_directories(${EXTERNAL_LIBRARY_INCLUDE_DIRS})
>set(external_libraries ${EXTERNAL_LIBRARY_LIBRARIES})
>endif()
>…
>set(libraries_to_link
>${libcore}
>${external_libraries}
>)
3) Find libraries from VcPkg with FindPackage()
>include(${VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
>find_package(SomeExternalLibrary QUIET)
>if(${SomeExternalLibrary_FOUND})
>include_directories(${SomeExternalLibrary_INCLUDE_DIRS})
>set(external_libraries ${SomeExternalLibrary_LIBRARIES})
>endif()
>…
>set(libraries_to_link
>${libcore}
>${external_libraries}
>)
4. One hard way: if you want to find a library in a directory provided by you, try
find_library(
external_library_dependency
external_library_name
PATHS /path/to/the/library/top/directory # you can manually provide a path to search for your library if it’s not in the PATH
PATH_SUFFIXES /build /build/lib /lib # possible subfolders inside the top directory of your library
)
${external_library_dependency} will have either the path to the external_library_name or will be set to ${external_library_name-NOTFOUND}.
In another ns-3 user group discussion[11], Gabriel highlighted a simple way of using CMake to integrate and use an external library under ns-3. The following is just a cut and paste from Gabriel’s answer :
If you care, then read the manual.
https://www.nsnam.org/docs/manual/html/working-with-cmake.html#linking-third-party-libraries
In fact, I tried all of the above methods but could not able to integrate Crypto++ with old as well as new ns-3 versions. Of course I used different versions of ns-3 and different versions of Crypto++ library also – but could not make it work when I am following any one of the above procedures. The reason for my failure is: I still could not understand the way CMake works or I had not spent sufficient time learning it on ns-3 – or simply I may be adding/editing the above lines in the wrong place or file. In all cases, my trials failed during ns-3 configuration phase or ns-3 compile phase or linking phase with different kinds of errors that you may already saw.
Now we can implement Crypto++ inside any ns-3 project by following the above steps. If you want to use the Crypto++ library in a ns-3 project or a particular application/protocol code, you should add the necessary things in the header file of the application/protocol.
If you are successfully compiling ns-3 with Crypto++, then, as a simple case, you can use it in your ns-3 simulations as explained below:
Using Crypto++ in a ns-3 Simulation
#include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/point-to-point-module.h" #include "ns3/internet-module.h" #include "ns3/applications-module.h" #include "cryptopp/integer.h" #include "cryptopp/eccrypto.h" #include "cryptopp/osrng.h" #include "cryptopp/oids.h" #include#include using namespace ns3; using namespace CryptoPP; int main (int argc, char *argv[]) { NodeContainer nodes; nodes.Create (2);PointToPointHelper channel; channel.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); channel.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer netDevices; netDevices = channel.Install (nodes); . . . . . . . . . . . . . . . . . . . typedef DL_GroupParameters_EC GroupParameters; typedef DL_GroupParameters_EC ::Element Element; AutoSeededRandomPool prng; GroupParameters group; group.Initialize(ASN1::secp256r1()); // private key . . . . . . . . . . . . . . . . . . . // public key . . . . . . . . . . . . . . . . . . . std::cout << "Mult:" << std::endl; std::cout << " " << std::hex << v.x << std::endl; std::cout << " " << std::hex << v.y << std::endl; return 0; Simulator::Run (); }
The above code segments highlight a simple way of directly using Crypto++ in a ns-3 simulation script itself.
The following is the complete code of one such implementation.
The following is the output of one such example program based on the inputs and outputs of “TestEccNetWorkSimulation.cpp” – it is implemented inside a simple network simulation code of ns-3.
Conclusion
This article explains the way of using Cryptography in ns-3 simulations using Crypto++ library. In this example, we only used a simple simulation script to test the working of the integrated Crypto++ library. It is possible to design secured hand-shake protocols and other security-related things by sending and receiving keys and data over packets in the network. Or future article may explain the way of designing one such security network protocol using Crypto++.
- https://github.com/weidai11/cryptopp
- https://www.cryptopp.com/wiki/Main_Page
- https://www.cryptopp.com/wiki/Linux
- https://www.mehic.info/2016/04/installing-and-crypto-libcryptopp-with-ns3/
- Installing ns-3-dev Under chroot Jail and Compile with CMake
- https://www.cryptopp.com/
- https://www.cryptopp.com/wiki/Elliptic_Curve_Cryptography
- https://www.projectguideline.com/installing-and-using-cryptography-under-linux-using-crypto-library/
- https://www.nsnam.org/docs/manual/html/working-with-cmake.html
- https://groups.google.com/g/ns-3-users/c/GVsE1z4PgHU
- https://groups.google.com/g/ns-3-users/c/QGvnl25KS2M/m/6Lt9YqGSAAAJ
- https://groups.google.com/g/ns-3-users/c/PbZi1KOaRFw