/*
 *
 * University of Luxembourg
 * Laboratory of Algorithmics, Cryptology and Security (LACS)
 *
 * FELICS - Fair Evaluation of Lightweight Cryptographic Systems
 *
 * Copyright (C) 2015 University of Luxembourg
 *
 * Written in 2015 by Daniel Dinu <dumitru-daniel.dinu@uni.lu>
 *
 * This file is part of FELICS.
 *
 * FELICS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * FELICS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef AVR_MACROS_H
#define AVR_MACROS_H


#include "stringify.h"


#define EKS_STORE_ROUND_KEYS_(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15) \
    st z+, k0                                                                                  \n\t \
    st z+, k1                                                                                  \n\t \
    st z+, k2                                                                                  \n\t \
    st z+, k3                                                                                  \n\t \
                                                                                                    \
    st z+, k4                                                                                  \n\t \
    st z+, k5                                                                                  \n\t \
    st z+, k6                                                                                  \n\t \
    st z+, k7                                                                                  \n\t \
                                                                                                    \
    st z+, k8                                                                                  \n\t \
    st z+, k9                                                                                  \n\t \
    st z+, k10                                                                                 \n\t \
    st z+, k11                                                                                 \n\t \
                                                                                                    \
    st z+, k12                                                                                 \n\t \
    st z+, k13                                                                                 \n\t \
    st z+, k14                                                                                 \n\t \
    st z+, k15                                                                                 \n\t


#define EKS_ROUND_KEYS_(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, temp, c) \
    eor k8, k9                                                                                    \n\t \
    eor k9, k8                                                                                    \n\t \
    eor k8, k9                                                                                    \n\t \
    lsl k8                                                                                        \n\t \
    rol k9                                                                                        \n\t \
    adc k8, __zero_reg__                                                                          \n\t \
                                                                                                       \
    add k8, k10                                                                                   \n\t \
    adc k9, k11                                                                                   \n\t \
                                                                                                       \
    lsl k10                                                                                       \n\t \
    rol k11                                                                                       \n\t \
    adc k10, __zero_reg__                                                                         \n\t \
    lsl k10                                                                                       \n\t \
    rol k11                                                                                       \n\t \
    adc k10, __zero_reg__                                                                         \n\t \
                                                                                                       \
    eor k10, k8                                                                                   \n\t \
    eor k11, k9                                                                                   \n\t \
                                                                                                       \
                                                                                                       \
    eor k0, k1                                                                                    \n\t \
    eor k1, k0                                                                                    \n\t \
    eor k0, k1                                                                                    \n\t \
    lsl k0                                                                                        \n\t \
    rol k1                                                                                        \n\t \
    adc k0, __zero_reg__                                                                          \n\t \
                                                                                                       \
    add k0, k2                                                                                    \n\t \
    adc k1, k3                                                                                    \n\t \
                                                                                                       \
    lsl k2                                                                                        \n\t \
    rol k3                                                                                        \n\t \
    adc k2, __zero_reg__                                                                          \n\t \
    lsl k2                                                                                        \n\t \
    rol k3                                                                                        \n\t \
    adc k2, __zero_reg__                                                                          \n\t \
                                                                                                       \
    eor k2, k0                                                                                    \n\t \
    eor k3, k1                                                                                    \n\t \
                                                                                                       \
                                                                                                       \
    add k12, k8                                                                                   \n\t \
    adc k13, k9                                                                                   \n\t \
                                                                                                       \
    add k14, k10                                                                                  \n\t \
    adc k15, k11                                                                                  \n\t \
                                                                                                       \
    add k14, c                                                                                    \n\t \
    adc k15, __zero_reg__                                                                         \n\t \
                                                                                                       \
                                                                                                       \
    add k4, k0                                                                                    \n\t \
    adc k5, k1                                                                                    \n\t \
                                                                                                       \
    add k6, k2                                                                                    \n\t \
    adc k7, k3                                                                                    \n\t \
                                                                                                       \
                                                                                                       \
    mov temp, k15                                                                                 \n\t \
    mov k15, k11                                                                                  \n\t \
    mov k11, k7                                                                                   \n\t \
    mov k7, k3                                                                                    \n\t \
    mov k3, temp                                                                                  \n\t \
                                                                                                       \
    mov temp, k14                                                                                 \n\t \
    mov k14, k10                                                                                  \n\t \
    mov k10, k6                                                                                   \n\t \
    mov k6, k2                                                                                    \n\t \
    mov k2, temp                                                                                  \n\t \
                                                                                                       \
    mov temp, k13                                                                                 \n\t \
    mov k13, k9                                                                                   \n\t \
    mov k9, k5                                                                                    \n\t \
    mov k5, k1                                                                                    \n\t \
    mov k1, temp                                                                                  \n\t \
                                                                                                       \
    mov temp, k12                                                                                 \n\t \
    mov k12, k8                                                                                   \n\t \
    mov k8, k4                                                                                    \n\t \
    mov k4, k0                                                                                    \n\t \
    mov k0, temp                                                                                  \n\t


#if defined(SCENARIO) && (SCENARIO_2 == SCENARIO)
#define ENC_ADD_ROUND_KEY_(b0, b1, b2, b3, rk) \
    lpm rk, z+                            \n\t \
    eor b0, rk                            \n\t \
                                               \
    lpm rk, z+                            \n\t \
    eor b1, rk                            \n\t \
                                               \
    lpm rk, z+                            \n\t \
    eor b2, rk                            \n\t \
                                               \
    lpm rk, z+                            \n\t \
    eor b3, rk                            \n\t
#else
#define ENC_ADD_ROUND_KEY_(b0, b1, b2, b3, rk) \
    ld rk, z+                             \n\t \
    eor b0, rk                            \n\t \
                                               \
    ld rk, z+                             \n\t \
    eor b1, rk                            \n\t \
                                               \
    ld rk, z+                             \n\t \
    eor b2, rk                            \n\t \
                                               \
    ld rk, z+                             \n\t \
    eor b3, rk                            \n\t
#endif

#if defined(SCENARIO) && (SCENARIO_2 == SCENARIO)
#define DEC_ADD_ROUND_KEY_(b0, b1, b2, b3, rk) \
    lpm rk, z+                            \n\t \
    eor b3, rk                            \n\t \
                                               \
    lpm rk, z+                            \n\t \
    eor b2, rk                            \n\t \
                                               \
    lpm rk, z+                            \n\t \
    eor b1, rk                            \n\t \
                                               \
    lpm rk, z+                            \n\t \
    eor b0, rk                            \n\t \
                                               \
    sbiw r30, 8                            \n\t
#else
#define DEC_ADD_ROUND_KEY_(b0, b1, b2, b3, rk) \
    ld rk, -z                             \n\t \
    eor b3, rk                            \n\t \
                                               \
    ld rk, -z                             \n\t \
    eor b2, rk                            \n\t \
                                               \
    ld rk, -z                             \n\t \
    eor b1, rk                            \n\t \
                                               \
    ld rk, -z                             \n\t \
    eor b0, rk                            \n\t
#endif


#define ENC_A_(b0, b1, b2, b3) \
    eor b0, b1            \n\t \
    eor b1, b0            \n\t \
    eor b0, b1            \n\t \
    lsl b0                \n\t \
    rol b1                \n\t \
    adc b0, __zero_reg__  \n\t \
                               \
    add b0, b2            \n\t \
    adc b1, b3            \n\t \
                               \
    lsl b2                \n\t \
    rol b3                \n\t \
    adc b2, __zero_reg__  \n\t \
    lsl b2                \n\t \
    rol b3                \n\t \
    adc b2, __zero_reg__  \n\t \
                               \
    eor b2, b0            \n\t \
    eor b3, b1            \n\t

#define DEC_A_(b0, b1, b2, b3) \
    eor b2, b0            \n\t \
    eor b3, b1            \n\t \
                               \
    bst b2, 0             \n\t \
    ror b3                \n\t \
    ror b2                \n\t \
    bld b3, 7             \n\t \
    bst b2, 0             \n\t \
    ror b3                \n\t \
    ror b2                \n\t \
    bld b3, 7             \n\t \
                               \
    sub b0, b2            \n\t \
    sbc b1, b3            \n\t \
                               \
    eor b0, b1            \n\t \
    eor b1, b0            \n\t \
    eor b0, b1            \n\t \
    bst b1, 0             \n\t \
    ror b0                \n\t \
    ror b1                \n\t \
    bld b0, 7             \n\t


#define ENC_L_(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, temp) \
    eor b8, b1                                                                        \n\t \
    eor b8, b3                                                                        \n\t \
    eor b8, b4                                                                        \n\t \
    eor b8, b5                                                                        \n\t \
    eor b8, b7                                                                        \n\t \
                                                                                           \
    eor b9, b0                                                                        \n\t \
    eor b9, b2                                                                        \n\t \
    eor b9, b4                                                                        \n\t \
    eor b9, b5                                                                        \n\t \
    eor b9, b6                                                                        \n\t \
                                                                                           \
    eor b10, b1                                                                       \n\t \
    eor b10, b2                                                                       \n\t \
    eor b10, b3                                                                       \n\t \
    eor b10, b5                                                                       \n\t \
    eor b10, b7                                                                       \n\t \
                                                                                           \
    eor b11, b0                                                                       \n\t \
    eor b11, b2                                                                       \n\t \
    eor b11, b3                                                                       \n\t \
    eor b11, b4                                                                       \n\t \
    eor b11, b6                                                                       \n\t \
                                                                                           \
    eor b12, b0                                                                       \n\t \
    eor b12, b1                                                                       \n\t \
    eor b12, b3                                                                       \n\t \
    eor b12, b5                                                                       \n\t \
    eor b12, b7                                                                       \n\t \
                                                                                           \
    eor b13, b0                                                                       \n\t \
    eor b13, b1                                                                       \n\t \
    eor b13, b2                                                                       \n\t \
    eor b13, b4                                                                       \n\t \
    eor b13, b6                                                                       \n\t \
                                                                                           \
    eor b14, b1                                                                       \n\t \
    eor b14, b3                                                                       \n\t \
    eor b14, b5                                                                       \n\t \
    eor b14, b6                                                                       \n\t \
    eor b14, b7                                                                       \n\t \
                                                                                           \
    eor b15, b0                                                                       \n\t \
    eor b15, b2                                                                       \n\t \
    eor b15, b4                                                                       \n\t \
    eor b15, b6                                                                       \n\t \
    eor b15, b7                                                                       \n\t \
                                                                                           \
                                                                                           \
    mov temp, b0                                                                      \n\t \
    mov b0, b8                                                                        \n\t \
    mov b8, temp                                                                      \n\t \
                                                                                           \
    mov temp, b1                                                                      \n\t \
    mov b1, b9                                                                        \n\t \
    mov b9, temp                                                                      \n\t \
                                                                                           \
    mov temp, b2                                                                      \n\t \
    mov b2, b10                                                                       \n\t \
    mov b10, temp                                                                     \n\t \
                                                                                           \
    mov temp, b3                                                                      \n\t \
    mov b3, b11                                                                       \n\t \
    mov b11, temp                                                                     \n\t \
                                                                                           \
    mov temp, b4                                                                      \n\t \
    mov b4, b12                                                                       \n\t \
    mov b12, temp                                                                     \n\t \
                                                                                           \
    mov temp, b5                                                                      \n\t \
    mov b5, b13                                                                       \n\t \
    mov b13, temp                                                                     \n\t \
                                                                                           \
    mov temp, b6                                                                      \n\t \
    mov b6, b14                                                                       \n\t \
    mov b14, temp                                                                     \n\t \
                                                                                           \
    mov temp, b7                                                                      \n\t \
    mov b7, b15                                                                       \n\t \
    mov b15, temp                                                                     \n\t


#define DEC_L_(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, temp) \
    eor b0, b9                                                                        \n\t \
    eor b0, b11                                                                        \n\t \
    eor b0, b12                                                                        \n\t \
    eor b0, b13                                                                        \n\t \
    eor b0, b15                                                                        \n\t \
                                                                                           \
    eor b1, b8                                                                        \n\t \
    eor b1, b10                                                                        \n\t \
    eor b1, b12                                                                        \n\t \
    eor b1, b13                                                                        \n\t \
    eor b1, b14                                                                        \n\t \
                                                                                           \
    eor b2, b9                                                                       \n\t \
    eor b2, b10                                                                       \n\t \
    eor b2, b11                                                                       \n\t \
    eor b2, b13                                                                       \n\t \
    eor b2, b15                                                                       \n\t \
                                                                                           \
    eor b3, b8                                                                       \n\t \
    eor b3, b10                                                                       \n\t \
    eor b3, b11                                                                       \n\t \
    eor b3, b12                                                                       \n\t \
    eor b3, b14                                                                       \n\t \
                                                                                           \
    eor b4, b8                                                                       \n\t \
    eor b4, b9                                                                       \n\t \
    eor b4, b11                                                                       \n\t \
    eor b4, b13                                                                       \n\t \
    eor b4, b15                                                                       \n\t \
                                                                                           \
    eor b5, b8                                                                       \n\t \
    eor b5, b9                                                                       \n\t \
    eor b5, b10                                                                       \n\t \
    eor b5, b12                                                                       \n\t \
    eor b5, b14                                                                       \n\t \
                                                                                           \
    eor b6, b9                                                                       \n\t \
    eor b6, b11                                                                       \n\t \
    eor b6, b13                                                                       \n\t \
    eor b6, b14                                                                       \n\t \
    eor b6, b15                                                                       \n\t \
                                                                                           \
    eor b7, b8                                                                       \n\t \
    eor b7, b10                                                                       \n\t \
    eor b7, b12                                                                       \n\t \
    eor b7, b14                                                                       \n\t \
    eor b7, b15                                                                       \n\t \
                                                                                           \
                                                                                           \
    mov temp, b0                                                                      \n\t \
    mov b0, b8                                                                        \n\t \
    mov b8, temp                                                                      \n\t \
                                                                                           \
    mov temp, b1                                                                      \n\t \
    mov b1, b9                                                                        \n\t \
    mov b9, temp                                                                      \n\t \
                                                                                           \
    mov temp, b2                                                                      \n\t \
    mov b2, b10                                                                       \n\t \
    mov b10, temp                                                                     \n\t \
                                                                                           \
    mov temp, b3                                                                      \n\t \
    mov b3, b11                                                                       \n\t \
    mov b11, temp                                                                     \n\t \
                                                                                           \
    mov temp, b4                                                                      \n\t \
    mov b4, b12                                                                       \n\t \
    mov b12, temp                                                                     \n\t \
                                                                                           \
    mov temp, b5                                                                      \n\t \
    mov b5, b13                                                                       \n\t \
    mov b13, temp                                                                     \n\t \
                                                                                           \
    mov temp, b6                                                                      \n\t \
    mov b6, b14                                                                       \n\t \
    mov b14, temp                                                                     \n\t \
                                                                                           \
    mov temp, b7                                                                      \n\t \
    mov b7, b15                                                                       \n\t \
    mov b15, temp                                                                     \n\t


#if defined(SCENARIO) && (SCENARIO_2 == SCENARIO)
#define ENC_ADD_WHITENING_KEY_(b0, b1, b2, b3, rk) \
    lpm rk, z+                                \n\t \
    eor b0, rk                                \n\t \
                                                   \
    lpm rk, z+                                \n\t \
    eor b1, rk                                \n\t \
                                                   \
    lpm rk, z+                                \n\t \
    eor b2, rk                                \n\t \
                                                   \
    lpm rk, z+                                \n\t \
    eor b3, rk                                \n\t
#else
#define ENC_ADD_WHITENING_KEY_(b0, b1, b2, b3, rk) \
    ld rk, z+                                 \n\t \
    eor b0, rk                                \n\t \
                                                   \
    ld rk, z+                                 \n\t \
    eor b1, rk                                \n\t \
                                                   \
    ld rk, z+                                 \n\t \
    eor b2, rk                                \n\t \
                                                   \
    ld rk, z+                                 \n\t \
    eor b3, rk                                \n\t
#endif

#if defined(SCENARIO) && (SCENARIO_2 == SCENARIO)
#define DEC_ADD_WHITENING_KEY_(b0, b1, b2, b3, rk) \
    lpm rk, z+                                \n\t \
    eor b0, rk                                \n\t \
                                                   \
    lpm rk, z+                                \n\t \
    eor b1, rk                                \n\t \
                                                   \
    lpm rk, z+                                \n\t \
    eor b2, rk                                \n\t \
                                                   \
    lpm rk, z+                                \n\t \
    eor b3, rk                                \n\t \
                                                   \
    sbiw r30, 8                               \n\t
#else
#define DEC_ADD_WHITENING_KEY_(b0, b1, b2, b3, rk) \
    ld rk, -z                                 \n\t \
    eor b3, rk                                \n\t \
                                                   \
    ld rk, -z                                 \n\t \
    eor b2, rk                                \n\t \
                                                   \
    ld rk, -z                                 \n\t \
    eor b1, rk                                \n\t \
                                                   \
    ld rk, -z                                 \n\t \
    eor b0, rk                                \n\t
#endif


#define EKS_STORE_ROUND_KEYS(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15) \
    STR(EKS_STORE_ROUND_KEYS_(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15))


#define EKS_ROUND_KEYS(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, temp, c) \
    STR(EKS_ROUND_KEYS_(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, temp, c))


#define ENC_ADD_ROUND_KEY(b0, b1, b2, b3, rk) \
    STR(ENC_ADD_ROUND_KEY_(b0, b1, b2, b3, rk))

#define DEC_ADD_ROUND_KEY(b0, b1, b2, b3, rk) \
    STR(DEC_ADD_ROUND_KEY_(b0, b1, b2, b3, rk))


#define ENC_A(b0, b1, b2, b3) \
    STR(ENC_A_(b0, b1, b2, b3))

#define DEC_A(b0, b1, b2, b3) \
    STR(DEC_A_(b0, b1, b2, b3))


#define ENC_L(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, temp) \
    STR(ENC_L_(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, temp))

#define DEC_L(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, temp) \
    STR(DEC_L_(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, temp))


#define ENC_ADD_WHITENING_KEY(b0, b1, b2, b3, rk) \
    STR(ENC_ADD_WHITENING_KEY_(b0, b1, b2, b3, rk))

#define DEC_ADD_WHITENING_KEY(b0, b1, b2, b3, rk) \
    STR(DEC_ADD_WHITENING_KEY_(b0, b1, b2, b3, rk))


#endif /* AVR_MACROS_H */
