Initial SHA256 test harness

This commit is contained in:
Stanislav N Mikhailov
2026-03-09 18:35:43 +03:00
commit f0383c9294
8 changed files with 172 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
build/*
!build/Debug/
build/Debug/*
!build/Debug/*.exe
!build/Debug/*.dll
+24
View File
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.20)
project(sha256_client_c LANGUAGES C)
if(NOT WIN32)
message(FATAL_ERROR "This sample is intended for Win64 (DLL import).")
endif()
add_executable(sha256_client
src/main.c
)
target_include_directories(sha256_client PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)
target_link_libraries(sha256_client PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/dll/sha-256.lib
)
add_custom_command(TARGET sha256_client POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/dll/sha-256.dll
$<TARGET_FILE_DIR:sha256_client>/sha-256.dll
)
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+48
View File
@@ -0,0 +1,48 @@
#ifndef SHA256_SHA_H
#define SHA256_SHA_H
#include <stddef.h>
#include <stdint.h>
#ifdef _WIN32
#ifdef SHA256_EXPORTS
#define SHA256_API __declspec(dllexport)
#else
#define SHA256_API __declspec(dllimport)
#endif
#else
#define SHA256_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef uint32_t sha256_digest_t[8];
SHA256_API int TestHello(void);
/*
* Returns NULL (0) on success according to assembly comments.
* data_addr - pointer to current data chunk.
* full_size - total message/file size in bytes.
* current_size - current chunk size in bytes.
* digest - 32-byte state/result buffer (8 x uint32_t).
* is_last_chunk - 1 if this is the last chunk, otherwise 0.
*/
SHA256_API void *Sha256(
const void *data_addr,
uint64_t full_size,
uint64_t current_size,
sha256_digest_t digest,
uint64_t is_last_chunk
);
/* Initializes digest and internal K constants. */
SHA256_API void Sha256Init(sha256_digest_t digest);
#ifdef __cplusplus
}
#endif
#endif /* SHA256_SHA_H */
+95
View File
@@ -0,0 +1,95 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sha.h"
static void print_digest_words(const sha256_digest_t digest) {
for (int i = 0; i < 8; ++i) {
printf("%08x", digest[i]);
}
putchar('\n');
}
int main(void) {
char path[4096] = {0};
sha256_digest_t digest = {0};
if (fgets(path, (int)sizeof(path), stdin) == NULL) {
fprintf(stderr, "Failed to read file path from stdin\n");
return 1;
}
path[strcspn(path, "\r\n")] = '\0';
if (path[0] == '\0') {
fprintf(stderr, "Empty file path\n");
return 1;
}
FILE *fp = fopen(path, "rb");
if (fp == NULL) {
fprintf(stderr, "Failed to open file: %s\n", path);
return 1;
}
if (_fseeki64(fp, 0, SEEK_END) != 0) {
fprintf(stderr, "Failed to seek file end: %s\n", path);
fclose(fp);
return 1;
}
const long long file_size_ll = _ftelli64(fp);
if (file_size_ll < 0) {
fprintf(stderr, "Failed to get file size: %s\n", path);
fclose(fp);
return 1;
}
if (_fseeki64(fp, 0, SEEK_SET) != 0) {
fprintf(stderr, "Failed to seek file start: %s\n", path);
fclose(fp);
return 1;
}
const uint64_t full_size = (uint64_t)file_size_ll;
size_t alloc_size = (size_t)full_size;
if ((uint64_t)alloc_size != full_size) {
fprintf(stderr, "File is too large for this client: %s\n", path);
fclose(fp);
return 1;
}
if (alloc_size == 0) {
alloc_size = 1;
}
unsigned char *data = (unsigned char *)malloc(alloc_size);
if (data == NULL) {
fprintf(stderr, "Out of memory while reading: %s\n", path);
fclose(fp);
return 1;
}
if (full_size > 0) {
const size_t read_size = fread(data, 1, (size_t)full_size, fp);
if (read_size != (size_t)full_size) {
fprintf(stderr, "Failed to read file: %s\n", path);
free(data);
fclose(fp);
return 1;
}
}
fclose(fp);
void *rc = Sha256(data, full_size, full_size, digest, 1);
free(data);
if (rc != 0) {
fprintf(stderr, "Sha256 failed, rc=%p\n", rc);
return 1;
}
printf("Digest (library word order): ");
print_digest_words(digest);
return 0;
}