Skip to content
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/.vscode/
/demo_sha1
/test_sha1
bin/
build/
67 changes: 67 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.18)
project("SHA1_tests")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-Wall")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

get_filename_component(PARENT_DIR ../ ABSOLUTE)


if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
add_definitions(-D_WIN32)
add_compile_options("/O2")
else()
add_definitions(-D_LINUX)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
message(WARNING "Assuming system in Linux")
endif()
add_compile_options("-O3")
add_compile_options("-g")
endif()

#---------------------------------------------------------------------

add_library(SHA1_lib INTERFACE)

target_include_directories(
SHA1_lib
INTERFACE
"${CMAKE_SOURCE_DIR}"
)

#---------------------------------------------------------------------

set(TEST test_sha1)

add_executable(
"${TEST}"
test_sha1.cpp
test_sha1_file.cpp
)

target_link_libraries(
"${TEST}"
PRIVATE
SHA1_lib
)

#---------------------------------------------------------------------

set(TEST demo_sha1)

add_executable(
"${TEST}"
demo_sha1.cpp
)

target_link_libraries(
"${TEST}"
PRIVATE
SHA1_lib
)

#---------------------------------------------------------------------
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ RM = rm -f
all: demo_sha1 test_sha1

demo_sha1: demo_sha1.cpp sha1.cpp sha1.hpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -Wall -Wextra -std=c++11 -o $@ demo_sha1.cpp sha1.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -Wall -Wextra -std=c++11 -g -O3 -o $@ demo_sha1.cpp

test_sha1: test_sha1.cpp test_sha1_file.cpp sha1.hpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -Wall -Wextra -std=c++11 -o $@ test_sha1.cpp test_sha1_file.cpp sha1.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -Wall -Wextra -std=c++11 -g -O3 -o $@ test_sha1.cpp test_sha1_file.cpp

check: test_sha1
./test_sha1
Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SHA-1 implementation in C++

## Warning

Do not use SHA-1 unless you have to. [SHA-1 is practically broken](https://en.wikipedia.org/wiki/SHA-1#Birthday-Near-Collision_Attack_%E2%80%93_first_practical_chosen-prefix_attack).
Use a hash function from the [SHA-2](https://en.wikipedia.org/wiki/SHA-2) or [SHA-3](https://en.wikipedia.org/wiki/SHA-3) family instead.

- Despite been proven that SHA-1 has collision attacks, SHA-1 is still extensively used, for example in
websocket protocol.

- For security related purposes one should use a combination of at least two hashes. For example in pseudocode:
- sha2(sha1(data)) not very good
- sha1(data)+sha2(data) better
- sha1(data.part1)+sha2(data.part2)+sha3(data) strong (where data=data.part1+data.part2)


## To build the tests
```
cd tests
mkdir build
cd build
cmake ..
```

## License

100% Public Domain

## Authors

- Steve Reid (Original C Code)
- [Bruce Guenter](http://untroubled.org/) (Small changes to fit into bglibs)
- [Volker Diels-Grabsch](https://njh.eu/) (Translation to simpler C++ Code)
- [Eugene Hopkinson](https://riot.so/) (Safety improvements)
- [Zlatko Michailov](http://zlatko.michailov.org) (Header-only library)
- [Dan Machado](dan-machado@yandex.com) (Optimization)
17 changes: 0 additions & 17 deletions README.org

This file was deleted.

88 changes: 88 additions & 0 deletions performance/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
cmake_minimum_required(VERSION 3.18)
project("SHA1_tests")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-Wall")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

get_filename_component(PARENT_DIR ../ ABSOLUTE)


if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
add_definitions(-D_WIN32)
add_compile_options("/O2")
else()
add_definitions(-D_LINUX)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
message(WARNING "Assuming system in Linux")
endif()
add_compile_options("-O3")
add_compile_options("-g")
endif()

#---------------------------------------------------------------------

include(FetchContent)

FetchContent_Declare(TimeProfiler
GIT_REPOSITORY "https://github.com/volatilflerovium/time_profiler_visualizer"
GIT_TAG "origin/main"
)

FetchContent_MakeAvailable(TimeProfiler)

#---------------------------------------------------------------------

add_library(SHA1_lib INTERFACE)

target_include_directories(
SHA1_lib
INTERFACE
"${CMAKE_SOURCE_DIR}/.."
)

#---------------------------------------------------------------------

if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")

execute_process(COMMAND ls /tmp/1G_sha1_test_file.txt
ERROR_VARIABLE error
OUTPUT_VARIABLE output
)

if(NOT ("${error}" STREQUAL ""))
message("Creating a 1G file of random data in /tmp directory...")
execute_process(COMMAND dd if=/dev/urandom of=/tmp/1G_sha1_test_file.txt bs=1G count=1 iflag=fullblock
ERROR_VARIABLE error
OUTPUT_VARIABLE output
)
endif()
add_compile_definitions(TEST_FILE="/tmp/1G_sha1_test_file.txt")
endif()

#---------------------------------------------------------------------

set(TEST "big_file_test")

add_executable(
"${TEST}"
big_file_test.cpp
)

target_link_libraries(
"${TEST}"
PRIVATE
TimeProfiler
SHA1_lib
)

target_compile_definitions(
"${TEST}"
PRIVATE
-DENABLE_STOPWATCH
)

#---------------------------------------------------------------------
20 changes: 20 additions & 0 deletions performance/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Profiling

Charts were generated using (time_profiler_visualizer)[https://github.com/volatilflerovium/time_profiler_visualizer]

## Performance

Performace tests run under Debian 11 with AMD Ryzen7 processor.

For a file of 1GB
- SHA1 previous version: ~1870ms
- Linux command sha1sum: ~1471ms
- SHA1 optimized: ~1340ms (under Linux with mmap) and ~1530ms (for Linux and Windows using std::fread)

On a 1 GB file (in seconds)

[![performance-1GB-file.png](https://i.postimg.cc/GpPT4tPZ/performance-1GB-file.png)](https://postimg.cc/7C6ZcxWV)

On incremental string (in microseconds)

[![performance.png](https://i.postimg.cc/J4dN8sK0/performance.png)](https://postimg.cc/YhYGfq5B)
47 changes: 47 additions & 0 deletions performance/big_file_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <iostream>

#include "sha1.hpp"

#include "time_profiler/time_profiler.h"

using Profiler=tprofiler::TimeProfiler<std::chrono::seconds>;

//====================================================================

int main()
{
const char* testFile="";
#ifndef TEST_FILE
std::cout<<TEST_FILE<<" no found.\n";
return 0;
#else
testFile= TEST_FILE;
#endif

Profiler watch("sha1_new_1file", "#5400AA");

SHA1 sha1;

std::string hash;

for(int i=0; i<10; i++){
std::cout<<"sha1sum command: ";

watch.start();
system("sha1sum /tmp/1G_sha1_test_file.txt");
watch.takeSample(true);

std::cout<<"\nSHA1 class: ";
watch.start();
if(sha1(testFile, hash)){
std::cout<<hash<<"\n";
}
else{
std::cout<<"Error: "<<sha1.getError()<<"\n";
}
watch.takeSample(true);
std::cout<<"\n";
}

return 0;
}
Binary file added performance/performance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added performance/performance_1GB_file.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading