IT - 801 Information Security Lab Manual
IT - 801 Information Security Lab Manual
Semester-VIII th / IV th Year
To achieve global standard in quality of education, research & development in Information Technology by
adapting to the rapid technological advancement to empowering the IT- industry with the wings of
knowledge and power of innovation though knowledge creation, acquisition and dissemination for the
benefit of Society and Humanity.
M1: To provide students with Innovative and research skills, which is need of the hour for technical students.
M2: To impart knowledge to the students of Information Technology with relevant core and practical
knowledge inculcating real time experience in the promising field of computing.
M3: To prepare the graduates to meet information technology challenges with a blend of social, human,
ethical and value based education.
M5: To contribute to the community services at large as well as catering to socio-economic goals in local
and national levels.
.
PROGRAM OUTCOMES (POs)
PO4.Conductinvestigationsofcomplexproblems:Useresearch-basedknowledgeandresearch
methods including design of experiments, analysis and interpretation of data, and synthesis of the
information to provide validconclusions.
PO5.Moderntoolusage:Create,select,andapplyappropriatetechniques,resources,andmodern
engineeringandITtoolsincludingpredictionandmodelingtocomplexengineeringactivitieswith an
understanding of thelimitations.
PO6.Theengineerandsociety:Applyreasoninginformedbythecontextualknowledgetoassess
societal, health, safety, legal and cultural issues and the consequent responsibilities relevant tothe
professional engineeringpractice.
PO8. Ethics:Apply ethical principles and commit to professional ethics and responsibilities and
norms of the engineering practice.
PO9.Individualandteamwork:Functioneffectivelyasanindividual,andasamemberorleader in
diverse teams, and in multidisciplinarysettings.
PO12.Life-longlearning:Recognizetheneedfor,andhavethepreparationandabilitytoengage in
independent and life-long learning in the broadest context of technologicalchange
PROGRAM EDUCATION OBJECTIVES (PEOs)
PEO-I: Meet Market Demands: To prepare students to become a successful engineer to meet the
demand driven needs of industries/technical profession.
PEO-II: Core Competence: Graduates will demonstrate core competence in mathematical, Scientific and
basic engineering fundamentals necessary to formulate, analyze and solve engineering problems and also to
pursue advanced study or research.
PEO-III: Design and Analysis : Graduates will demonstrate good breadth of knowledge in core areas of
Information Technology and related engineering so as to comprehend engineering trade-offs, analyze,
design, and synthesize data and technical concepts to create novel designs in solving the real life problems.
PEO-V: Life-long learning: Graduates will engage themselves in life-long learning through independent
study and by participating in professional activities or continuing education
PROGRAM SPECIFIC OUTCOMES (PSOs)
PSO1: Understand, Analyze and develop computer programs for efficient analysis and design of computer based
system.
PSO3: Employ modern computer language software tools and platforms in creating innovative career paths to
be a successful professional
Marks Signature
S. Date of Date of Obtained Signature
Name of Experiment of
No Experiment Submission of Faculty
LW(10 PQ (10 Student
. marks) marks)
Study of Network Security
fundamentals - Ethical
1 Hacking, Social Engineering
practices.
Study of Anti-Intrusion
6
Technique – Honey pot.
Implementation of encryption
and decryption a string using
7
Caesar Cipher.
Implementation of S-DES
8 algorithm for data encryption.
Implementation of RSA
9 algorithm.
Implementation of MD5
10
Algorithm.
Experiment No. 1
Ethical Hacking- Ethical hacking and ethical hacker are terms that describe hacking
performed to help a company or individual identify potential threats on the computer or network.
An ethical hacker attempts to hack their way past the system security, finding any weak points in
the security that could be exploited by other hackers. The organization uses what the ethical
hacker finds to improve the system security, in an effort to minimize, if not eliminate any
potential hacker attacks.
In order for hacking to be deemed ethical, the hacker must obey the below rules.
1. You have permission to probe the network and attempt to identify potential security risks. It's
recommended that if you are the person performing the tests that you get written consent.
2. You respect the individual's or company's privacy and only go looking for security issues.
3. You report all security vulnerabilities you detect to the company, not leaving anything open
for you or someone else to come in at a later time.
4. You let the software developer or hardware manufacturer know of any security vulnerabilities
you locate in their software or hardware if not already known by the company.
The term "ethical hacker" has received criticism at times from people who say that there is no
such thing as an "ethical" hacker. Hacking is hacking, no matter how you look at it and those
who do the hacking are commonly referred to as computer criminals. However, the work that
ethical hackers do for organizations has helped improve system security and can be said to be
quite successful. Individuals interested in becoming an ethical hacker can work towards a
certification to become a Certified Ethical Hacker. This certification is provided by the
International Council of E-Commerce Consultants (EC-Council).
Social Engineering practices: The practice of deceiving someone, either in person, over the
phone, or using a computer, with the express intent of breaching some level of security either
personal or professional. Social engineering techniques are considered con games which are
performed by con artists. The targets of social engineering may never realize they have been
victimized.
Also Known As: Con Games
Examples:
Using social engineering techniques, the hacker managed to get the network administrator to
provide him the username and password needed to gain access to the company's server.
Social engineering attacks are based on one thing – information. Without information about your
customers, social engineers aren’t able to use the elicitation and pretesting tactics that are
described below.
This information is relatively simple to obtain. A good social engineer can spend a few hours
researching a target online and have enough information to make even the most seasoned contact
center agent believe the social engineer is someone they are not. The increasing amount of
personal information that’s available using search engines, who is databases, social media
(Facebook, LinkedIn, MySpace, Twitter, etc.), blogs, wikis, and photo sharing sites makes it
very simple for them to find or determine:
Even social security numbers are available from some paid research services.
Once the social engineer has relevant information, they use it in these highly effective human
hacking tactics:
• Elicitation
• Pretexting
Experiment No. 2
Denial of Service: The goal of a denial of service attack is to deny legitimate users access to a
particular resource. An incident is considered an attack if a malicious user intentionally disrupts
service to a computer or network resource. Denial of service (DoS) attacks has become a major
threat to current computer networks. To have a better understanding on DoS attacks, In
particular, we network based and host based DoS attack techniques to illustrate attack principles.
DoS attacks are classified according to their major attack characteristics. Current counterattack
technologies are also reviewed, including major defense products in deployment and
representative defense approaches in research. Finally, DoS attacks and defenses in 802.11 based
wireless networks are explored at physical, MAC and network layers.
Attack Techniques
Many attack techniques can be used for DoS purpose as long as they can disable service, or
downgrade service performance by exhausting resources for providing services. Although it is
Impossible to enumerate all existing attack techniques, we describe several representatives
network based and host based attacks in this section to illustrate attack principles. Readers can
find complementary information on DoS attacks in Handley et al. 2006 and Mirkovicet al. 2005.
ICMP Smurf Flooding. ICMP is often used to determine if a computer in the Internet is
responding. To achieve this task, an ICMP echo request packet is sent to a computer. If the
computer receives the request packet, it will return an ICMP echo reply packet. In a smurf attack,
attacking hosts forge ICMP echo requests having the victim's address as the source address and
the broadcast address of these remote networks as the destination address (CERT 1998). As
depicted in Figure 1, if the firewall or router of the remote network does not filter the special
6/28 crafted packets, they will be delivered (broadcast) to all computers on that network. These
computers will then send ICMP echo reply packets back to the source (i.e., the victim) carried in
the request packets. The victim’s network is thus congested.
If confidentiality is not required, the Authentication Header (AH) alone can provide security (in
this case, connectionless data integrity and data origin authentication) to IP datagram. The
implementation can be host-host, host-gateway or gateway-gateway. But only host-host
implementation is encouraged. The reason is that, in the case that security gateway provides
security service for the trusted hosts behind the gateway, The security attack can still arise when
the trusted hosts become untrusted. In other words the security can be violated for two
communicating end user if the security (without confidentiality) does not cover completely the
communicating path, but instead stop at the gateway, even though SA is established. Certainly in
any kind of implementation, the untrusted systems (i.e., the systems that don't have the SA
established) can't have the ability to attack data authentication (always referring to both data
integrity and data origin authentication).
The IP Encapsulating Security Payload (ESP) header provides integrity, authentication, and
confidentiality to IP datagram. It can provide a mix of optional security. ESP header can be
applied alone, in combination with the IP Authentication Header (AH), or in a nested way, e. g.
by using Tunnel-mode. The ESP header implementation can be host-host, host-gateway, or
gateway-gateway. The ESP header is inserted after the IP header and before a higher-level
protocol header (Transport-mode) or the encapsulated IP header (Tunnel-mode). Gateway-to-
gateway ESP implementation, using encryption/decryption , is critical for building Private
Virtual Networks (PVN) across an untrusted backbone in an open environment such as the
Internet.
Experiment No. 4
4: Brute Force
Brute Force refers to discovering passwords through trial and error, similar to trying every
possible combination on a lock. The most well known form of brute force attack is for password
cracking software to methodically try millions of passwords on one specific user name on a
specific account. A typically weak password can be cracked in less than a day using this method.
Security conscious online vendors like banks or e-mail services provide some protection against
such brute force attempts by denying access if there are too many attempts per hour. However,
different forms of brute force can be used to get around these safeguards. A common example is
software which automatically logs in to millions of different accounts per day by combining
popular user names, passwords, and web sites (i.e. try password1 at Jsmith@gmail.com, 123456
at dj@facebook.com, qwerty at Mrodriguez@yahoo.com, etc.). As such methods become more
widely adopted, it would not be surprising if nearly all accounts with short user names and short
passwords get compromised.
Brute force is also used as a supplementary attack after a first password is captured. For example,
if the password badpassword1 was captured by phishing, brute force can be used to try similar
passwords on other accounts.
Protection: Brute force attacks are highly unlikely to crack very strong passwords. So just use
strong passwords. I suggest randomized 15 character jumbles.
Damage Control: Your damages are limited to one account if you have a unique password for
each account. Immediately change the password of the affected account.
Trojans: Trojan horse attacks pose one of the most serious threats to computer security. If you
were referred here, you may have not only been attacked but may also be attacking others
unknowingly. This page will teach you how to avoid falling prey to them, and how to repair the
damage if you already did. According to legend, the Greeks won the Trojan war by hiding in a
huge, hollow wooden horse to sneak into the fortified city of Troy. In today’s computer world, a
Trojan horse is defined as a “malicious, security-breaking program that is disguised as something
benign”. For example, you download what appears to be a movie or music file, but when you
click on it, you unleash a dangerous program that erases your disk, sends your credit card
numbers and passwords to a stranger, or lets that stranger hijack your computer to commit illegal
denial of service attacks.
The following general information applies to all operating systems, but by far most of the
damage is done to/with Windows users due to its vast popularity and many weaknesses. Linux,
MacOS X, and other operating systems are not as frequently infected, but they are far from
immune.
Repairing the Damage
1. Anti-Virus Software: Some of these can handle most of the well knowntrojans, but none are
perfect, no matter what their advertising claims. You absolutely MUST make sure you have the
very latest update files for your programs, or else they will miss the latest trojans. Compared to
traditional viruses, today’s trojans evolve much quicker and come in many seemingly innocuous
forms, so anti-virus software is always going to be playing catch up. Also, if they fail to find
every trojan, anti-virus software can give you a false sense of security, such that you go about
your business not realizing that you are still dangerously compromised. There are many products
to choose from, but the following are generally effective: AVP, PC-cillin, and McAfee Virus
Scan. All are available for immediate downloading typically with a 30 day free trial. For a more
complete review of all major anti-virus programs, including specific configuration suggestions
for each, see the Hack Fix Project’s anti-virus software page .When you are done, make sure
you’ve updated Windows with all security patches .
2. Anti-Trojan Programs: These programs are the most effective against trojan horse attacks,
because they specialize in trojans instead of general viruses. A popular choice is The Cleaner,
$30 commercial software with a 30 day free trial. To use it effectively when you are done, make
sure you’ve updated Windows with all security patches, then change all your passwords because
they may have been seen by every “hacker” in the world.
BASIS FOR
VIRUS WORM TROJAN HORSE
COMPARISON
network.
action. executed.
controlled
software.
Purpose Modification of the Halt the CPU and Steals the user's
Production honeypots are easy to use, capture only limited information, and are used primarily
by companies or corporations; Production honeypots are placed inside the production network
with other production servers by an organization to improve their overall state of security.
Normally, production honeypots are low-interaction honeypots, which are easier to deploy. They
give less information about the attacks or attackers than research honeypots do.
Research honeypots are run to gather information about the motives and tactics of the Blackhat
community targeting different networks. These honeypots do not add direct value to a specific
organization; instead, they are used to research the threats organizations face and to learn how to
better protect against those threats.Research honeypots are complex to deploy and maintain,
capture extensive information, and are used primarily by research, military, or government
organizations.
There are three types of honeypot deployments that permit threat actors to perform different
levels of malicious activity:
Pure honeypots—complete production systems that monitor attacks through bug taps on
the link that connects the honeypot to the network. They are unsophisticated.
Honeypot Limitations
Honeypot security has its limitations as the honeypot cannot detect security breaches in
legitimate systems, and it does not always identify the attacker. There is also a risk that, having
successfully exploited the honeypot, an attacker can move laterally to infiltrate the real
production network. To prevent this, you need to ensure that the honeypot is adequately isolated.
To help scale your security operations, you can combine honeypots with other techniques. For
example, the canary trap strategy helps find information leaks by selectively sharing different
versions of sensitive information with suspected moles or whistleblowers.
A “honeywall” monitors the traffic going in and out of the network and directs it to the honeypot
instances. You can inject vulnerabilities into a honeynet to make it easy for an attacker to access
the trap.
This makes honeynet a better solution for large, complex networks – it presents attackers with an
alternative corporate network which can represent an attractive alternative to the real one.
Experiment No. 7
For encrypting a string, key-value ‘2’ is added to the ASCII value of the characters in the string.
Similarly, for decrypting a string, key-value ‘2’ is subtracted from the ASCII value of the
characters.
#include <iostream>
using namespace std;
int main()
{
int i, x;
char str[100];
default:
cout << "\nInvalid Input !!!\n";
}
return 0;
}
Output :
Please enter a string: svceindore
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
// Array to hold 16 keys
string round_keys[16];
// String to hold the plain text
string pt;
// Function to convert a number in decimal to binary
string convertDecimalToBinary(int decimal)
{
string binary;
while(decimal != 0) {
binary = (decimal % 2 == 0 ? "0" : "1") + binary;
decimal = decimal/2;
}
while(binary.length() < 4){
binary = "0" + binary;
}
return binary;
}
// Function to convert a number in binary to decimal
int convertBinaryToDecimal(string binary)
{
int decimal = 0;
int counter = 0;
int size = binary.length();
for(int i = size-1; i >= 0; i--)
{
if(binary[i] == '1'){
decimal += pow(2, counter);
}
counter++;
}
return decimal;
}
// Function to do a circular left shift by 1
string shift_left_once(string key_chunk){
string shifted="";
for(int i = 1; i < 28; i++){
shifted += key_chunk[i];
}
shifted += key_chunk[0];
return shifted;
}
// Function to do a circular left shift by 2
string shift_left_twice(string key_chunk){
string shifted="";
for(int i = 0; i < 2; i++){
for(int j = 1; j < 28; j++){
shifted += key_chunk[j];
}
shifted += key_chunk[0];
key_chunk= shifted;
shifted ="";
}
return key_chunk;
}
// Function to compute xor between two strings
string Xor(string a, string b){
string result = "";
int size = b.size();
for(int i = 0; i < size; i++){
if(a[i] != b[i]){
result += "1";
}
else{
result += "0";
}
}
return result;
}
// Function to generate the 16 keys.
void generate_keys(string key){
// The PC1 table
int pc1[56] = {
57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4
};
// The PC2 table
int pc2[48] = {
14,17,11,24,1,5,
3,28,15,6,21,10,
23,19,12,4,26,8,
16,7,27,20,13,2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32
};
// 1. Compressing the key using the PC1 table
string perm_key ="";
for(int i = 0; i < 56; i++){
perm_key+= key[pc1[i]-1];
}
// 2. Dividing the key into two equal halves
string left= perm_key.substr(0, 28);
string right= perm_key.substr(28, 28);
for(int i=0; i<16; i++){
// 3.1. For rounds 1, 2, 9, 16 the key_chunks
// are shifted by one.
if(i == 0 || i == 1 || i==8 || i==15 ){
left= shift_left_once(left);
right= shift_left_once(right);
}
// 3.2. For other rounds, the key_chunks
// are shifted by two
else{
left= shift_left_twice(left);
right= shift_left_twice(right);
}
// Combining the two chunks
string combined_key = left + right;
string round_key = "";
// Finally, using the PC2 table to transpose the key bits
for(int i = 0; i < 48; i++){
round_key += combined_key[pc2[i]-1];
}
round_keys[i] = round_key;
}
}
// Implementing the algorithm
string DES(){
// The initial permutation table
int initial_permutation[64] = {
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7
};
// The expansion table
int expansion_table[48] = {
32,1,2,3,4,5,4,5,
6,7,8,9,8,9,10,11,
12,13,12,13,14,15,16,17,
16,17,18,19,20,21,20,21,
22,23,24,25,24,25,26,27,
28,29,28,29,30,31,32,1
};
// The substitution boxes. The should contain values
// from 0 to 15 in any order.
int substition_boxes[8][4][16]=
{{
14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13
},
{
15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9
},
{
10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12
},
{
7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14
},
{
2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3
},
{
12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13
},
{
4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12
},
{
13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
}};
// The permutation table
int permutation_tab[32] = {
16,7,20,21,29,12,28,17,
1,15,23,26,5,18,31,10,
2,8,24,14,32,27,3,9,
19,13,30,6,22,11,4,25
};
// The inverse permutation table
int inverse_permutation[64]= {
40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25
};
//1. Applying the initial permutation
string perm = "";
for(int i = 0; i < 64; i++){
perm += pt[initial_permutation[i]-1];
}
// 2. Dividing the result into two equal halves
string left = perm.substr(0, 32);
string right = perm.substr(32, 32);
// The plain text is encrypted 16 times
for(int i=0; i<16; i++) {
string right_expanded = "";
// 3.1. The right half of the plain text is expanded
for(int i = 0; i < 48; i++) {
right_expanded += right[expansion_table[i]-1];
}; // 3.3. The result is xored with a key
string xored = Xor(round_keys[i], right_expanded);
string res = "";
// 3.4. The result is divided into 8 equal parts and passed
// through 8 substitution boxes. After passing through a
// substituion box, each box is reduces from 6 to 4 bits.
for(int i=0;i<8; i++){
// Finding row and column indices to lookup the
// substituition box
string row1= xored.substr(i*6,1) + xored.substr(i*6 + 5,1);
int row = convertBinaryToDecimal(row1);
string col1 = xored.substr(i*6 + 1,1) + xored.substr(i*6 + 2,1) + xored.substr(i*6 + 3,1) +
xored.substr(i*6 + 4,1);;
int col = convertBinaryToDecimal(col1);
int val = substition_boxes[i][row][col];
res += convertDecimalToBinary(val);
}
// 3.5. Another permutation is applied
string perm2 ="";
for(int i = 0; i < 32; i++){
perm2 += res[permutation_tab[i]-1];
}
// 3.6. The result is xored with the left half
xored = Xor(perm2, left);
// 3.7. The left and the right parts of the plain text are swapped
left = xored;
if(i < 15){
string temp = right;
right = xored;
left = temp;
}
}
// 4. The halves of the plain text are applied
string combined_text = left + right;
string ciphertext ="";
// The inverse of the initial permuttaion is applied
for(int i = 0; i < 64; i++){
ciphertext+= combined_text[inverse_permutation[i]-1];
}
//And we finally get the cipher text
return ciphertext;
}
int main(){
// A 64 bit key
string key= "1010101010111011000010010001100000100111001101101100110011011101";
pt= "0000000111001101111001101010101111001101000100110010010100110110";
string apt = pt;
// Calling the function to generate 16 keys
generate_keys(key);
cout<<"\n Plain text: "<<pt<<endl;
// Applying the algo
string ct= DES();
cout<<" \n Ciphertext: "<<ct<<endl;
// Reversing the round_keys array for decryption
int i = 15;
int j = 0;
while(i > j)
{
string temp = round_keys[i];
round_keys[i] = round_keys[j];
round_keys[j] = temp;
i--;
j++;
}
pt = ct;
string decrypted = DES();
cout<<"\n Decrypted text:"<<decrypted<<endl;
// Comapring the initial plain text with the decrypted text
if (decrypted == apt){
cout<<"\n \n Plain text Encrypted and Decrypted successfully."<<endl;
}
}
Experiment No. 9
#include<iostream>
#include<math.h>
#include<string.h>
#include<stdlib.h>
Output :
The MD5 hash function was originally designed for use as a secure cryptographic hash algorithm
for authenticating digital signatures. But MD5 has been deprecated for uses other than as a
noncryptographic checksum to verify data integrity and detect unintentional data corruption.
#ifndef CONSTEXPR_HASH_MD5_H
#define CONSTEXPR_HASH_MD5_H
#include <array>
#include <iostream>
#include <cstdint>
namespace ConstexprHashes {
// MD5 operations
constexpr uint32_t f(uint32_t x, uint32_t y, uint32_t z) {
return z ^ (x & (y ^ z));
}
template<typename Functor>
constexpr uint32_t step(Functor fun, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t t, uint32_t s)
{
return step_helper(a + fun(b, c, d) + x + t, s, b);
}
// Constants
// Functions applied
template<size_t... indexes>
struct index_tuple {};
template<size_t... indexes>
struct index_tuple<0, indexes...> {
typedef index_tuple<indexes...> type;
};
template<typename... Args>
struct index_tuple_maker {
typedef typename index_tuple<sizeof...(Args)>::type type;
};
template<size_t n>
struct buffer_builder<n, n> {
static constexpr char make_value(const char *) {
return 0x80;
}
};
template<size_t n>
struct buffer_builder<n, 56> {
static constexpr char make_value(const char *) {
return n << 3;
}
};
/*
* Simple array implementation, which allows constexpr access to its
* elements.
*/
template<size_t n>
constexpr buffer_type make_buffer(const char (&data)[n]) {
return make_buffer_helper(data, index_tuple<64>::type());
}
/*
* There are 64 steps. The ith step has the same structure as the ith + 4 step.
* That means that we can repeat the same structure, and pick the appropiate
* constants and function to apply, depending on the step number.
*/
/*
* Nasty, but works. Convert the MD5 result(which is 4 uint32_t), to
* a std::array<char, 16>.
*/
template<>
struct md5_step<64, 0> {
static constexpr md5_type do_step(const char *, uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
return make_md5_result(a + 0x67452301, b + 0xefcdab89, c + 0x98badcfe, d + 0x10325476);
}
};
template<size_t n>
struct md5_step<n, 3> {
static constexpr md5_type do_step(const char *data, uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
return md5_step<n + 1, (n + 1) % 4>::do_step(data, a, step(md5_functions[n / 16], b, c, d, a, data32(data,
md5_indexes[n]), md5_constants[n], md5_shift[n]), c, d);
}
};
template<size_t n>
struct md5_step<n, 2> {
static constexpr md5_type do_step(const char *data, uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
return md5_step<n + 1, (n + 1) % 4>::do_step(data, a, b, step(md5_functions[n / 16], c, d, a, b, data32(data,
md5_indexes[n]), md5_constants[n], md5_shift[n]), d);
}
};
template<size_t n>
struct md5_step<n, 1> {
static constexpr md5_type do_step(const char *data, uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
return md5_step<n + 1, (n + 1) % 4>::do_step(data, a, b, c, step(md5_functions[n / 16], d, a, b, c, data32(data,
md5_indexes[n]), md5_constants[n], md5_shift[n]));
}
};
template<size_t n>
struct md5_step<n, 0> {
static constexpr md5_type do_step(const char *data, uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
return md5_step<n + 1, (n + 1) % 4>::do_step(data, step(md5_functions[n / 16], a, b, c, d, data32(data,
md5_indexes[n]), md5_constants[n], md5_shift[n]), b, c, d);
}
};
template<size_t n>
constexpr md5_type md5(const char (&data)[n]) {
return md5_step<0, 0>::do_step(make_buffer(data).data(), 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476);
}
} // namespace ConstexprHashes
#endif //CONSTEXPR_HASH_MD5_H
#include <iostream>
#include <iomanip>
int main() {
auto hash = ConstexprHashes::md5("SVCE indore");
cout << hex;
for (auto i : hash) {
cout << (static_cast<int>(i) & 0xff);
}
cout << endl;
}