Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing , Testing and documenting SHA-1 algorithm #1204

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@babel/cli": "7.20.7",
"@babel/preset-env": "7.20.2",
"@types/jest": "29.4.0",
"eslint": "8.33.0",
"eslint": "^8.33.0",
"eslint-config-airbnb": "19.0.4",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jest": "27.2.1",
Expand Down
55 changes: 55 additions & 0 deletions src/algorithms/cryptography/sha1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# SHA-1 Algorithm

The SHA-1 (Secure Hash Algorithm 1) is a cryptographic hash function that produces a 160-bit (20-byte) hash value, which is often represented as a 40-digit hexadecimal number. It was developed by the National Security Agency (NSA) and published by the National Institute of Standards and Technology (NIST) in 1993 as a part of the Digital Signature Algorithm.

## How SHA-1 Works
SHA-1 takes an input message of any length and generates a fixed-size 160-bit (20-byte) hash value. The process involves several steps:

1. **Preprocessing**
- **Padding:** The original message is padded with a '1' bit followed by enough '0' bits to make the message length congruent to 448 modulo 512. This ensures the length of the message is a multiple of 512 bits (64 bytes).
- **Length Append:** The original length of the message (before padding) is represented as a 64-bit binary number and appended to the end of the padded message.

2. **Initialize Buffers**
- Five 32-bit buffers are used, denoted as `H0`, `H1`, `H2`, `H3`, and `H4`, which are initialized to specific constants derived from the square roots of prime numbers:
- `H0 = 0x67452301`
- `H1 = 0xEFCDAB89`
- `H2 = 0x98BADCFE`
- `H3 = 0x10325476`
- `H4 = 0xC3D2E1F0`

3. **Processing the Message in 512-bit Chunks**
- The padded message is divided into blocks of 512 bits (64 bytes). Each block is processed through 80 rounds, utilizing bitwise operations, modular addition, and logical functions.
- **Message Schedule Creation:** The 512-bit block is divided into 16 words of 32 bits each, which are then expanded into an 80-word schedule using bitwise operations.
- **Main Loop:** During each round, a different logical function is applied, and the five buffers are updated using the message schedule. This process involves mixing the buffers in a complex way to produce the hash.

4. **Updating the Buffers**
- After processing each block, the intermediate hash values are added to the existing buffer values. This process ensures that each block of the message contributes to the final hash.

5. **Producing the Final Hash**
- Once all blocks have been processed, the final hash value is generated by concatenating the five buffers (`H0`, `H1`, `H2`, `H3`, `H4`). This results in a 160-bit (20-byte) output, typically represented as a 40-digit hexadecimal number.

## Applications of SHA-1
SHA-1 is widely used in various applications where data integrity verification is essential:
- **Digital Signatures:** It is used in digital signature algorithms to verify the authenticity and integrity of digital documents.
- **Secure Communication Protocols:** SHA-1 is integrated into protocols such as TLS/SSL for ensuring secure communication over networks.
- **Checksum and Data Integrity Verification:** It can be used to detect alterations or corruption in data files.
- **Version Control Systems:** Systems like Git use SHA-1 for identifying commits uniquely.

## How to Implement SHA-1
Implementing SHA-1 involves following the step-by-step process outlined above. Libraries in various programming languages (JavaScript, Python, C++, etc.) provide built-in support for computing SHA-1 hashes, making it easier to integrate into projects.

For example, in JavaScript, a basic implementation could involve creating functions for padding the input, initializing buffers, processing blocks, and producing the final hash. Using these functions, the SHA-1 algorithm can compute the hash of a given input string.

## How to Use This Code

- First, import the `sha1` from the directory where it is exported as a constant.

- The `sha1` object contains two methods:
- `hash`: Takes a string as input and returns its corresponding SHA-1 hash value.
- `compare`: Takes a string and a SHA-1 hash string, and returns `true` if the hash value of the input string matches the given SHA-1 hash; otherwise, it returns `false`.

## References
- [Wikipedia - SHA-1](https://en.wikipedia.org/wiki/SHA-1)
- [RFC 3174 - US Secure Hash Algorithm 1 (SHA1)](https://tools.ietf.org/html/rfc3174)
- [NIST FIPS PUB 180-4 - Secure Hash Standard (SHS)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf)
- [Digital Signature Algorithm Overview](https://csrc.nist.gov/publications/detail/fips/186/4/final)
56 changes: 56 additions & 0 deletions src/algorithms/cryptography/sha1/_test_/sha_1.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import sha1 from '../sha_1';

describe('sha1', () => {
it('should return the correct SHA-1 hash for a given input string', () => {
const input = 'hello world';
const expectedHash = '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed';
expect(sha1.hash(input)).toBe(expectedHash);
});

it('should return the correct SHA-1 hash for an empty string', () => {
const input = '';
const expectedHash = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
expect(sha1.hash(input)).toBe(expectedHash);
});

it('should return the same hash for the same input string', () => {
const input = 'consistent hash';
const firstHash = sha1.hash(input);
const secondHash = sha1.hash(input);
expect(firstHash).toBe(secondHash);
});

it('should return different hashes for different input strings', () => {
const input1 = 'input one';
const input2 = 'input two';
const hash1 = sha1.hash(input1);
const hash2 = sha1.hash(input2);
expect(hash1).not.toBe(hash2);
});

it('should handle long input strings correctly', () => {
const input = 'a'.repeat(1000); // A string of 1000 'a' characters
const expectedHash = '291e9a6c66994949b57ba5e650361e98fc36b1ba';
expect(sha1.hash(input)).toBe(expectedHash);
});

it('should handle long complex input strings correctly', () => {
const input = 'the best $-percentage is below x% & ^ this one';
const expectedHash = '90c7605658a6e7bec952c3b818285e32b79ac304';
expect(sha1.hash(input)).toBe(expectedHash);
});

it('should return true while comparing the string with its corresponding hash value', () => {
const input = 'the best $-percentage is below x% & ^ this one';
const inputHash = '90c7605658a6e7bec952c3b818285e32b79ac304';
const expectedOutput = true;
expect(sha1.compare(input, inputHash)).toBe(expectedOutput);
});

it('should return false while comparing the string with diffrent hash value', () => {
const input = 'the best $-percentage is below x% & ^ this one';
const inputHash = '291e9a6c66994949b57ba5e650361e98fc36b1ba';
const expectedOutput = false;
expect(sha1.compare(input, inputHash)).toBe(expectedOutput);
});
});
Loading