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-18-32.macros

HEADERS_OPTIMIZED_64 = \
    $(HEADERS_OPTIMIZED) \
    Sources/KeccakOpt64-settings.h \
    Sources/KeccakF-1600-18-64.macros \
    Sources/KeccakF-1600-18-simd64.macros \
    Sources/KeccakF-1600-18-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 = -save-temps -fomit-frame-pointer -O3 -g0 -march=nocona -m32

CFLAGS_OPTIMIZED_64 = -save-temps -fomit-frame-pointer -O3 -g0 -march=nocona

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-18-32.macros

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

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

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

.PHONY: eBash keccakr1024c576-opt32 keccakr1024c576-opt64 keccakr1024c576-sse keccakr1024c576-mmx
.PHONY: keccakr1024c576-opt32u18 keccakr1024c576-opt32u9 keccakr1024c576-opt32u6 keccakr1024c576-opt32u3 keccakr1024c576-opt32u2 keccakr1024c576-opt32u6nit keccakr1024c576-opt32u3nit keccakr1024c576-opt32u2nit
.PHONY: keccakr1024c576-opt64u18 keccakr1024c576-opt64u9 keccakr1024c576-opt64u6 keccakr1024c576-opt64u3 keccakr1024c576-opt64u2
.PHONY: keccakr1024c576-sseu6 keccakr1024c576-sseu2
.PHONY: keccakr1024c576-mmxu6 keccakr1024c576-mmxu2 keccakr1024c576-mmxu1

keccakr1024c576-opt32: keccakr1024c576-opt32u18 keccakr1024c576-opt32u6 keccakr1024c576-opt32u3 keccakr1024c576-opt32u2 keccakr1024c576-opt32u6nit keccakr1024c576-opt32u3nit keccakr1024c576-opt32u2nit

keccakr1024c576-opt32u18: eBash/KeccakOpt32-settings-u18.h $(FILES_EBASH_OPT32) eBash/api-keccakr1024c576.h 
	mkdir -p eBash/crypto_hash/keccakr1024c576/opt32u18
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccakr1024c576/opt32u18/
	cp -p eBash/api-keccakr1024c576.h eBash/crypto_hash/keccakr1024c576/opt32u18/api.h
	cp -p eBash/KeccakOpt32-settings-u18.h eBash/crypto_hash/keccakr1024c576/opt32u18/KeccakOpt32-settings.h

keccakr1024c576-opt32u9: eBash/KeccakOpt32-settings-u9.h $(FILES_EBASH_OPT32) eBash/api-keccakr1024c576.h 
	mkdir -p eBash/crypto_hash/keccakr1024c576/opt32u9
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccakr1024c576/opt32u9/
	cp -p eBash/api-keccakr1024c576.h eBash/crypto_hash/keccakr1024c576/opt32u9/api.h
	cp -p eBash/KeccakOpt32-settings-u9.h eBash/crypto_hash/keccakr1024c576/opt32u9/KeccakOpt32-settings.h

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

keccakr1024c576-opt32u3: eBash/KeccakOpt32-settings-u3.h $(FILES_EBASH_OPT32) eBash/api-keccakr1024c576.h 
	mkdir -p eBash/crypto_hash/keccakr1024c576/opt32u3
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccakr1024c576/opt32u3/
	cp -p eBash/api-keccakr1024c576.h eBash/crypto_hash/keccakr1024c576/opt32u3/api.h
	cp -p eBash/KeccakOpt32-settings-u3.h eBash/crypto_hash/keccakr1024c576/opt32u3/KeccakOpt32-settings.h

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

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

keccakr1024c576-opt32u3nit: eBash/KeccakOpt32-settings-u3nit.h $(FILES_EBASH_OPT32) eBash/api-keccakr1024c576.h 
	mkdir -p eBash/crypto_hash/keccakr1024c576/opt32u3nit
	cp -p $(FILES_EBASH_OPT32) eBash/crypto_hash/keccakr1024c576/opt32u3nit/
	cp -p eBash/api-keccakr1024c576.h eBash/crypto_hash/keccakr1024c576/opt32u3nit/api.h
	cp -p eBash/KeccakOpt32-settings-u3nit.h eBash/crypto_hash/keccakr1024c576/opt32u3nit/KeccakOpt32-settings.h

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

keccakr1024c576-opt64: keccakr1024c576-opt64u18 keccakr1024c576-opt64u6

keccakr1024c576-opt64u18: eBash/KeccakOpt64-settings-u18.h $(FILES_EBASH_OPT64) eBash/api-keccakr1024c576.h 
	mkdir -p eBash/crypto_hash/keccakr1024c576/opt64u18
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccakr1024c576/opt64u18/
	cp -p eBash/api-keccakr1024c576.h eBash/crypto_hash/keccakr1024c576/opt64u18/api.h
	cp -p eBash/KeccakOpt64-settings-u18.h eBash/crypto_hash/keccakr1024c576/opt64u18/KeccakOpt64-settings.h

keccakr1024c576-opt64u9: eBash/KeccakOpt64-settings-u9.h $(FILES_EBASH_OPT64) eBash/api-keccakr1024c576.h 
	mkdir -p eBash/crypto_hash/keccakr1024c576/opt64u9
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccakr1024c576/opt64u9/
	cp -p eBash/api-keccakr1024c576.h eBash/crypto_hash/keccakr1024c576/opt64u9/api.h
	cp -p eBash/KeccakOpt64-settings-u9.h eBash/crypto_hash/keccakr1024c576/opt64u9/KeccakOpt64-settings.h

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

keccakr1024c576-opt64u3: eBash/KeccakOpt64-settings-u3.h $(FILES_EBASH_OPT64) eBash/api-keccakr1024c576.h 
	mkdir -p eBash/crypto_hash/keccakr1024c576/opt64u3
	cp -p $(FILES_EBASH_OPT64) eBash/crypto_hash/keccakr1024c576/opt64u3/
	cp -p eBash/api-keccakr1024c576.h eBash/crypto_hash/keccakr1024c576/opt64u3/api.h
	cp -p eBash/KeccakOpt64-settings-u3.h eBash/crypto_hash/keccakr1024c576/opt64u3/KeccakOpt64-settings.h

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

keccakr1024c576-sse: keccakr1024c576-sseu6 keccakr1024c576-sseu2

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

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

keccakr1024c576-mmx: keccakr1024c576-mmxu6 keccakr1024c576-mmxu2 keccakr1024c576-mmxu1

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

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

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

eBash: eBash/keccakr1024c576.tar.gz

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