all: KeccakReference KeccakOptimized32 KeccakOptimized64

SOURCES_COMMON = \
    Sources/genKAT.c \
    Sources/KeccakSponge.c

SOURCES_REFERENCE = \
    $(SOURCES_COMMON) \
    Sources/displayIntermediateValues.c \
    Sources/KeccakPermutationReference.c \
    Sources/mainReference.c

SOURCES_OPTIMIZED = \
    $(SOURCES_COMMON) \
    Sources/mainOptimized.c \
    Sources/timing.c

SOURCES_OPTIMIZED_32 = \
    $(SOURCES_OPTIMIZED) \
    Sources/KeccakPermutationOptimized32.c

SOURCES_OPTIMIZED_64 = \
    $(SOURCES_OPTIMIZED) \
    Sources/KeccakPermutationOptimized64.c

HEADERS_COMMON = \
    Sources/KeccakNISTInterface.h \
    Sources/KeccakPermutationInterface.h

HEADERS_REFERENCE = \
    $(HEADERS_COMMON) \
    Sources/displayIntermediateValues.h \
    Sources/KeccakPermutationReference.h

HEADERS_OPTIMIZED = \
    $(HEADERS_COMMON) \
    Sources/timing.h \
    Sources/brg_endian.h \
    Sources/KeccakPermutationOptimized.macros

HEADERS_OPTIMIZED_32 = \
    $(HEADERS_OPTIMIZED) \
    Sources/KeccakOpt32-settings.h \
    Sources/KeccakF-1600-32.macros

HEADERS_OPTIMIZED_64 = \
    $(HEADERS_OPTIMIZED) \
    Sources/KeccakOpt64-settings.h \
    Sources/KeccakF-1600-64.macros \
    Sources/KeccakF-1600-simd64.macros \
    Sources/KeccakF-1600-simd128.macros

BINDIR_REFERENCE = bin/reference

$(BINDIR_REFERENCE):
	mkdir -p $(BINDIR_REFERENCE)

BINDIR_OPTIMIZED_32 = bin/optimized32

$(BINDIR_OPTIMIZED_32):
	mkdir -p $(BINDIR_OPTIMIZED_32)

BINDIR_OPTIMIZED_64 = bin/optimized64

$(BINDIR_OPTIMIZED_64):
	mkdir -p $(BINDIR_OPTIMIZED_64)

OBJECTS_REFERENCE = $(addprefix $(BINDIR_REFERENCE)/, $(notdir $(patsubst %.c,%.o,$(SOURCES_REFERENCE))))

OBJECTS_OPTIMIZED_32 = $(addprefix $(BINDIR_OPTIMIZED_32)/, $(notdir $(patsubst %.c,%.o,$(SOURCES_OPTIMIZED_32))))

OBJECTS_OPTIMIZED_64 = $(addprefix $(BINDIR_OPTIMIZED_64)/, $(notdir $(patsubst %.c,%.o,$(SOURCES_OPTIMIZED_64))))

CFLAGS_REFERENCE = -DKeccakReference

CFLAGS_OPTIMIZED_32 = -fomit-frame-pointer -O3 -g0 -march=barcelona -m32

CFLAGS_OPTIMIZED_64 = -fomit-frame-pointer -O3 -g0 -march=barcelona

VPATH = Sources

INCLUDES = -ISources

$(BINDIR_REFERENCE)/%.o:%.c $(HEADERS_REFERENCE)
	$(CC) $(INCLUDES) $(CFLAGS_REFERENCE) -c $< -o $@

$(BINDIR_OPTIMIZED_32)/%.o:%.c $(HEADERS_OPTIMIZED_32)
	$(CC) $(INCLUDES) $(CFLAGS_OPTIMIZED_32) -c $< -o $@

$(BINDIR_OPTIMIZED_64)/%.o:%.c $(HEADERS_OPTIMIZED_64)
	$(CC) $(INCLUDES) $(CFLAGS_OPTIMIZED_64) -c $< -o $@

.PHONY: KeccakReference KeccakOptimized32 KeccakOptimized64

KeccakReference: bin/KeccakReference

bin/KeccakReference:  $(BINDIR_REFERENCE) $(OBJECTS_REFERENCE)  $(HEADERS_REFERENCE)
	$(CC) $(CFLAGS_REFERENCE) -o $@ $(OBJECTS_REFERENCE)

KeccakOptimized32: bin/KeccakOptimized32

bin/KeccakOptimized32:  $(BINDIR_OPTIMIZED_32) $(OBJECTS_OPTIMIZED_32)  $(HEADERS_OPTIMIZED_32)
	$(CC) $(CFLAGS_OPTIMIZED_32) -o $@ $(OBJECTS_OPTIMIZED_32)

KeccakOptimized64: bin/KeccakOptimized64

bin/KeccakOptimized64:  $(BINDIR_OPTIMIZED_64) $(OBJECTS_OPTIMIZED_64)  $(HEADERS_OPTIMIZED_64)
	$(CC) $(CFLAGS_OPTIMIZED_64) -o $@ $(OBJECTS_OPTIMIZED_64)

.PHONY: clean

clean:
	rm -rf bin/

FILES_EBASH_COMMON = \
    eBash/hash.c \
    Sources/brg_endian.h \
    Sources/KeccakSponge.c \
    Sources/KeccakNISTInterface.h \
    Sources/KeccakPermutationInterface.h \
    Sources/KeccakPermutationOptimized.macros

FILES_EBASH_OPT32 = \
    $(FILES_EBASH_COMMON) \
    Sources/KeccakPermutationOptimized32.c \
    Sources/KeccakF-1600-32.macros

FILES_EBASH_OPT64 = \
    $(FILES_EBASH_COMMON) \
    Sources/KeccakPermutationOptimized64.c \
    Sources/KeccakF-1600-64.macros

FILES_EBASH_SSE = \
    $(FILES_EBASH_COMMON) \
    Sources/KeccakPermutationOptimized64.c \
    Sources/KeccakF-1600-simd128.macros

FILES_EBASH_MMX = \
    $(FILES_EBASH_COMMON) \
    Sources/KeccakPermutationOptimized64.c \
    Sources/KeccakF-1600-simd64.macros

.PHONY: eBash keccak-opt32 keccak-opt64 keccak-sse keccak-mmx
.PHONY: keccak-opt32u24 keccak-opt32u12 keccak-opt32u6 keccak-opt32u4 keccak-opt32u2 keccak-opt32u6nit keccak-opt32u4nit keccak-opt32u2nit
.PHONY: keccak-opt64u24 keccak-opt64u12 keccak-opt64u6 keccak-opt64u4 keccak-opt64u2
.PHONY: keccak-sseu6 keccak-sseu2
.PHONY: keccak-mmxu6 keccak-mmxu2 keccak-mmxu1

keccak-opt32: keccak-opt32u24 keccak-opt32u6 keccak-opt32u2 keccak-opt32u6nit keccak-opt32u2nit

keccak-opt32u24: eBash/KeccakOpt32-settings-u24.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u24
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u24/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u24/api.h
	cp -p eBash/KeccakOpt32-settings-u24.h eBash/crypto_hash/keccak/opt32u24/KeccakOpt32-settings.h

keccak-opt32u12: eBash/KeccakOpt32-settings-u12.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u12
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u12/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u12/api.h
	cp -p eBash/KeccakOpt32-settings-u12.h eBash/crypto_hash/keccak/opt32u12/KeccakOpt32-settings.h

keccak-opt32u6: eBash/KeccakOpt32-settings-u6.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u6
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u6/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u6/api.h
	cp -p eBash/KeccakOpt32-settings-u6.h eBash/crypto_hash/keccak/opt32u6/KeccakOpt32-settings.h

keccak-opt32u4: eBash/KeccakOpt32-settings-u4.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u4
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u4/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u4/api.h
	cp -p eBash/KeccakOpt32-settings-u4.h eBash/crypto_hash/keccak/opt32u4/KeccakOpt32-settings.h

keccak-opt32u2: eBash/KeccakOpt32-settings-u2.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u2
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u2/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u2/api.h
	cp -p eBash/KeccakOpt32-settings-u2.h eBash/crypto_hash/keccak/opt32u2/KeccakOpt32-settings.h

keccak-opt32u6nit: eBash/KeccakOpt32-settings-u6nit.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u6nit
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u6nit/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u6nit/api.h
	cp -p eBash/KeccakOpt32-settings-u6nit.h eBash/crypto_hash/keccak/opt32u6nit/KeccakOpt32-settings.h

keccak-opt32u4nit: eBash/KeccakOpt32-settings-u4nit.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u4nit
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u4nit/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u4nit/api.h
	cp -p eBash/KeccakOpt32-settings-u4nit.h eBash/crypto_hash/keccak/opt32u4nit/KeccakOpt32-settings.h

keccak-opt32u2nit: eBash/KeccakOpt32-settings-u2nit.h $(FILES_EBASH_OPT32) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt32u2nit
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccak/opt32u2nit/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt32u2nit/api.h
	cp -p eBash/KeccakOpt32-settings-u2nit.h eBash/crypto_hash/keccak/opt32u2nit/KeccakOpt32-settings.h

keccak-opt64: keccak-opt64u24 keccak-opt64u12 keccak-opt64u6

keccak-opt64u24: eBash/KeccakOpt64-settings-u24.h $(FILES_EBASH_OPT64) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt64u24
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccak/opt64u24/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt64u24/api.h
	cp -p eBash/KeccakOpt64-settings-u24.h eBash/crypto_hash/keccak/opt64u24/KeccakOpt64-settings.h

keccak-opt64u12: eBash/KeccakOpt64-settings-u12.h $(FILES_EBASH_OPT64) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt64u12
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccak/opt64u12/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt64u12/api.h
	cp -p eBash/KeccakOpt64-settings-u12.h eBash/crypto_hash/keccak/opt64u12/KeccakOpt64-settings.h

keccak-opt64u6: eBash/KeccakOpt64-settings-u6.h $(FILES_EBASH_OPT64) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt64u6
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccak/opt64u6/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt64u6/api.h
	cp -p eBash/KeccakOpt64-settings-u6.h eBash/crypto_hash/keccak/opt64u6/KeccakOpt64-settings.h

keccak-opt64u4: eBash/KeccakOpt64-settings-u4.h $(FILES_EBASH_OPT64) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt64u4
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccak/opt64u4/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt64u4/api.h
	cp -p eBash/KeccakOpt64-settings-u4.h eBash/crypto_hash/keccak/opt64u4/KeccakOpt64-settings.h

keccak-opt64u2: eBash/KeccakOpt64-settings-u2.h $(FILES_EBASH_OPT64) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/opt64u2
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccak/opt64u2/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/opt64u2/api.h
	cp -p eBash/KeccakOpt64-settings-u2.h eBash/crypto_hash/keccak/opt64u2/KeccakOpt64-settings.h

keccak-sse: keccak-sseu6 keccak-sseu2

keccak-sseu6: eBash/KeccakOpt64-settings-sseu6.h $(FILES_EBASH_SSE) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/sseu6
	cp -p $(FILES_EBASH_SSE) eBash/crypto_hash/keccak/sseu6/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/sseu6/api.h
	cp -p eBash/KeccakOpt64-settings-sseu6.h eBash/crypto_hash/keccak/sseu6/KeccakOpt64-settings.h

keccak-sseu2: eBash/KeccakOpt64-settings-sseu2.h $(FILES_EBASH_SSE) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/sseu2
	cp -p $(FILES_EBASH_SSE) eBash/crypto_hash/keccak/sseu2/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/sseu2/api.h
	cp -p eBash/KeccakOpt64-settings-sseu2.h eBash/crypto_hash/keccak/sseu2/KeccakOpt64-settings.h

keccak-mmx: keccak-mmxu2 keccak-mmxu1

keccak-mmxu6: eBash/KeccakOpt64-settings-mmxu6.h $(FILES_EBASH_MMX) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/mmxu6
	cp -p $(FILES_EBASH_MMX) eBash/crypto_hash/keccak/mmxu6/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/mmxu6/api.h
	cp -p eBash/KeccakOpt64-settings-mmxu6.h eBash/crypto_hash/keccak/mmxu6/KeccakOpt64-settings.h

keccak-mmxu2: eBash/KeccakOpt64-settings-mmxu2.h $(FILES_EBASH_MMX) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/mmxu2
	cp -p $(FILES_EBASH_MMX) eBash/crypto_hash/keccak/mmxu2/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/mmxu2/api.h
	cp -p eBash/KeccakOpt64-settings-mmxu2.h eBash/crypto_hash/keccak/mmxu2/KeccakOpt64-settings.h

keccak-mmxu1: eBash/KeccakOpt64-settings-mmxu1.h $(FILES_EBASH_MMX) eBash/api-keccak.h
	mkdir -p eBash/crypto_hash/keccak/mmxu1
	cp -p $(FILES_EBASH_MMX) eBash/crypto_hash/keccak/mmxu1/
	cp -p eBash/api-keccak.h eBash/crypto_hash/keccak/mmxu1/api.h
	cp -p eBash/KeccakOpt64-settings-mmxu1.h eBash/crypto_hash/keccak/mmxu1/KeccakOpt64-settings.h

eBash: eBash/keccak.tar.gz

eBash/keccak.tar.gz: keccak-opt32 keccak-opt64 keccak-sse keccak-mmx
	cd eBash ; tar -cvzf keccak.tar.gz crypto_hash/
