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
42 changes: 21 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ BIN_DIR=./bin
CC=gcc
COMPILERS=gcc-4.8 gcc-4.9 gcc-5 gcc-6
OPT=-O3
CFLAGS=$(OPT) -g -Wall -Werror -std=c99
ALL_CFLAGS=$(OPT) -g -Wall -Werror -std=c99 $(CFLAGS)

PERF_TXT=$(BIN_DIR)/perfexample.txt
# Number of perf stat iterations
Expand Down Expand Up @@ -53,61 +53,61 @@ all-compiler: $(BINS)

# Objects - Not using %.o as X64 wouldn't compile
$(BIN_DIR)/sha256_compress_c_$(SUFFIX).o: sha2_compress_c.c base-types.h sha2_compress.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(BIN_DIR)/sha512_compress_c_$(SUFFIX).o: sha2_compress_c.c base-types.h sha2_compress.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=512 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=512 -o $@

$(BIN_DIR)/sha256_c_$(SUFFIX).o: sha2_compress_c.c sha2_common.h base-types.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(BIN_DIR)/sha512_c_$(SUFFIX).o: sha2_compress_c.c sha2_common.h base-types.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=512 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=512 -o $@

$(BIN_DIR)/sha256_$(SUFFIX).o: sha2.c sha2_common.h base-types.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(BIN_DIR)/sha512_$(SUFFIX).o: sha2.c sha2_common.h base-types.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=512 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=512 -o $@

$(BIN_DIR)/sha256_common_$(SUFFIX).o: sha2_common.c sha2_compress.h base-types.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(BIN_DIR)/sha512_common_$(SUFFIX).o: sha2_common.c sha2_compress.h base-types.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=512 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=512 -o $@

ifeq (x$(ARCH),xppc64le)
sha256_compress_ppc.s: common.m4 sha256_compress_ppc.m4 # Order matters!
m4 $^ > $@
$(BIN_DIR)/sha256_compress_$(SUFFIX).o: sha256_compress_ppc.s
$(CC) $(CFLAGS) -c $< -o $@
$(CC) $(ALL_CFLAGS) -c $< -o $@
$(BIN_DIR)/sha512_compress_$(SUFFIX).o: sha512_compress.c base-types.h sha2_compress.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=512 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=512 -o $@

$(BIN_DIR)/test256_$(SUFFIX).o: tests.c base-types.h sha2_common.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=256 -o $@
$(BIN_DIR)/test512_$(SUFFIX).o: tests.c base-types.h sha2_common.h
$(CC) $(CFLAGS) -c $< -DSHA_BITS=512 -o $@
$(CC) $(ALL_CFLAGS) -c $< -DSHA_BITS=512 -o $@
endif


# Binaries
$(BIN_DIR)/sha256_libcrypto_$(SUFFIX): sha2.c
$(CC) $(CFLAGS) $^ -DSHA_BITS=256 -DLIBCRYPTO -o $@ -lcrypto
$(CC) $(ALL_CFLAGS) $^ -DSHA_BITS=256 -DLIBCRYPTO -o $@ -lcrypto
$(BIN_DIR)/sha512_libcrypto_$(SUFFIX): sha2.c
$(CC) $(CFLAGS) $^ -DSHA_BITS=512 -DLIBCRYPTO -o $@ -lcrypto
$(CC) $(ALL_CFLAGS) $^ -DSHA_BITS=512 -DLIBCRYPTO -o $@ -lcrypto

$(BIN_DIR)/sha256_c_$(SUFFIX): $(BIN_DIR)/sha256_c_$(SUFFIX).o $(BIN_DIR)/sha256_$(SUFFIX).o $(BIN_DIR)/sha256_common_$(SUFFIX).o
$(CC) $(CFLAGS) $^ -o $@
$(CC) $(ALL_CFLAGS) $^ -o $@
$(BIN_DIR)/sha512_c_$(SUFFIX): $(BIN_DIR)/sha512_c_$(SUFFIX).o $(BIN_DIR)/sha512_$(SUFFIX).o $(BIN_DIR)/sha512_common_$(SUFFIX).o
$(CC) $(CFLAGS) $^ -o $@
$(CC) $(ALL_CFLAGS) $^ -o $@

ifeq (x$(ARCH),xppc64le)
$(BIN_DIR)/sha256_$(SUFFIX): $(BIN_DIR)/sha256_$(SUFFIX).o $(BIN_DIR)/sha256_compress_$(SUFFIX).o $(BIN_DIR)/sha256_common_$(SUFFIX).o
$(CC) $(CFLAGS) $^ -o $@
$(CC) $(ALL_CFLAGS) $^ -o $@
$(BIN_DIR)/sha512_$(SUFFIX): $(BIN_DIR)/sha512_$(SUFFIX).o $(BIN_DIR)/sha512_compress_$(SUFFIX).o $(BIN_DIR)/sha512_common_$(SUFFIX).o
$(CC) $(CFLAGS) $^ -o $@
$(CC) $(ALL_CFLAGS) $^ -o $@

$(BIN_DIR)/test256_$(SUFFIX): $(BIN_DIR)/test256_$(SUFFIX).o $(BIN_DIR)/sha256_common_$(SUFFIX).o $(BIN_DIR)/sha256_compress_$(SUFFIX).o
$(CC) $(CFLAGS) $^ -o $@
$(CC) $(ALL_CFLAGS) $^ -o $@
$(BIN_DIR)/test512_$(SUFFIX): $(BIN_DIR)/test512_$(SUFFIX).o $(BIN_DIR)/sha512_common_$(SUFFIX).o $(BIN_DIR)/sha512_compress_$(SUFFIX).o
$(CC) $(CFLAGS) $^ -o $@
$(CC) $(ALL_CFLAGS) $^ -o $@
endif

test-compiler: $(BINS) $(TESTS)
Expand Down
76 changes: 68 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,74 @@
# This project is about SHA256 and SHA512 implementations and optimizations
# SHA256 and SHA512 Power implementations

The focus of this project is creating an optimized code for IBM POWER
architecture, especifically using ABI v2 (Little Endian), aka ppc64le.
The project creates optimized code for IBM POWER architecture, specifically using ABI v2 (Little Endian), a.k.a. ppc64le.

This is a generic project and self-contained now. We are going to start
backporting it to different Languages and JIT projects. Our initial
target at this moment is the following list:
This is a generic project and self-contained now. We are going to start backporting it to different languages and JIT projects. Our initial target at this moment is the following list:

- OpenJDK
- nettle
- Nettle
- Cryptopp
- ...

## Building the project

To build the project run `make`. You can edit `COMPILERS` in the `Makefile` to suit your taste. You can also override the `COMPILERS` variable from the command line. For example:

```
$ make COMPILERS=gcc
$ make COMPILERS=gcc
mkdir -p ./bin
make[1]: Entering directory `/home/test/sha2-le'
gcc -O3 -g -Wall -Werror -std=c99 sha2.c -DSHA_BITS=256 -DLIBCRYPTO -o bin/sha256_libcrypto_gcc -lcrypto
gcc -O3 -g -Wall -Werror -std=c99 -c sha2_compress_c.c -DSHA_BITS=256 -o bin/sha256_c_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 -c sha2.c -DSHA_BITS=256 -o bin/sha256_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 -c sha2_common.c -DSHA_BITS=256 -o bin/sha256_common_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 bin/sha256_c_gcc.o bin/sha256_gcc.o bin/sha256_common_gcc.o -o bin/sha256_c_gcc
m4 common.m4 sha256_compress_ppc.m4 > sha256_compress_ppc.s
gcc -O3 -g -Wall -Werror -std=c99 -c sha256_compress_ppc.s -o bin/sha256_compress_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 bin/sha256_gcc.o bin/sha256_compress_gcc.o bin/sha256_common_gcc.o -o bin/sha256_gcc
gcc -O3 -g -Wall -Werror -std=c99 sha2.c -DSHA_BITS=512 -DLIBCRYPTO -o bin/sha512_libcrypto_gcc -lcrypto
gcc -O3 -g -Wall -Werror -std=c99 -c sha2_compress_c.c -DSHA_BITS=512 -o bin/sha512_c_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 -c sha2.c -DSHA_BITS=512 -o bin/sha512_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 -c sha2_common.c -DSHA_BITS=512 -o bin/sha512_common_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 bin/sha512_c_gcc.o bin/sha512_gcc.o bin/sha512_common_gcc.o -o bin/sha512_c_gcc
gcc -O3 -g -Wall -Werror -std=c99 -c sha512_compress.c -DSHA_BITS=512 -o bin/sha512_compress_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 bin/sha512_gcc.o bin/sha512_compress_gcc.o bin/sha512_common_gcc.o -o bin/sha512_gcc
make[1]: Leaving directory `/home/test/sha2-le'
```

You can clean the project by removing the `/bin` directory.

## Testing the project

To test the project run `make test`. Use the same `COMPILERS` value that was used when building the project.

```
$ make COMPILERS=gcc test
mkdir -p ./bin
make[1]: Entering directory `/home/test/sha2-le'
make[1]: Nothing to be done for `all-compiler'.
make[1]: Leaving directory `/home/test/sha2-le'
make[1]: Entering directory `/home/test/sha2-le'
gcc -O3 -g -Wall -Werror -std=c99 -c tests.c -DSHA_BITS=256 -o bin/test256_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 bin/test256_gcc.o bin/sha256_common_gcc.o bin/sha256_compress_gcc.o -o bin/test256_gcc
gcc -O3 -g -Wall -Werror -std=c99 -c tests.c -DSHA_BITS=512 -o bin/test512_gcc.o
gcc -O3 -g -Wall -Werror -std=c99 bin/test512_gcc.o bin/sha512_common_gcc.o bin/sha512_compress_gcc.o -o bin/test512_gcc
=======================================================================
Testing gcc
=======================================================================
./bin/test256_gcc
./bin/test512_gcc
CC=gcc ./blackbox-test.sh
Running tests for SHA-256:
Test #1: sha2-le is Ok libcrypto is Ok c is Ok
Test #2: sha2-le is Ok libcrypto is Ok c is Ok
Test #3: sha2-le is Ok libcrypto is Ok c is Ok
Test #4: sha2-le is Ok libcrypto is Ok c is Ok

Running tests for SHA-512:
Test #1: sha2-le is Ok libcrypto is Ok c is Ok
Test #2: sha2-le is Ok libcrypto is Ok c is Ok
Test #3: sha2-le is Ok libcrypto is Ok c is Ok
Test #4: sha2-le is Ok libcrypto is Ok c is Ok

make[1]: Leaving directory `/home/test/sha2-le'
```
22 changes: 12 additions & 10 deletions base-types.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#ifndef _PPC64_LE_BASE_TYPES_H_
#define _PPC64_LE_BASE_TYPES_H_
#ifndef PPC64_LE_BASE_TYPES_H
#define PPC64_LE_BASE_TYPES_H

#include <stdint.h>
#include <stdlib.h>

#if defined(__powerpc64__)
#if defined(__powerpc64__) || defined(__ALTIVEC__)
#include <altivec.h>
#else
// dummy define to avoid errors on x64 compilation
Expand All @@ -13,16 +13,18 @@

#if SHA_BITS == 256
typedef unsigned int base_type;
const base_type k[64];
typedef vector unsigned int vector_base_type;
extern const base_type h[8];
extern const base_type k[64];
static const size_t W_SIZE = 64;
#elif SHA_BITS == 512
typedef unsigned long long base_type;
const base_type k[80];
typedef vector unsigned long long vector_base_type;
extern const base_type h[8];
extern const base_type k[80];
static const size_t W_SIZE = 80;
#endif // SHA_BITS

base_type _h[8];
const size_t W_SIZE;

static const size_t base_type_size = sizeof(base_type);
typedef vector base_type vector_base_type;

#endif // _PPC64_LE_BASE_TYPES_H_
#endif // PPC64_LE_BASE_TYPES_H
21 changes: 9 additions & 12 deletions sha2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ const base_type k[64] = {
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
const size_t W_SIZE = 64;

#elif SHA_BITS == 512

Expand Down Expand Up @@ -73,7 +72,6 @@ const base_type k[80] = {
0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
0x5fcb6fab3ad6faec, 0x6c44198c4a475817
};
const size_t W_SIZE = 80;

#else
#error "Invalid SHA_BITS"
Expand Down Expand Up @@ -114,15 +112,14 @@ void swap_bytes(unsigned char *input, unsigned char *output, size_t size) {
base_type *input_cast = (base_type*)input+i;
base_type *output_cast = (base_type*)output+i;

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__

#if __LITTLE_ENDIAN__
*output_cast =
#if SHA_BITS == 256
# if SHA_BITS == 256
(*input_cast & 0xFF000000) >> 24 |
(*input_cast & 0x00FF0000) >> 8 |
(*input_cast & 0x0000FF00) << 8 |
(*input_cast & 0x000000FF) << 24;
#elif SHA_BITS == 512
# elif SHA_BITS == 512
(*input_cast & 0xFF00000000000000ULL) >> 56 |
(*input_cast & 0x00FF000000000000ULL) >> 40 |
(*input_cast & 0x0000FF0000000000ULL) >> 24 |
Expand All @@ -131,20 +128,20 @@ void swap_bytes(unsigned char *input, unsigned char *output, size_t size) {
(*input_cast & 0x0000000000FF0000ULL) << 24 |
(*input_cast & 0x000000000000FF00ULL) << 40 |
(*input_cast & 0x00000000000000FFULL) << 56;
#endif // SHA_BITS
}
# endif // SHA_BITS
#else
#error "Little endian only"
memcpy(output_cast, input_cast, sizeof(base_type));
#endif
}
}

void write_size(unsigned char *input, size_t size, size_t position) {
base_type* total_size = (base_type*)&input[position];
// Undefined for SHA512. Right shift count >= width of type (uint64_t)
const unsigned long long bit_size = size * 8;
#if SHA_BITS == 256
*total_size = (base_type)((size * 8) >> 32); // higher bits
*total_size = (base_type)(bit_size >> 32); // higher bits
#endif
*(++total_size) = (base_type)size * 8; // lower bits
*(++total_size) = (base_type)bit_size; // lower bits
}

int sha2(unsigned char *input, size_t size, size_t padded_size) {
Expand Down
6 changes: 3 additions & 3 deletions sha2_common.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef _PPC64_LE_SHA2_H_
#define _PPC64_LE_SHA2_H_
#ifndef PPC64_LE_SHA2_H
#define PPC64_LE_SHA2_H

#include <stdio.h>
#include <string.h>
Expand All @@ -22,5 +22,5 @@ int sha2(unsigned char *input, size_t size, size_t padded_size);
#define BLOCK_SIZE 128
#define sha2_compress sha512_compress
#endif
#endif // _PPC64_LE_SHA2_H_
#endif // PPC64_LE_SHA2_H

6 changes: 3 additions & 3 deletions sha2_compress.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef _PPC64_LE_SHA2_COMPRESS_H_
#define _PPC64_LE_SHA2_COMPRESS_H_
#ifndef PPC64_LE_SHA2_COMPRESS_H
#define PPC64_LE_SHA2_COMPRESS_H

#include "base-types.h"

Expand All @@ -14,4 +14,4 @@ void sha512_compress(base_type* _h, const unsigned char* w, const base_type *k);

#endif

#endif // _PPC64_LE_SHA2_COMPRESS_H_
#endif // PPC64_LE_SHA2_COMPRESS_H