diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/aead-common.c b/romulus/Implementations/crypto_aead/romulusm1+/rhys/aead-common.c new file mode 100644 index 0000000..84fc53a --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/aead-common.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "aead-common.h" + +int aead_check_tag + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned size) +{ + /* Set "accum" to -1 if the tags match, or 0 if they don't match */ + int accum = 0; + while (size > 0) { + accum |= (*tag1++ ^ *tag2++); + --size; + } + accum = (accum - 1) >> 8; + + /* Destroy the plaintext if the tag match failed */ + while (plaintext_len > 0) { + *plaintext++ &= accum; + --plaintext_len; + } + + /* If "accum" is 0, return -1, otherwise return 0 */ + return ~accum; +} + +int aead_check_tag_precheck + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned size, int precheck) +{ + /* Set "accum" to -1 if the tags match, or 0 if they don't match */ + int accum = 0; + while (size > 0) { + accum |= (*tag1++ ^ *tag2++); + --size; + } + accum = ((accum - 1) >> 8) & precheck; + + /* Destroy the plaintext if the tag match failed */ + while (plaintext_len > 0) { + *plaintext++ &= accum; + --plaintext_len; + } + + /* If "accum" is 0, return -1, otherwise return 0 */ + return ~accum; +} diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/aead-common.h b/romulus/Implementations/crypto_aead/romulusm1+/rhys/aead-common.h new file mode 100644 index 0000000..2be95eb --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/aead-common.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LWCRYPTO_AEAD_COMMON_H +#define LWCRYPTO_AEAD_COMMON_H + +#include + +/** + * \file aead-common.h + * \brief Definitions that are common across AEAD schemes. + * + * AEAD stands for "Authenticated Encryption with Associated Data". + * It is a standard API pattern for securely encrypting and + * authenticating packets of data. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Encrypts and authenticates a packet with an AEAD scheme. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - normally not used by AEAD schemes. + * \param npub Points to the public nonce for the packet. + * \param k Points to the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + */ +typedef int (*aead_cipher_encrypt_t) + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with an AEAD scheme. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - normally not used by AEAD schemes. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet. + * \param k Points to the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + */ +typedef int (*aead_cipher_decrypt_t) + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Hashes a block of input data. + * + * \param out Buffer to receive the hash output. + * \param in Points to the input data to be hashed. + * \param inlen Length of the input data in bytes. + * + * \return Returns zero on success or -1 if there was an error in the + * parameters. + */ +typedef int (*aead_hash_t) + (unsigned char *out, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Initializes the state for a hashing operation. + * + * \param state Hash state to be initialized. + */ +typedef void (*aead_hash_init_t)(void *state); + +/** + * \brief Updates a hash state with more input data. + * + * \param state Hash state to be updated. + * \param in Points to the input data to be incorporated into the state. + * \param inlen Length of the input data to be incorporated into the state. + */ +typedef void (*aead_hash_update_t) + (void *state, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Returns the final hash value from a hashing operation. + * + * \param Hash state to be finalized. + * \param out Points to the output buffer to receive the hash value. + */ +typedef void (*aead_hash_finalize_t)(void *state, unsigned char *out); + +/** + * \brief Aborbs more input data into an XOF state. + * + * \param state XOF state to be updated. + * \param in Points to the input data to be absorbed into the state. + * \param inlen Length of the input data to be absorbed into the state. + * + * \sa ascon_xof_init(), ascon_xof_squeeze() + */ +typedef void (*aead_xof_absorb_t) + (void *state, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Squeezes output data from an XOF state. + * + * \param state XOF state to squeeze the output data from. + * \param out Points to the output buffer to receive the squeezed data. + * \param outlen Number of bytes of data to squeeze out of the state. + */ +typedef void (*aead_xof_squeeze_t) + (void *state, unsigned char *out, unsigned long long outlen); + +/** + * \brief No special AEAD features. + */ +#define AEAD_FLAG_NONE 0x0000 + +/** + * \brief The natural byte order of the AEAD cipher is little-endian. + * + * If this flag is not present, then the natural byte order of the + * AEAD cipher should be assumed to be big-endian. + * + * The natural byte order may be useful when formatting packet sequence + * numbers as nonces. The application needs to know whether the sequence + * number should be packed into the leading or trailing bytes of the nonce. + */ +#define AEAD_FLAG_LITTLE_ENDIAN 0x0001 + +/** + * \brief Meta-information about an AEAD cipher. + */ +typedef struct +{ + const char *name; /**< Name of the cipher */ + unsigned key_len; /**< Length of the key in bytes */ + unsigned nonce_len; /**< Length of the nonce in bytes */ + unsigned tag_len; /**< Length of the tag in bytes */ + unsigned flags; /**< Flags for extra features */ + aead_cipher_encrypt_t encrypt; /**< AEAD encryption function */ + aead_cipher_decrypt_t decrypt; /**< AEAD decryption function */ + +} aead_cipher_t; + +/** + * \brief Meta-information about a hash algorithm that is related to an AEAD. + * + * Regular hash algorithms should provide the "hash", "init", "update", + * and "finalize" functions. Extensible Output Functions (XOF's) should + * proivde the "hash", "init", "absorb", and "squeeze" functions. + */ +typedef struct +{ + const char *name; /**< Name of the hash algorithm */ + size_t state_size; /**< Size of the incremental state structure */ + unsigned hash_len; /**< Length of the hash in bytes */ + unsigned flags; /**< Flags for extra features */ + aead_hash_t hash; /**< All in one hashing function */ + aead_hash_init_t init; /**< Incremental hash/XOF init function */ + aead_hash_update_t update; /**< Incremental hash update function */ + aead_hash_finalize_t finalize; /**< Incremental hash finalize function */ + aead_xof_absorb_t absorb; /**< Incremental XOF absorb function */ + aead_xof_squeeze_t squeeze; /**< Incremental XOF squeeze function */ + +} aead_hash_algorithm_t; + +/** + * \brief Check an authentication tag in constant time. + * + * \param plaintext Points to the plaintext data. + * \param plaintext_len Length of the plaintext in bytes. + * \param tag1 First tag to compare. + * \param tag2 Second tag to compare. + * \param tag_len Length of the tags in bytes. + * + * \return Returns -1 if the tag check failed or 0 if the check succeeded. + * + * If the tag check fails, then the \a plaintext will also be zeroed to + * prevent it from being used accidentally by the application when the + * ciphertext was invalid. + */ +int aead_check_tag + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned tag_len); + +/** + * \brief Check an authentication tag in constant time with a previous check. + * + * \param plaintext Points to the plaintext data. + * \param plaintext_len Length of the plaintext in bytes. + * \param tag1 First tag to compare. + * \param tag2 Second tag to compare. + * \param tag_len Length of the tags in bytes. + * \param precheck Set to -1 if previous check succeeded or 0 if it failed. + * + * \return Returns -1 if the tag check failed or 0 if the check succeeded. + * + * If the tag check fails, then the \a plaintext will also be zeroed to + * prevent it from being used accidentally by the application when the + * ciphertext was invalid. + * + * This version can be used to incorporate other information about the + * correctness of the plaintext into the final result. + */ +int aead_check_tag_precheck + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned tag_len, int precheck); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/api.h b/romulus/Implementations/crypto_aead/romulusm1+/rhys/api.h new file mode 100644 index 0000000..b2f8a36 --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/api.h @@ -0,0 +1,5 @@ +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 16 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/encrypt.c b/romulus/Implementations/crypto_aead/romulusm1+/rhys/encrypt.c new file mode 100644 index 0000000..192e5e9 --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/encrypt.c @@ -0,0 +1,25 @@ +#include "romulus.h" + +int crypto_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + return romulus_m1_aead_encrypt + (c, clen, m, mlen, ad, adlen, nsec, npub, k); +} + +int crypto_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + return romulus_m1_aead_decrypt + (m, mlen, nsec, c, clen, ad, adlen, npub, k); +} diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128-avr.S b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128-avr.S new file mode 100644 index 0000000..0fafa4e --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128-avr.S @@ -0,0 +1,10099 @@ +#if defined(__AVR__) +#include +/* Automatically generated - do not edit */ + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_0, @object + .size table_0, 256 +table_0: + .byte 101 + .byte 76 + .byte 106 + .byte 66 + .byte 75 + .byte 99 + .byte 67 + .byte 107 + .byte 85 + .byte 117 + .byte 90 + .byte 122 + .byte 83 + .byte 115 + .byte 91 + .byte 123 + .byte 53 + .byte 140 + .byte 58 + .byte 129 + .byte 137 + .byte 51 + .byte 128 + .byte 59 + .byte 149 + .byte 37 + .byte 152 + .byte 42 + .byte 144 + .byte 35 + .byte 153 + .byte 43 + .byte 229 + .byte 204 + .byte 232 + .byte 193 + .byte 201 + .byte 224 + .byte 192 + .byte 233 + .byte 213 + .byte 245 + .byte 216 + .byte 248 + .byte 208 + .byte 240 + .byte 217 + .byte 249 + .byte 165 + .byte 28 + .byte 168 + .byte 18 + .byte 27 + .byte 160 + .byte 19 + .byte 169 + .byte 5 + .byte 181 + .byte 10 + .byte 184 + .byte 3 + .byte 176 + .byte 11 + .byte 185 + .byte 50 + .byte 136 + .byte 60 + .byte 133 + .byte 141 + .byte 52 + .byte 132 + .byte 61 + .byte 145 + .byte 34 + .byte 156 + .byte 44 + .byte 148 + .byte 36 + .byte 157 + .byte 45 + .byte 98 + .byte 74 + .byte 108 + .byte 69 + .byte 77 + .byte 100 + .byte 68 + .byte 109 + .byte 82 + .byte 114 + .byte 92 + .byte 124 + .byte 84 + .byte 116 + .byte 93 + .byte 125 + .byte 161 + .byte 26 + .byte 172 + .byte 21 + .byte 29 + .byte 164 + .byte 20 + .byte 173 + .byte 2 + .byte 177 + .byte 12 + .byte 188 + .byte 4 + .byte 180 + .byte 13 + .byte 189 + .byte 225 + .byte 200 + .byte 236 + .byte 197 + .byte 205 + .byte 228 + .byte 196 + .byte 237 + .byte 209 + .byte 241 + .byte 220 + .byte 252 + .byte 212 + .byte 244 + .byte 221 + .byte 253 + .byte 54 + .byte 142 + .byte 56 + .byte 130 + .byte 139 + .byte 48 + .byte 131 + .byte 57 + .byte 150 + .byte 38 + .byte 154 + .byte 40 + .byte 147 + .byte 32 + .byte 155 + .byte 41 + .byte 102 + .byte 78 + .byte 104 + .byte 65 + .byte 73 + .byte 96 + .byte 64 + .byte 105 + .byte 86 + .byte 118 + .byte 88 + .byte 120 + .byte 80 + .byte 112 + .byte 89 + .byte 121 + .byte 166 + .byte 30 + .byte 170 + .byte 17 + .byte 25 + .byte 163 + .byte 16 + .byte 171 + .byte 6 + .byte 182 + .byte 8 + .byte 186 + .byte 0 + .byte 179 + .byte 9 + .byte 187 + .byte 230 + .byte 206 + .byte 234 + .byte 194 + .byte 203 + .byte 227 + .byte 195 + .byte 235 + .byte 214 + .byte 246 + .byte 218 + .byte 250 + .byte 211 + .byte 243 + .byte 219 + .byte 251 + .byte 49 + .byte 138 + .byte 62 + .byte 134 + .byte 143 + .byte 55 + .byte 135 + .byte 63 + .byte 146 + .byte 33 + .byte 158 + .byte 46 + .byte 151 + .byte 39 + .byte 159 + .byte 47 + .byte 97 + .byte 72 + .byte 110 + .byte 70 + .byte 79 + .byte 103 + .byte 71 + .byte 111 + .byte 81 + .byte 113 + .byte 94 + .byte 126 + .byte 87 + .byte 119 + .byte 95 + .byte 127 + .byte 162 + .byte 24 + .byte 174 + .byte 22 + .byte 31 + .byte 167 + .byte 23 + .byte 175 + .byte 1 + .byte 178 + .byte 14 + .byte 190 + .byte 7 + .byte 183 + .byte 15 + .byte 191 + .byte 226 + .byte 202 + .byte 238 + .byte 198 + .byte 207 + .byte 231 + .byte 199 + .byte 239 + .byte 210 + .byte 242 + .byte 222 + .byte 254 + .byte 215 + .byte 247 + .byte 223 + .byte 255 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_1, @object + .size table_1, 256 +table_1: + .byte 172 + .byte 232 + .byte 104 + .byte 60 + .byte 108 + .byte 56 + .byte 168 + .byte 236 + .byte 170 + .byte 174 + .byte 58 + .byte 62 + .byte 106 + .byte 110 + .byte 234 + .byte 238 + .byte 166 + .byte 163 + .byte 51 + .byte 54 + .byte 102 + .byte 99 + .byte 227 + .byte 230 + .byte 225 + .byte 164 + .byte 97 + .byte 52 + .byte 49 + .byte 100 + .byte 161 + .byte 228 + .byte 141 + .byte 201 + .byte 73 + .byte 29 + .byte 77 + .byte 25 + .byte 137 + .byte 205 + .byte 139 + .byte 143 + .byte 27 + .byte 31 + .byte 75 + .byte 79 + .byte 203 + .byte 207 + .byte 133 + .byte 192 + .byte 64 + .byte 21 + .byte 69 + .byte 16 + .byte 128 + .byte 197 + .byte 130 + .byte 135 + .byte 18 + .byte 23 + .byte 66 + .byte 71 + .byte 194 + .byte 199 + .byte 150 + .byte 147 + .byte 3 + .byte 6 + .byte 86 + .byte 83 + .byte 211 + .byte 214 + .byte 209 + .byte 148 + .byte 81 + .byte 4 + .byte 1 + .byte 84 + .byte 145 + .byte 212 + .byte 156 + .byte 216 + .byte 88 + .byte 12 + .byte 92 + .byte 8 + .byte 152 + .byte 220 + .byte 154 + .byte 158 + .byte 10 + .byte 14 + .byte 90 + .byte 94 + .byte 218 + .byte 222 + .byte 149 + .byte 208 + .byte 80 + .byte 5 + .byte 85 + .byte 0 + .byte 144 + .byte 213 + .byte 146 + .byte 151 + .byte 2 + .byte 7 + .byte 82 + .byte 87 + .byte 210 + .byte 215 + .byte 157 + .byte 217 + .byte 89 + .byte 13 + .byte 93 + .byte 9 + .byte 153 + .byte 221 + .byte 155 + .byte 159 + .byte 11 + .byte 15 + .byte 91 + .byte 95 + .byte 219 + .byte 223 + .byte 22 + .byte 19 + .byte 131 + .byte 134 + .byte 70 + .byte 67 + .byte 195 + .byte 198 + .byte 65 + .byte 20 + .byte 193 + .byte 132 + .byte 17 + .byte 68 + .byte 129 + .byte 196 + .byte 28 + .byte 72 + .byte 200 + .byte 140 + .byte 76 + .byte 24 + .byte 136 + .byte 204 + .byte 26 + .byte 30 + .byte 138 + .byte 142 + .byte 74 + .byte 78 + .byte 202 + .byte 206 + .byte 53 + .byte 96 + .byte 224 + .byte 165 + .byte 101 + .byte 48 + .byte 160 + .byte 229 + .byte 50 + .byte 55 + .byte 162 + .byte 167 + .byte 98 + .byte 103 + .byte 226 + .byte 231 + .byte 61 + .byte 105 + .byte 233 + .byte 173 + .byte 109 + .byte 57 + .byte 169 + .byte 237 + .byte 59 + .byte 63 + .byte 171 + .byte 175 + .byte 107 + .byte 111 + .byte 235 + .byte 239 + .byte 38 + .byte 35 + .byte 179 + .byte 182 + .byte 118 + .byte 115 + .byte 243 + .byte 246 + .byte 113 + .byte 36 + .byte 241 + .byte 180 + .byte 33 + .byte 116 + .byte 177 + .byte 244 + .byte 44 + .byte 120 + .byte 248 + .byte 188 + .byte 124 + .byte 40 + .byte 184 + .byte 252 + .byte 42 + .byte 46 + .byte 186 + .byte 190 + .byte 122 + .byte 126 + .byte 250 + .byte 254 + .byte 37 + .byte 112 + .byte 240 + .byte 181 + .byte 117 + .byte 32 + .byte 176 + .byte 245 + .byte 34 + .byte 39 + .byte 178 + .byte 183 + .byte 114 + .byte 119 + .byte 242 + .byte 247 + .byte 45 + .byte 121 + .byte 249 + .byte 189 + .byte 125 + .byte 41 + .byte 185 + .byte 253 + .byte 43 + .byte 47 + .byte 187 + .byte 191 + .byte 123 + .byte 127 + .byte 251 + .byte 255 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_2, @object + .size table_2, 256 +table_2: + .byte 0 + .byte 2 + .byte 4 + .byte 6 + .byte 8 + .byte 10 + .byte 12 + .byte 14 + .byte 16 + .byte 18 + .byte 20 + .byte 22 + .byte 24 + .byte 26 + .byte 28 + .byte 30 + .byte 32 + .byte 34 + .byte 36 + .byte 38 + .byte 40 + .byte 42 + .byte 44 + .byte 46 + .byte 48 + .byte 50 + .byte 52 + .byte 54 + .byte 56 + .byte 58 + .byte 60 + .byte 62 + .byte 65 + .byte 67 + .byte 69 + .byte 71 + .byte 73 + .byte 75 + .byte 77 + .byte 79 + .byte 81 + .byte 83 + .byte 85 + .byte 87 + .byte 89 + .byte 91 + .byte 93 + .byte 95 + .byte 97 + .byte 99 + .byte 101 + .byte 103 + .byte 105 + .byte 107 + .byte 109 + .byte 111 + .byte 113 + .byte 115 + .byte 117 + .byte 119 + .byte 121 + .byte 123 + .byte 125 + .byte 127 + .byte 128 + .byte 130 + .byte 132 + .byte 134 + .byte 136 + .byte 138 + .byte 140 + .byte 142 + .byte 144 + .byte 146 + .byte 148 + .byte 150 + .byte 152 + .byte 154 + .byte 156 + .byte 158 + .byte 160 + .byte 162 + .byte 164 + .byte 166 + .byte 168 + .byte 170 + .byte 172 + .byte 174 + .byte 176 + .byte 178 + .byte 180 + .byte 182 + .byte 184 + .byte 186 + .byte 188 + .byte 190 + .byte 193 + .byte 195 + .byte 197 + .byte 199 + .byte 201 + .byte 203 + .byte 205 + .byte 207 + .byte 209 + .byte 211 + .byte 213 + .byte 215 + .byte 217 + .byte 219 + .byte 221 + .byte 223 + .byte 225 + .byte 227 + .byte 229 + .byte 231 + .byte 233 + .byte 235 + .byte 237 + .byte 239 + .byte 241 + .byte 243 + .byte 245 + .byte 247 + .byte 249 + .byte 251 + .byte 253 + .byte 255 + .byte 1 + .byte 3 + .byte 5 + .byte 7 + .byte 9 + .byte 11 + .byte 13 + .byte 15 + .byte 17 + .byte 19 + .byte 21 + .byte 23 + .byte 25 + .byte 27 + .byte 29 + .byte 31 + .byte 33 + .byte 35 + .byte 37 + .byte 39 + .byte 41 + .byte 43 + .byte 45 + .byte 47 + .byte 49 + .byte 51 + .byte 53 + .byte 55 + .byte 57 + .byte 59 + .byte 61 + .byte 63 + .byte 64 + .byte 66 + .byte 68 + .byte 70 + .byte 72 + .byte 74 + .byte 76 + .byte 78 + .byte 80 + .byte 82 + .byte 84 + .byte 86 + .byte 88 + .byte 90 + .byte 92 + .byte 94 + .byte 96 + .byte 98 + .byte 100 + .byte 102 + .byte 104 + .byte 106 + .byte 108 + .byte 110 + .byte 112 + .byte 114 + .byte 116 + .byte 118 + .byte 120 + .byte 122 + .byte 124 + .byte 126 + .byte 129 + .byte 131 + .byte 133 + .byte 135 + .byte 137 + .byte 139 + .byte 141 + .byte 143 + .byte 145 + .byte 147 + .byte 149 + .byte 151 + .byte 153 + .byte 155 + .byte 157 + .byte 159 + .byte 161 + .byte 163 + .byte 165 + .byte 167 + .byte 169 + .byte 171 + .byte 173 + .byte 175 + .byte 177 + .byte 179 + .byte 181 + .byte 183 + .byte 185 + .byte 187 + .byte 189 + .byte 191 + .byte 192 + .byte 194 + .byte 196 + .byte 198 + .byte 200 + .byte 202 + .byte 204 + .byte 206 + .byte 208 + .byte 210 + .byte 212 + .byte 214 + .byte 216 + .byte 218 + .byte 220 + .byte 222 + .byte 224 + .byte 226 + .byte 228 + .byte 230 + .byte 232 + .byte 234 + .byte 236 + .byte 238 + .byte 240 + .byte 242 + .byte 244 + .byte 246 + .byte 248 + .byte 250 + .byte 252 + .byte 254 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_3, @object + .size table_3, 256 +table_3: + .byte 0 + .byte 128 + .byte 1 + .byte 129 + .byte 2 + .byte 130 + .byte 3 + .byte 131 + .byte 4 + .byte 132 + .byte 5 + .byte 133 + .byte 6 + .byte 134 + .byte 7 + .byte 135 + .byte 8 + .byte 136 + .byte 9 + .byte 137 + .byte 10 + .byte 138 + .byte 11 + .byte 139 + .byte 12 + .byte 140 + .byte 13 + .byte 141 + .byte 14 + .byte 142 + .byte 15 + .byte 143 + .byte 16 + .byte 144 + .byte 17 + .byte 145 + .byte 18 + .byte 146 + .byte 19 + .byte 147 + .byte 20 + .byte 148 + .byte 21 + .byte 149 + .byte 22 + .byte 150 + .byte 23 + .byte 151 + .byte 24 + .byte 152 + .byte 25 + .byte 153 + .byte 26 + .byte 154 + .byte 27 + .byte 155 + .byte 28 + .byte 156 + .byte 29 + .byte 157 + .byte 30 + .byte 158 + .byte 31 + .byte 159 + .byte 160 + .byte 32 + .byte 161 + .byte 33 + .byte 162 + .byte 34 + .byte 163 + .byte 35 + .byte 164 + .byte 36 + .byte 165 + .byte 37 + .byte 166 + .byte 38 + .byte 167 + .byte 39 + .byte 168 + .byte 40 + .byte 169 + .byte 41 + .byte 170 + .byte 42 + .byte 171 + .byte 43 + .byte 172 + .byte 44 + .byte 173 + .byte 45 + .byte 174 + .byte 46 + .byte 175 + .byte 47 + .byte 176 + .byte 48 + .byte 177 + .byte 49 + .byte 178 + .byte 50 + .byte 179 + .byte 51 + .byte 180 + .byte 52 + .byte 181 + .byte 53 + .byte 182 + .byte 54 + .byte 183 + .byte 55 + .byte 184 + .byte 56 + .byte 185 + .byte 57 + .byte 186 + .byte 58 + .byte 187 + .byte 59 + .byte 188 + .byte 60 + .byte 189 + .byte 61 + .byte 190 + .byte 62 + .byte 191 + .byte 63 + .byte 64 + .byte 192 + .byte 65 + .byte 193 + .byte 66 + .byte 194 + .byte 67 + .byte 195 + .byte 68 + .byte 196 + .byte 69 + .byte 197 + .byte 70 + .byte 198 + .byte 71 + .byte 199 + .byte 72 + .byte 200 + .byte 73 + .byte 201 + .byte 74 + .byte 202 + .byte 75 + .byte 203 + .byte 76 + .byte 204 + .byte 77 + .byte 205 + .byte 78 + .byte 206 + .byte 79 + .byte 207 + .byte 80 + .byte 208 + .byte 81 + .byte 209 + .byte 82 + .byte 210 + .byte 83 + .byte 211 + .byte 84 + .byte 212 + .byte 85 + .byte 213 + .byte 86 + .byte 214 + .byte 87 + .byte 215 + .byte 88 + .byte 216 + .byte 89 + .byte 217 + .byte 90 + .byte 218 + .byte 91 + .byte 219 + .byte 92 + .byte 220 + .byte 93 + .byte 221 + .byte 94 + .byte 222 + .byte 95 + .byte 223 + .byte 224 + .byte 96 + .byte 225 + .byte 97 + .byte 226 + .byte 98 + .byte 227 + .byte 99 + .byte 228 + .byte 100 + .byte 229 + .byte 101 + .byte 230 + .byte 102 + .byte 231 + .byte 103 + .byte 232 + .byte 104 + .byte 233 + .byte 105 + .byte 234 + .byte 106 + .byte 235 + .byte 107 + .byte 236 + .byte 108 + .byte 237 + .byte 109 + .byte 238 + .byte 110 + .byte 239 + .byte 111 + .byte 240 + .byte 112 + .byte 241 + .byte 113 + .byte 242 + .byte 114 + .byte 243 + .byte 115 + .byte 244 + .byte 116 + .byte 245 + .byte 117 + .byte 246 + .byte 118 + .byte 247 + .byte 119 + .byte 248 + .byte 120 + .byte 249 + .byte 121 + .byte 250 + .byte 122 + .byte 251 + .byte 123 + .byte 252 + .byte 124 + .byte 253 + .byte 125 + .byte 254 + .byte 126 + .byte 255 + .byte 127 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_4, @object + .size table_4, 112 +table_4: + .byte 1 + .byte 0 + .byte 3 + .byte 0 + .byte 7 + .byte 0 + .byte 15 + .byte 0 + .byte 15 + .byte 1 + .byte 14 + .byte 3 + .byte 13 + .byte 3 + .byte 11 + .byte 3 + .byte 7 + .byte 3 + .byte 15 + .byte 2 + .byte 14 + .byte 1 + .byte 12 + .byte 3 + .byte 9 + .byte 3 + .byte 3 + .byte 3 + .byte 7 + .byte 2 + .byte 14 + .byte 0 + .byte 13 + .byte 1 + .byte 10 + .byte 3 + .byte 5 + .byte 3 + .byte 11 + .byte 2 + .byte 6 + .byte 1 + .byte 12 + .byte 2 + .byte 8 + .byte 1 + .byte 0 + .byte 3 + .byte 1 + .byte 2 + .byte 2 + .byte 0 + .byte 5 + .byte 0 + .byte 11 + .byte 0 + .byte 7 + .byte 1 + .byte 14 + .byte 2 + .byte 12 + .byte 1 + .byte 8 + .byte 3 + .byte 1 + .byte 3 + .byte 3 + .byte 2 + .byte 6 + .byte 0 + .byte 13 + .byte 0 + .byte 11 + .byte 1 + .byte 6 + .byte 3 + .byte 13 + .byte 2 + .byte 10 + .byte 1 + .byte 4 + .byte 3 + .byte 9 + .byte 2 + .byte 2 + .byte 1 + .byte 4 + .byte 2 + .byte 8 + .byte 0 + .byte 1 + .byte 1 + .byte 2 + .byte 2 + .byte 4 + .byte 0 + .byte 9 + .byte 0 + .byte 3 + .byte 1 + .byte 6 + .byte 2 + .byte 12 + .byte 0 + .byte 9 + .byte 1 + .byte 2 + .byte 3 + .byte 5 + .byte 2 + .byte 10 + .byte 0 + + .text +.global skinny_128_384_init + .type skinny_128_384_init, @function +skinny_128_384_init: + movw r30,r24 + movw r26,r22 +.L__stack_usage = 2 + ldi r22,12 +1: + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + st Z+,r18 + st Z+,r19 + st Z+,r20 + st Z+,r21 + dec r22 + brne 1b + ret + .size skinny_128_384_init, .-skinny_128_384_init + + .text +.global skinny_128_384_encrypt + .type skinny_128_384_encrypt, @function +skinny_128_384_encrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,48 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 68 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + ldd r18,Z+4 + ldd r19,Z+5 + ldd r20,Z+6 + ldd r21,Z+7 + std Y+5,r18 + std Y+6,r19 + std Y+7,r20 + std Y+8,r21 + ldd r18,Z+8 + ldd r19,Z+9 + ldd r20,Z+10 + ldd r21,Z+11 + std Y+9,r18 + std Y+10,r19 + std Y+11,r20 + std Y+12,r21 + ldd r18,Z+12 + ldd r19,Z+13 + ldd r20,Z+14 + ldd r21,Z+15 + std Y+13,r18 + std Y+14,r19 + std Y+15,r20 + std Y+16,r21 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + ldd r18,Z+20 + ldd r19,Z+21 + ldd r20,Z+22 + ldd r21,Z+23 + std Y+21,r18 + std Y+22,r19 + std Y+23,r20 + std Y+24,r21 + ldd r18,Z+24 + ldd r19,Z+25 + ldd r20,Z+26 + ldd r21,Z+27 + std Y+25,r18 + std Y+26,r19 + std Y+27,r20 + std Y+28,r21 + ldd r18,Z+28 + ldd r19,Z+29 + ldd r20,Z+30 + ldd r21,Z+31 + std Y+29,r18 + std Y+30,r19 + std Y+31,r20 + std Y+32,r21 + ldd r18,Z+32 + ldd r19,Z+33 + ldd r20,Z+34 + ldd r21,Z+35 + std Y+33,r18 + std Y+34,r19 + std Y+35,r20 + std Y+36,r21 + ldd r18,Z+36 + ldd r19,Z+37 + ldd r20,Z+38 + ldd r21,Z+39 + std Y+37,r18 + std Y+38,r19 + std Y+39,r20 + std Y+40,r21 + ldd r18,Z+40 + ldd r19,Z+41 + ldd r20,Z+42 + ldd r21,Z+43 + std Y+41,r18 + std Y+42,r19 + std Y+43,r20 + std Y+44,r21 + ldd r18,Z+44 + ldd r19,Z+45 + ldd r20,Z+46 + ldd r21,Z+47 + std Y+45,r18 + std Y+46,r19 + std Y+47,r20 + std Y+48,r21 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r26,hh8(table_0) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + mov r26,r1 +114: + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + ldi r27,2 + eor r4,r27 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+33 + eor r18,r0 + ldd r0,Y+34 + eor r19,r0 + ldd r0,Y+35 + eor r20,r0 + ldd r0,Y+36 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldd r0,Y+37 + eor r22,r0 + ldd r0,Y+38 + eor r23,r0 + ldd r0,Y+39 + eor r2,r0 + ldd r0,Y+40 + eor r3,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + mov r0,r6 + mov r6,r4 + mov r4,r0 + mov r0,r7 + mov r7,r5 + mov r5,r0 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r13 + std Y+42,r17 + std Y+43,r12 + std Y+44,r25 + std Y+45,r14 + std Y+46,r16 + std Y+47,r24 + std Y+48,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + ldi r27,2 + eor r22,r27 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+41 + eor r8,r0 + ldd r0,Y+42 + eor r9,r0 + ldd r0,Y+43 + eor r10,r0 + ldd r0,Y+44 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldd r0,Y+45 + eor r18,r0 + ldd r0,Y+46 + eor r19,r0 + ldd r0,Y+47 + eor r20,r0 + ldd r0,Y+48 + eor r21,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + mov r0,r2 + mov r2,r22 + mov r22,r0 + mov r0,r3 + mov r3,r23 + mov r23,r0 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r13 + std Y+34,r17 + std Y+35,r12 + std Y+36,r25 + std Y+37,r14 + std Y+38,r16 + std Y+39,r24 + std Y+40,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + ldi r27,2 + eor r18,r27 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+33 + eor r4,r0 + ldd r0,Y+34 + eor r5,r0 + ldd r0,Y+35 + eor r6,r0 + ldd r0,Y+36 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldd r0,Y+37 + eor r8,r0 + ldd r0,Y+38 + eor r9,r0 + ldd r0,Y+39 + eor r10,r0 + ldd r0,Y+40 + eor r11,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + mov r0,r20 + mov r20,r18 + mov r18,r0 + mov r0,r21 + mov r21,r19 + mov r19,r0 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r13 + std Y+42,r17 + std Y+43,r12 + std Y+44,r25 + std Y+45,r14 + std Y+46,r16 + std Y+47,r24 + std Y+48,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + ldi r27,2 + eor r8,r27 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+41 + eor r22,r0 + ldd r0,Y+42 + eor r23,r0 + ldd r0,Y+43 + eor r2,r0 + ldd r0,Y+44 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldd r0,Y+45 + eor r4,r0 + ldd r0,Y+46 + eor r5,r0 + ldd r0,Y+47 + eor r6,r0 + ldd r0,Y+48 + eor r7,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + mov r0,r10 + mov r10,r8 + mov r8,r0 + mov r0,r11 + mov r11,r9 + mov r9,r0 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + cpi r26,80 + brne 5721f + rjmp 790f +5721: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r13 + std Y+34,r17 + std Y+35,r12 + std Y+36,r25 + std Y+37,r14 + std Y+38,r16 + std Y+39,r24 + std Y+40,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 114b +790: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+49 + ldd r27,Y+50 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,50 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_384_encrypt, .-skinny_128_384_encrypt + +.global skinny_128_384_encrypt_tk_full + .set skinny_128_384_encrypt_tk_full,skinny_128_384_encrypt + + .text +.global skinny_128_384_decrypt + .type skinny_128_384_decrypt, @function +skinny_128_384_decrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,48 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 68 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + ldd r22,Z+4 + ldd r23,Z+5 + ldd r2,Z+6 + ldd r3,Z+7 + ldd r4,Z+8 + ldd r5,Z+9 + ldd r6,Z+10 + ldd r7,Z+11 + ldd r8,Z+12 + ldd r9,Z+13 + ldd r10,Z+14 + ldd r11,Z+15 + std Y+1,r23 + std Y+2,r2 + std Y+3,r21 + std Y+4,r20 + std Y+5,r3 + std Y+6,r18 + std Y+7,r19 + std Y+8,r22 + std Y+9,r9 + std Y+10,r10 + std Y+11,r7 + std Y+12,r6 + std Y+13,r11 + std Y+14,r4 + std Y+15,r5 + std Y+16,r8 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + ldd r22,Z+20 + ldd r23,Z+21 + ldd r2,Z+22 + ldd r3,Z+23 + ldd r4,Z+24 + ldd r5,Z+25 + ldd r6,Z+26 + ldd r7,Z+27 + ldd r8,Z+28 + ldd r9,Z+29 + ldd r10,Z+30 + ldd r11,Z+31 + std Y+17,r23 + std Y+18,r2 + std Y+19,r21 + std Y+20,r20 + std Y+21,r3 + std Y+22,r18 + std Y+23,r19 + std Y+24,r22 + std Y+25,r9 + std Y+26,r10 + std Y+27,r7 + std Y+28,r6 + std Y+29,r11 + std Y+30,r4 + std Y+31,r5 + std Y+32,r8 + ldd r18,Z+32 + ldd r19,Z+33 + ldd r20,Z+34 + ldd r21,Z+35 + ldd r22,Z+36 + ldd r23,Z+37 + ldd r2,Z+38 + ldd r3,Z+39 + ldd r4,Z+40 + ldd r5,Z+41 + ldd r6,Z+42 + ldd r7,Z+43 + ldd r8,Z+44 + ldd r9,Z+45 + ldd r10,Z+46 + ldd r11,Z+47 + std Y+33,r23 + std Y+34,r2 + std Y+35,r21 + std Y+36,r20 + std Y+37,r3 + std Y+38,r18 + std Y+39,r19 + std Y+40,r22 + std Y+41,r9 + std Y+42,r10 + std Y+43,r7 + std Y+44,r6 + std Y+45,r11 + std Y+46,r4 + std Y+47,r5 + std Y+48,r8 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r26,hh8(table_2) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,20 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 +122: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 122b + std Y+17,r12 + std Y+18,r13 + std Y+19,r14 + std Y+20,r15 + std Y+21,r24 + std Y+22,r25 + std Y+23,r16 + std Y+24,r17 + ldi r26,20 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 +150: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 150b + std Y+25,r12 + std Y+26,r13 + std Y+27,r14 + std Y+28,r15 + std Y+29,r24 + std Y+30,r25 + std Y+31,r16 + std Y+32,r17 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r26,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,20 + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 +179: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 179b + std Y+33,r12 + std Y+34,r13 + std Y+35,r14 + std Y+36,r15 + std Y+37,r24 + std Y+38,r25 + std Y+39,r16 + std Y+40,r17 + ldi r26,20 + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 +207: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 207b + std Y+41,r12 + std Y+42,r13 + std Y+43,r14 + std Y+44,r15 + std Y+45,r24 + std Y+46,r25 + std Y+47,r16 + std Y+48,r17 + ldi r26,80 +227: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r14 + std Y+34,r12 + std Y+35,r24 + std Y+36,r17 + std Y+37,r16 + std Y+38,r15 + std Y+39,r25 + std Y+40,r13 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + mov r0,r8 + mov r8,r10 + mov r10,r0 + mov r0,r9 + mov r9,r11 + mov r11,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+41 + eor r22,r0 + ldd r0,Y+42 + eor r23,r0 + ldd r0,Y+43 + eor r2,r0 + ldd r0,Y+44 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldd r0,Y+45 + eor r4,r0 + ldd r0,Y+46 + eor r5,r0 + ldd r0,Y+47 + eor r6,r0 + ldd r0,Y+48 + eor r7,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + ldi r27,2 + eor r8,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r14 + std Y+42,r12 + std Y+43,r24 + std Y+44,r17 + std Y+45,r16 + std Y+46,r15 + std Y+47,r25 + std Y+48,r13 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + mov r0,r18 + mov r18,r20 + mov r20,r0 + mov r0,r19 + mov r19,r21 + mov r21,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+33 + eor r4,r0 + ldd r0,Y+34 + eor r5,r0 + ldd r0,Y+35 + eor r6,r0 + ldd r0,Y+36 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldd r0,Y+37 + eor r8,r0 + ldd r0,Y+38 + eor r9,r0 + ldd r0,Y+39 + eor r10,r0 + ldd r0,Y+40 + eor r11,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + ldi r27,2 + eor r18,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r14 + std Y+34,r12 + std Y+35,r24 + std Y+36,r17 + std Y+37,r16 + std Y+38,r15 + std Y+39,r25 + std Y+40,r13 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + mov r0,r22 + mov r22,r2 + mov r2,r0 + mov r0,r23 + mov r23,r3 + mov r3,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+41 + eor r8,r0 + ldd r0,Y+42 + eor r9,r0 + ldd r0,Y+43 + eor r10,r0 + ldd r0,Y+44 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldd r0,Y+45 + eor r18,r0 + ldd r0,Y+46 + eor r19,r0 + ldd r0,Y+47 + eor r20,r0 + ldd r0,Y+48 + eor r21,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + ldi r27,2 + eor r22,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r14 + std Y+42,r12 + std Y+43,r24 + std Y+44,r17 + std Y+45,r16 + std Y+46,r15 + std Y+47,r25 + std Y+48,r13 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + mov r0,r4 + mov r4,r6 + mov r6,r0 + mov r0,r5 + mov r5,r7 + mov r7,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+33 + eor r18,r0 + ldd r0,Y+34 + eor r19,r0 + ldd r0,Y+35 + eor r20,r0 + ldd r0,Y+36 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldd r0,Y+37 + eor r22,r0 + ldd r0,Y+38 + eor r23,r0 + ldd r0,Y+39 + eor r2,r0 + ldd r0,Y+40 + eor r3,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + ldi r27,2 + eor r4,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + cp r26,r1 + breq 903f + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 227b +903: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+49 + ldd r27,Y+50 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,50 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_384_decrypt, .-skinny_128_384_decrypt + + .text +.global skinny_128_256_init + .type skinny_128_256_init, @function +skinny_128_256_init: + movw r30,r24 + movw r26,r22 +.L__stack_usage = 2 + ldi r22,8 +1: + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + st Z+,r18 + st Z+,r19 + st Z+,r20 + st Z+,r21 + dec r22 + brne 1b + ret + .size skinny_128_256_init, .-skinny_128_256_init + + .text +.global skinny_128_256_encrypt + .type skinny_128_256_encrypt, @function +skinny_128_256_encrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,32 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 52 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + ldd r18,Z+4 + ldd r19,Z+5 + ldd r20,Z+6 + ldd r21,Z+7 + std Y+5,r18 + std Y+6,r19 + std Y+7,r20 + std Y+8,r21 + ldd r18,Z+8 + ldd r19,Z+9 + ldd r20,Z+10 + ldd r21,Z+11 + std Y+9,r18 + std Y+10,r19 + std Y+11,r20 + std Y+12,r21 + ldd r18,Z+12 + ldd r19,Z+13 + ldd r20,Z+14 + ldd r21,Z+15 + std Y+13,r18 + std Y+14,r19 + std Y+15,r20 + std Y+16,r21 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + ldd r18,Z+20 + ldd r19,Z+21 + ldd r20,Z+22 + ldd r21,Z+23 + std Y+21,r18 + std Y+22,r19 + std Y+23,r20 + std Y+24,r21 + ldd r18,Z+24 + ldd r19,Z+25 + ldd r20,Z+26 + ldd r21,Z+27 + std Y+25,r18 + std Y+26,r19 + std Y+27,r20 + std Y+28,r21 + ldd r18,Z+28 + ldd r19,Z+29 + ldd r20,Z+30 + ldd r21,Z+31 + std Y+29,r18 + std Y+30,r19 + std Y+31,r20 + std Y+32,r21 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r26,hh8(table_0) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + mov r26,r1 +82: + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + ldi r27,2 + eor r4,r27 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + mov r0,r6 + mov r6,r4 + mov r4,r0 + mov r0,r7 + mov r7,r5 + mov r5,r0 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + ldi r27,2 + eor r22,r27 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + mov r0,r2 + mov r2,r22 + mov r22,r0 + mov r0,r3 + mov r3,r23 + mov r23,r0 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + ldi r27,2 + eor r18,r27 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + mov r0,r20 + mov r20,r18 + mov r18,r0 + mov r0,r21 + mov r21,r19 + mov r19,r0 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + ldi r27,2 + eor r8,r27 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + mov r0,r10 + mov r10,r8 + mov r8,r0 + mov r0,r11 + mov r11,r9 + mov r9,r0 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + cpi r26,96 + breq 594f + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 82b +594: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+33 + ldd r27,Y+34 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,34 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_256_encrypt, .-skinny_128_256_encrypt + +.global skinny_128_256_encrypt_tk_full + .set skinny_128_256_encrypt_tk_full,skinny_128_256_encrypt + + .text +.global skinny_128_256_decrypt + .type skinny_128_256_decrypt, @function +skinny_128_256_decrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,32 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 52 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + ldd r22,Z+4 + ldd r23,Z+5 + ldd r2,Z+6 + ldd r3,Z+7 + ldd r4,Z+8 + ldd r5,Z+9 + ldd r6,Z+10 + ldd r7,Z+11 + ldd r8,Z+12 + ldd r9,Z+13 + ldd r10,Z+14 + ldd r11,Z+15 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + std Y+5,r22 + std Y+6,r23 + std Y+7,r2 + std Y+8,r3 + std Y+9,r4 + std Y+10,r5 + std Y+11,r6 + std Y+12,r7 + std Y+13,r8 + std Y+14,r9 + std Y+15,r10 + std Y+16,r11 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + ldd r22,Z+20 + ldd r23,Z+21 + ldd r2,Z+22 + ldd r3,Z+23 + ldd r4,Z+24 + ldd r5,Z+25 + ldd r6,Z+26 + ldd r7,Z+27 + ldd r8,Z+28 + ldd r9,Z+29 + ldd r10,Z+30 + ldd r11,Z+31 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + std Y+21,r22 + std Y+22,r23 + std Y+23,r2 + std Y+24,r3 + std Y+25,r4 + std Y+26,r5 + std Y+27,r6 + std Y+28,r7 + std Y+29,r8 + std Y+30,r9 + std Y+31,r10 + std Y+32,r11 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r26,hh8(table_2) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,24 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 +90: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 90b + std Y+17,r12 + std Y+18,r13 + std Y+19,r14 + std Y+20,r15 + std Y+21,r24 + std Y+22,r25 + std Y+23,r16 + std Y+24,r17 + ldi r26,24 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 +118: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 118b + std Y+25,r12 + std Y+26,r13 + std Y+27,r14 + std Y+28,r15 + std Y+29,r24 + std Y+30,r25 + std Y+31,r16 + std Y+32,r17 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r26,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,96 +139: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + mov r0,r8 + mov r8,r10 + mov r10,r0 + mov r0,r9 + mov r9,r11 + mov r11,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + ldi r27,2 + eor r8,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + mov r0,r18 + mov r18,r20 + mov r20,r0 + mov r0,r19 + mov r19,r21 + mov r21,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + ldi r27,2 + eor r18,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + mov r0,r22 + mov r22,r2 + mov r2,r0 + mov r0,r23 + mov r23,r3 + mov r3,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + ldi r27,2 + eor r22,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + mov r0,r4 + mov r4,r6 + mov r6,r0 + mov r0,r5 + mov r5,r7 + mov r7,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + ldi r27,2 + eor r4,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + cp r26,r1 + breq 651f + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 139b +651: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+33 + ldd r27,Y+34 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,34 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_256_decrypt, .-skinny_128_256_decrypt + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128.c b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128.c new file mode 100644 index 0000000..cb1fbda --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128.c @@ -0,0 +1,801 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "internal-skinny128.h" +#include "internal-skinnyutil.h" +#include "internal-util.h" +#include + +#if !defined(__AVR__) + +STATIC_INLINE void skinny128_fast_forward_tk(uint32_t *tk) +{ + /* This function is used to fast-forward the TK1 tweak value + * to the value at the end of the key schedule for decryption. + * + * The tweak permutation repeats every 16 rounds, so SKINNY-128-256 + * with 48 rounds does not need any fast forwarding applied. + * SKINNY-128-128 with 40 rounds and SKINNY-128-384 with 56 rounds + * are equivalent to applying the permutation 8 times: + * + * PT*8 = [5, 6, 3, 2, 7, 0, 1, 4, 13, 14, 11, 10, 15, 8, 9, 12] + */ + uint32_t row0 = tk[0]; + uint32_t row1 = tk[1]; + uint32_t row2 = tk[2]; + uint32_t row3 = tk[3]; + tk[0] = ((row1 >> 8) & 0x0000FFFFU) | + ((row0 >> 8) & 0x00FF0000U) | + ((row0 << 8) & 0xFF000000U); + tk[1] = ((row1 >> 24) & 0x000000FFU) | + ((row0 << 8) & 0x00FFFF00U) | + ((row1 << 24) & 0xFF000000U); + tk[2] = ((row3 >> 8) & 0x0000FFFFU) | + ((row2 >> 8) & 0x00FF0000U) | + ((row2 << 8) & 0xFF000000U); + tk[3] = ((row3 >> 24) & 0x000000FFU) | + ((row2 << 8) & 0x00FFFF00U) | + ((row3 << 24) & 0xFF000000U); +} + +void skinny_128_384_init + (skinny_128_384_key_schedule_t *ks, const unsigned char key[48]) +{ +#if !SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint32_t *schedule; + unsigned round; + uint8_t rc; +#endif + +#if SKINNY_128_SMALL_SCHEDULE + /* Copy the input key as-is when using the small key schedule version */ + memcpy(ks->TK1, key, sizeof(ks->TK1)); + memcpy(ks->TK2, key + 16, sizeof(ks->TK2)); + memcpy(ks->TK3, key + 32, sizeof(ks->TK3)); +#else + /* Set the initial states of TK1, TK2, and TK3 */ + memcpy(ks->TK1, key, 16); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + TK3[0] = le_load_word32(key + 32); + TK3[1] = le_load_word32(key + 36); + TK3[2] = le_load_word32(key + 40); + TK3[3] = le_load_word32(key + 44); + + /* Set up the key schedule using TK2 and TK3. TK1 is not added + * to the key schedule because we will derive that part of the + * schedule during encryption operations */ + schedule = ks->k; + rc = 0; + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round, schedule += 2) { + /* XOR the round constants with the current schedule words. + * The round constants for the 3rd and 4th rows are + * fixed and will be applied during encryption. */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + schedule[0] = TK2[0] ^ TK3[0] ^ (rc & 0x0F); + schedule[1] = TK2[1] ^ TK3[1] ^ (rc >> 4); + + /* Permute TK2 and TK3 for the next round */ + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + + /* Apply the LFSR's to TK2 and TK3 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + } +#endif +} + +void skinny_128_384_encrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 for the next round */ + skinny128_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_decrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint8_t rc = 0x15; +#else + const uint32_t *schedule = &(ks->k[SKINNY_128_384_ROUNDS * 2 - 2]); +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1 */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Permute TK1 to fast-forward it to the end of the key schedule */ + skinny128_fast_forward_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_fast_forward_tk(TK2); + skinny128_fast_forward_tk(TK3); + for (round = 0; round < SKINNY_128_384_ROUNDS; round += 2) { + /* Also fast-forward the LFSR's on every byte of TK2 and TK3 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR2(TK2[2]); + skinny128_LFSR2(TK2[3]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + skinny128_LFSR3(TK3[2]); + skinny128_LFSR3(TK3[3]); + } +#endif + + /* Perform all decryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Inverse permutation on TK1 for this round */ + skinny128_inv_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_inv_permute_tk(TK2); + skinny128_inv_permute_tk(TK3); + skinny128_LFSR3(TK2[2]); + skinny128_LFSR3(TK2[3]); + skinny128_LFSR2(TK3[2]); + skinny128_LFSR2(TK3[3]); +#endif + + /* Inverse mix of the columns */ + temp = s3; + s3 = s0; + s0 = s1; + s1 = s2; + s3 ^= temp; + s2 = temp ^ s0; + s1 ^= s2; + + /* Inverse shift of the rows */ + s1 = leftRotate24(s1); + s2 = leftRotate16(s2); + s3 = leftRotate8(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc >> 1) ^ (((rc << 5) ^ rc ^ 0x20) & 0x20); + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; + schedule -= 2; +#endif + s2 ^= 0x02; + + /* Apply the inverse of the S-box to all bytes in the state */ + skinny128_inv_sbox(s0); + skinny128_inv_sbox(s1); + skinny128_inv_sbox(s2); + skinny128_inv_sbox(s3); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK3[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); + TK2[0] = le_load_word32(tk2); + TK2[1] = le_load_word32(tk2 + 4); + TK2[2] = le_load_word32(tk2 + 8); + TK2[3] = le_load_word32(tk2 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0] ^ TK2[0]; + s1 ^= schedule[1] ^ TK1[1] ^ TK2[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK3); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_encrypt_tk_full + (const unsigned char key[48], unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; + uint32_t TK3[4]; + uint32_t temp; + unsigned round; + uint8_t rc = 0; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakey */ + TK1[0] = le_load_word32(key); + TK1[1] = le_load_word32(key + 4); + TK1[2] = le_load_word32(key + 8); + TK1[3] = le_load_word32(key + 12); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + TK3[0] = le_load_word32(key + 32); + TK3[1] = le_load_word32(key + 36); + TK3[2] = le_load_word32(key + 40); + TK3[3] = le_load_word32(key + 44); + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1, TK2, and TK3 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_init + (skinny_128_256_key_schedule_t *ks, const unsigned char key[32]) +{ +#if !SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t *schedule; + unsigned round; + uint8_t rc; +#endif + +#if SKINNY_128_SMALL_SCHEDULE + /* Copy the input key as-is when using the small key schedule version */ + memcpy(ks->TK1, key, sizeof(ks->TK1)); + memcpy(ks->TK2, key + 16, sizeof(ks->TK2)); +#else + /* Set the initial states of TK1 and TK2 */ + memcpy(ks->TK1, key, 16); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + + /* Set up the key schedule using TK2. TK1 is not added + * to the key schedule because we will derive that part of the + * schedule during encryption operations */ + schedule = ks->k; + rc = 0; + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round, schedule += 2) { + /* XOR the round constants with the current schedule words. + * The round constants for the 3rd and 4th rows are + * fixed and will be applied during encryption. */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + schedule[0] = TK2[0] ^ (rc & 0x0F); + schedule[1] = TK2[1] ^ (rc >> 4); + + /* Permute TK2 for the next round */ + skinny128_permute_tk(TK2); + + /* Apply the LFSR to TK2 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + } +#endif +} + +void skinny_128_256_encrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1 */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_decrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint8_t rc = 0x09; +#else + const uint32_t *schedule = &(ks->k[SKINNY_128_256_ROUNDS * 2 - 2]); +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1. + * There is no need to fast-forward TK1 because the value at + * the end of the key schedule is the same as at the start */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + for (round = 0; round < SKINNY_128_256_ROUNDS; round += 2) { + /* Also fast-forward the LFSR's on every byte of TK2 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR2(TK2[2]); + skinny128_LFSR2(TK2[3]); + } +#endif + + /* Perform all decryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Inverse permutation on TK1 for this round */ + skinny128_inv_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_inv_permute_tk(TK2); + skinny128_LFSR3(TK2[2]); + skinny128_LFSR3(TK2[3]); +#endif + + /* Inverse mix of the columns */ + temp = s3; + s3 = s0; + s0 = s1; + s1 = s2; + s3 ^= temp; + s2 = temp ^ s0; + s1 ^= s2; + + /* Inverse shift of the rows */ + s1 = leftRotate24(s1); + s2 = leftRotate16(s2); + s3 = leftRotate8(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc >> 1) ^ (((rc << 5) ^ rc ^ 0x20) & 0x20); + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; + schedule -= 2; +#endif + s2 ^= 0x02; + + /* Apply the inverse of the S-box to all bytes in the state */ + skinny128_inv_sbox(s0); + skinny128_inv_sbox(s1); + skinny128_inv_sbox(s2); + skinny128_inv_sbox(s3); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_encrypt_tk_full + (const unsigned char key[32], unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; + uint32_t temp; + unsigned round; + uint8_t rc = 0; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakey */ + TK1[0] = le_load_word32(key); + TK1[1] = le_load_word32(key + 4); + TK1[2] = le_load_word32(key + 8); + TK1[3] = le_load_word32(key + 12); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +#else /* __AVR__ */ + +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2) +{ + memcpy(ks->TK2, tk2, 16); + skinny_128_384_encrypt(ks, output, input); +} + +#endif /* __AVR__ */ diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128.h b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128.h new file mode 100644 index 0000000..2bfda3c --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinny128.h @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_SKINNY128_H +#define LW_INTERNAL_SKINNY128_H + +/** + * \file internal-skinny128.h + * \brief SKINNY-128 block cipher family. + * + * References: https://eprint.iacr.org/2016/660.pdf, + * https://sites.google.com/site/skinnycipher/ + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \def SKINNY_128_SMALL_SCHEDULE + * \brief Defined to 1 to use the small key schedule version of SKINNY-128. + */ +#if defined(__AVR__) +#define SKINNY_128_SMALL_SCHEDULE 1 +#else +#define SKINNY_128_SMALL_SCHEDULE 0 +#endif + +/** + * \brief Size of a block for SKINNY-128 block ciphers. + */ +#define SKINNY_128_BLOCK_SIZE 16 + +/** + * \brief Number of rounds for SKINNY-128-384. + */ +#define SKINNY_128_384_ROUNDS 56 + +/** + * \brief Structure of the key schedule for SKINNY-128-384. + */ +typedef struct +{ + /** TK1 for the tweakable part of the key schedule */ + uint8_t TK1[16]; + +#if SKINNY_128_SMALL_SCHEDULE + /** TK2 for the small key schedule */ + uint8_t TK2[16]; + + /** TK3 for the small key schedule */ + uint8_t TK3[16]; +#else + /** Words of the full key schedule */ + uint32_t k[SKINNY_128_384_ROUNDS * 2]; +#endif + +} skinny_128_384_key_schedule_t; + +/** + * \brief Initializes the key schedule for SKINNY-128-384. + * + * \param ks Points to the key schedule to initialize. + * \param key Points to the key data. + */ +void skinny_128_384_init + (skinny_128_384_key_schedule_t *ks, const unsigned char key[48]); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_384_encrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Decrypts a 128-bit block with SKINNY-128-384. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_384_decrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384 and an explicitly + * provided TK2 value. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * \param tk2 TK2 value that should be updated on the fly. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when both TK1 and TK2 change from block to block. + * When the key is initialized with skinny_128_384_init(), the TK2 part of + * the key value should be set to zero. + * + * \note Some versions of this function may modify the key schedule to + * copy tk2 into place. + */ +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384 and a + * fully specified tweakey value. + * + * \param key Points to the 384-bit tweakey value. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when the entire tweakey changes from block to + * block. It is slower than the other versions of SKINNY-128-384 but + * more memory-efficient. + */ +void skinny_128_384_encrypt_tk_full + (const unsigned char key[48], unsigned char *output, + const unsigned char *input); + +/** + * \brief Number of rounds for SKINNY-128-256. + */ +#define SKINNY_128_256_ROUNDS 48 + +/** + * \brief Structure of the key schedule for SKINNY-128-256. + */ +typedef struct +{ + /** TK1 for the tweakable part of the key schedule */ + uint8_t TK1[16]; + +#if SKINNY_128_SMALL_SCHEDULE + /** TK2 for the small key schedule */ + uint8_t TK2[16]; +#else + /** Words of the full key schedule */ + uint32_t k[SKINNY_128_256_ROUNDS * 2]; +#endif + +} skinny_128_256_key_schedule_t; + +/** + * \brief Initializes the key schedule for SKINNY-128-256. + * + * \param ks Points to the key schedule to initialize. + * \param key Points to the key data. + */ +void skinny_128_256_init + (skinny_128_256_key_schedule_t *ks, const unsigned char key[32]); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-256. + * + * \param ks Points to the SKINNY-128-256 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_256_encrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Decrypts a 128-bit block with SKINNY-128-256. + * + * \param ks Points to the SKINNY-128-256 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_256_decrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-256 and a + * fully specified tweakey value. + * + * \param key Points to the 256-bit tweakey value. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when the entire tweakey changes from block to + * block. It is slower than the other versions of SKINNY-128-256 but + * more memory-efficient. + */ +void skinny_128_256_encrypt_tk_full + (const unsigned char key[32], unsigned char *output, + const unsigned char *input); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinnyutil.h b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinnyutil.h new file mode 100644 index 0000000..83136cb --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-skinnyutil.h @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_SKINNYUTIL_H +#define LW_INTERNAL_SKINNYUTIL_H + +/** + * \file internal-skinnyutil.h + * \brief Utilities to help implement SKINNY and its variants. + */ + +#include "internal-util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond skinnyutil */ + +/* Utilities for implementing SKINNY-128 */ + +#define skinny128_LFSR2(x) \ + do { \ + uint32_t _x = (x); \ + (x) = ((_x << 1) & 0xFEFEFEFEU) ^ \ + (((_x >> 7) ^ (_x >> 5)) & 0x01010101U); \ + } while (0) + + +#define skinny128_LFSR3(x) \ + do { \ + uint32_t _x = (x); \ + (x) = ((_x >> 1) & 0x7F7F7F7FU) ^ \ + (((_x << 7) ^ (_x << 1)) & 0x80808080U); \ + } while (0) + +/* LFSR2 and LFSR3 are inverses of each other */ +#define skinny128_inv_LFSR2(x) skinny128_LFSR3(x) +#define skinny128_inv_LFSR3(x) skinny128_LFSR2(x) + +#define skinny128_permute_tk(tk) \ + do { \ + /* PT = [9, 15, 8, 13, 10, 14, 12, 11, 0, 1, 2, 3, 4, 5, 6, 7] */ \ + uint32_t row2 = tk[2]; \ + uint32_t row3 = tk[3]; \ + tk[2] = tk[0]; \ + tk[3] = tk[1]; \ + row3 = (row3 << 16) | (row3 >> 16); \ + tk[0] = ((row2 >> 8) & 0x000000FFU) | \ + ((row2 << 16) & 0x00FF0000U) | \ + ( row3 & 0xFF00FF00U); \ + tk[1] = ((row2 >> 16) & 0x000000FFU) | \ + (row2 & 0xFF000000U) | \ + ((row3 << 8) & 0x0000FF00U) | \ + ( row3 & 0x00FF0000U); \ + } while (0) + +#define skinny128_inv_permute_tk(tk) \ + do { \ + /* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \ + uint32_t row0 = tk[0]; \ + uint32_t row1 = tk[1]; \ + tk[0] = tk[2]; \ + tk[1] = tk[3]; \ + tk[2] = ((row0 >> 16) & 0x000000FFU) | \ + ((row0 << 8) & 0x0000FF00U) | \ + ((row1 << 16) & 0x00FF0000U) | \ + ( row1 & 0xFF000000U); \ + tk[3] = ((row0 >> 16) & 0x0000FF00U) | \ + ((row0 << 16) & 0xFF000000U) | \ + ((row1 >> 16) & 0x000000FFU) | \ + ((row1 << 8) & 0x00FF0000U); \ + } while (0) + +/* + * Apply the SKINNY sbox. The original version from the specification is + * equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x11111111U) ^ (x)) + * #define SBOX_SWAP(x) + * (((x) & 0xF9F9F9F9U) | + * (((x) >> 1) & 0x02020202U) | + * (((x) << 1) & 0x04040404U)) + * #define SBOX_PERMUTE(x) + * ((((x) & 0x01010101U) << 2) | + * (((x) & 0x06060606U) << 5) | + * (((x) & 0x20202020U) >> 5) | + * (((x) & 0xC8C8C8C8U) >> 2) | + * (((x) & 0x10101010U) >> 1)) + * + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * return SBOX_SWAP(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_PERMUTE and SBOX_SWAP steps to be performed with one + * final permuatation. This reduces the number of shift operations. + */ +#define skinny128_sbox(x) \ +do { \ + uint32_t y; \ + \ + /* Mix the bits */ \ + x = ~x; \ + x ^= (((x >> 2) & (x >> 3)) & 0x11111111U); \ + y = (((x << 5) & (x << 1)) & 0x20202020U); \ + x ^= (((x << 5) & (x << 4)) & 0x40404040U) ^ y; \ + y = (((x << 2) & (x << 1)) & 0x80808080U); \ + x ^= (((x >> 2) & (x << 1)) & 0x02020202U) ^ y; \ + y = (((x >> 5) & (x << 1)) & 0x04040404U); \ + x ^= (((x >> 1) & (x >> 2)) & 0x08080808U) ^ y; \ + x = ~x; \ + \ + /* Permutation generated by http://programming.sirrida.de/calcperm.php */ \ + /* The final permutation for each byte is [2 7 6 1 3 0 4 5] */ \ + x = ((x & 0x08080808U) << 1) | \ + ((x & 0x32323232U) << 2) | \ + ((x & 0x01010101U) << 5) | \ + ((x & 0x80808080U) >> 6) | \ + ((x & 0x40404040U) >> 4) | \ + ((x & 0x04040404U) >> 2); \ +} while (0) + +/* + * Apply the inverse of the SKINNY sbox. The original version from the + * specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x11111111U) ^ (x)) + * #define SBOX_SWAP(x) + * (((x) & 0xF9F9F9F9U) | + * (((x) >> 1) & 0x02020202U) | + * (((x) << 1) & 0x04040404U)) + * #define SBOX_PERMUTE_INV(x) + * ((((x) & 0x08080808U) << 1) | + * (((x) & 0x32323232U) << 2) | + * (((x) & 0x01010101U) << 5) | + * (((x) & 0xC0C0C0C0U) >> 5) | + * (((x) & 0x04040404U) >> 2)) + * + * x = SBOX_SWAP(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * return SBOX_MIX(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_PERMUTE_INV and SBOX_SWAP steps to be performed with one + * final permuatation. This reduces the number of shift operations. + */ +#define skinny128_inv_sbox(x) \ +do { \ + uint32_t y; \ + \ + /* Mix the bits */ \ + x = ~x; \ + y = (((x >> 1) & (x >> 3)) & 0x01010101U); \ + x ^= (((x >> 2) & (x >> 3)) & 0x10101010U) ^ y; \ + y = (((x >> 6) & (x >> 1)) & 0x02020202U); \ + x ^= (((x >> 1) & (x >> 2)) & 0x08080808U) ^ y; \ + y = (((x << 2) & (x << 1)) & 0x80808080U); \ + x ^= (((x >> 1) & (x << 2)) & 0x04040404U) ^ y; \ + y = (((x << 5) & (x << 1)) & 0x20202020U); \ + x ^= (((x << 4) & (x << 5)) & 0x40404040U) ^ y; \ + x = ~x; \ + \ + /* Permutation generated by http://programming.sirrida.de/calcperm.php */ \ + /* The final permutation for each byte is [5 3 0 4 6 7 2 1] */ \ + x = ((x & 0x01010101U) << 2) | \ + ((x & 0x04040404U) << 4) | \ + ((x & 0x02020202U) << 6) | \ + ((x & 0x20202020U) >> 5) | \ + ((x & 0xC8C8C8C8U) >> 2) | \ + ((x & 0x10101010U) >> 1); \ +} while (0) + +/* Utilities for implementing SKINNY-64 */ + +#define skinny64_LFSR2(x) \ + do { \ + uint16_t _x = (x); \ + (x) = ((_x << 1) & 0xEEEEU) ^ (((_x >> 3) ^ (_x >> 2)) & 0x1111U); \ + } while (0) + +#define skinny64_LFSR3(x) \ + do { \ + uint16_t _x = (x); \ + (x) = ((_x >> 1) & 0x7777U) ^ ((_x ^ (_x << 3)) & 0x8888U); \ + } while (0) + +/* LFSR2 and LFSR3 are inverses of each other */ +#define skinny64_inv_LFSR2(x) skinny64_LFSR3(x) +#define skinny64_inv_LFSR3(x) skinny64_LFSR2(x) + +#define skinny64_permute_tk(tk) \ + do { \ + /* PT = [9, 15, 8, 13, 10, 14, 12, 11, 0, 1, 2, 3, 4, 5, 6, 7] */ \ + uint16_t row2 = tk[2]; \ + uint16_t row3 = tk[3]; \ + tk[2] = tk[0]; \ + tk[3] = tk[1]; \ + row3 = (row3 << 8) | (row3 >> 8); \ + tk[0] = ((row2 << 4) & 0xF000U) | \ + ((row2 >> 8) & 0x00F0U) | \ + ( row3 & 0x0F0FU); \ + tk[1] = ((row2 << 8) & 0xF000U) | \ + ((row3 >> 4) & 0x0F00U) | \ + ( row3 & 0x00F0U) | \ + ( row2 & 0x000FU); \ + } while (0) + +#define skinny64_inv_permute_tk(tk) \ + do { \ + /* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \ + uint16_t row0 = tk[0]; \ + uint16_t row1 = tk[1]; \ + tk[0] = tk[2]; \ + tk[1] = tk[3]; \ + tk[2] = ((row0 << 8) & 0xF000U) | \ + ((row0 >> 4) & 0x0F00U) | \ + ((row1 >> 8) & 0x00F0U) | \ + ( row1 & 0x000FU); \ + tk[3] = ((row1 << 8) & 0xF000U) | \ + ((row0 << 8) & 0x0F00U) | \ + ((row1 >> 4) & 0x00F0U) | \ + ((row0 >> 8) & 0x000FU); \ + } while (0) + +/* + * Apply the SKINNY-64 sbox. The original version from the + * specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x1111U) ^ (x)) + * #define SBOX_SHIFT(x) + * ((((x) << 1) & 0xEEEEU) | (((x) >> 3) & 0x1111U)) + * + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * return SBOX_MIX(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_SHIFT steps to be performed with one final rotation. + * This reduces the number of required shift operations from 14 to 10. + * + * We can further reduce the number of NOT operations from 4 to 2 + * using the technique from https://github.com/kste/skinny_avx to + * convert NOR-XOR operations into AND-XOR operations by converting + * the S-box into its NOT-inverse. + */ +#define skinny64_sbox(x) \ +do { \ + x = ~x; \ + x = (((x >> 3) & (x >> 2)) & 0x1111U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x8888U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x4444U) ^ x; \ + x = (((x >> 2) & (x << 1)) & 0x2222U) ^ x; \ + x = ~x; \ + x = ((x >> 1) & 0x7777U) | ((x << 3) & 0x8888U); \ +} while (0) + +/* + * Apply the inverse of the SKINNY-64 sbox. The original version + * from the specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x1111U) ^ (x)) + * #define SBOX_SHIFT_INV(x) + * ((((x) >> 1) & 0x7777U) | (((x) << 3) & 0x8888U)) + * + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * return SBOX_MIX(x); + */ +#define skinny64_inv_sbox(x) \ +do { \ + x = ~x; \ + x = (((x >> 3) & (x >> 2)) & 0x1111U) ^ x; \ + x = (((x << 1) & (x >> 2)) & 0x2222U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x4444U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x8888U) ^ x; \ + x = ~x; \ + x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \ +} while (0) + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-util.h b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-util.h new file mode 100644 index 0000000..e30166d --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/internal-util.h @@ -0,0 +1,702 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_UTIL_H +#define LW_INTERNAL_UTIL_H + +#include + +/* Figure out how to inline functions using this C compiler */ +#if defined(__STDC__) && __STDC_VERSION__ >= 199901L +#define STATIC_INLINE static inline +#elif defined(__GNUC__) || defined(__clang__) +#define STATIC_INLINE static __inline__ +#else +#define STATIC_INLINE static +#endif + +/* Try to figure out whether the CPU is little-endian or big-endian. + * May need to modify this to include new compiler-specific defines. + * Alternatively, define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ in your + * compiler flags when you compile this library */ +#if defined(__x86_64) || defined(__x86_64__) || \ + defined(__i386) || defined(__i386__) || \ + defined(__AVR__) || defined(__arm) || defined(__arm__) || \ + defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86) || \ + defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM_FP) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 1234) || \ + defined(__LITTLE_ENDIAN__) +#define LW_UTIL_LITTLE_ENDIAN 1 +#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 4321) || \ + defined(__BIG_ENDIAN__) +/* Big endian */ +#else +#error "Cannot determine the endianess of this platform" +#endif + +/* Helper macros to load and store values while converting endian-ness */ + +/* Load a big-endian 32-bit word from a byte buffer */ +#define be_load_word32(ptr) \ + ((((uint32_t)((ptr)[0])) << 24) | \ + (((uint32_t)((ptr)[1])) << 16) | \ + (((uint32_t)((ptr)[2])) << 8) | \ + ((uint32_t)((ptr)[3]))) + +/* Store a big-endian 32-bit word into a byte buffer */ +#define be_store_word32(ptr, x) \ + do { \ + uint32_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 24); \ + (ptr)[1] = (uint8_t)(_x >> 16); \ + (ptr)[2] = (uint8_t)(_x >> 8); \ + (ptr)[3] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 32-bit word from a byte buffer */ +#define le_load_word32(ptr) \ + ((((uint32_t)((ptr)[3])) << 24) | \ + (((uint32_t)((ptr)[2])) << 16) | \ + (((uint32_t)((ptr)[1])) << 8) | \ + ((uint32_t)((ptr)[0]))) + +/* Store a little-endian 32-bit word into a byte buffer */ +#define le_store_word32(ptr, x) \ + do { \ + uint32_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + (ptr)[2] = (uint8_t)(_x >> 16); \ + (ptr)[3] = (uint8_t)(_x >> 24); \ + } while (0) + +/* Load a big-endian 64-bit word from a byte buffer */ +#define be_load_word64(ptr) \ + ((((uint64_t)((ptr)[0])) << 56) | \ + (((uint64_t)((ptr)[1])) << 48) | \ + (((uint64_t)((ptr)[2])) << 40) | \ + (((uint64_t)((ptr)[3])) << 32) | \ + (((uint64_t)((ptr)[4])) << 24) | \ + (((uint64_t)((ptr)[5])) << 16) | \ + (((uint64_t)((ptr)[6])) << 8) | \ + ((uint64_t)((ptr)[7]))) + +/* Store a big-endian 64-bit word into a byte buffer */ +#define be_store_word64(ptr, x) \ + do { \ + uint64_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 56); \ + (ptr)[1] = (uint8_t)(_x >> 48); \ + (ptr)[2] = (uint8_t)(_x >> 40); \ + (ptr)[3] = (uint8_t)(_x >> 32); \ + (ptr)[4] = (uint8_t)(_x >> 24); \ + (ptr)[5] = (uint8_t)(_x >> 16); \ + (ptr)[6] = (uint8_t)(_x >> 8); \ + (ptr)[7] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 64-bit word from a byte buffer */ +#define le_load_word64(ptr) \ + ((((uint64_t)((ptr)[7])) << 56) | \ + (((uint64_t)((ptr)[6])) << 48) | \ + (((uint64_t)((ptr)[5])) << 40) | \ + (((uint64_t)((ptr)[4])) << 32) | \ + (((uint64_t)((ptr)[3])) << 24) | \ + (((uint64_t)((ptr)[2])) << 16) | \ + (((uint64_t)((ptr)[1])) << 8) | \ + ((uint64_t)((ptr)[0]))) + +/* Store a little-endian 64-bit word into a byte buffer */ +#define le_store_word64(ptr, x) \ + do { \ + uint64_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + (ptr)[2] = (uint8_t)(_x >> 16); \ + (ptr)[3] = (uint8_t)(_x >> 24); \ + (ptr)[4] = (uint8_t)(_x >> 32); \ + (ptr)[5] = (uint8_t)(_x >> 40); \ + (ptr)[6] = (uint8_t)(_x >> 48); \ + (ptr)[7] = (uint8_t)(_x >> 56); \ + } while (0) + +/* Load a big-endian 16-bit word from a byte buffer */ +#define be_load_word16(ptr) \ + ((((uint16_t)((ptr)[0])) << 8) | \ + ((uint16_t)((ptr)[1]))) + +/* Store a big-endian 16-bit word into a byte buffer */ +#define be_store_word16(ptr, x) \ + do { \ + uint16_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 8); \ + (ptr)[1] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 16-bit word from a byte buffer */ +#define le_load_word16(ptr) \ + ((((uint16_t)((ptr)[1])) << 8) | \ + ((uint16_t)((ptr)[0]))) + +/* Store a little-endian 16-bit word into a byte buffer */ +#define le_store_word16(ptr, x) \ + do { \ + uint16_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + } while (0) + +/* XOR a source byte buffer against a destination */ +#define lw_xor_block(dest, src, len) \ + do { \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest++ ^= *_src++; \ + --_len; \ + } \ + } while (0) + +/* XOR two source byte buffers and put the result in a destination buffer */ +#define lw_xor_block_2_src(dest, src1, src2, len) \ + do { \ + unsigned char *_dest = (dest); \ + const unsigned char *_src1 = (src1); \ + const unsigned char *_src2 = (src2); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest++ = *_src1++ ^ *_src2++; \ + --_len; \ + } \ + } while (0) + +/* XOR a source byte buffer against a destination and write to another + * destination at the same time */ +#define lw_xor_block_2_dest(dest2, dest, src, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest2++ = (*_dest++ ^= *_src++); \ + --_len; \ + } \ + } while (0) + +/* XOR two byte buffers and write to a destination which at the same + * time copying the contents of src2 to dest2 */ +#define lw_xor_block_copy_src(dest2, dest, src1, src2, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src1 = (src1); \ + const unsigned char *_src2 = (src2); \ + unsigned _len = (len); \ + while (_len > 0) { \ + unsigned char _temp = *_src2++; \ + *_dest2++ = _temp; \ + *_dest++ = *_src1++ ^ _temp; \ + --_len; \ + } \ + } while (0) + +/* XOR a source byte buffer against a destination and write to another + * destination at the same time. This version swaps the source value + * into the "dest" buffer */ +#define lw_xor_block_swap(dest2, dest, src, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + unsigned char _temp = *_src++; \ + *_dest2++ = *_dest ^ _temp; \ + *_dest++ = _temp; \ + --_len; \ + } \ + } while (0) + +/* Rotation functions need to be optimised for best performance on AVR. + * The most efficient rotations are where the number of bits is 1 or a + * multiple of 8, so we compose the efficient rotations to produce all + * other rotation counts of interest. */ + +#if defined(__AVR__) +#define LW_CRYPTO_ROTATE32_COMPOSED 1 +#else +#define LW_CRYPTO_ROTATE32_COMPOSED 0 +#endif + +/* Rotation macros for 32-bit arguments */ + +/* Generic left rotate */ +#define leftRotate(a, bits) \ + (__extension__ ({ \ + uint32_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (32 - (bits))); \ + })) + +/* Generic right rotate */ +#define rightRotate(a, bits) \ + (__extension__ ({ \ + uint32_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (32 - (bits))); \ + })) + +#if !LW_CRYPTO_ROTATE32_COMPOSED + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1(a) (leftRotate((a), 1)) +#define leftRotate2(a) (leftRotate((a), 2)) +#define leftRotate3(a) (leftRotate((a), 3)) +#define leftRotate4(a) (leftRotate((a), 4)) +#define leftRotate5(a) (leftRotate((a), 5)) +#define leftRotate6(a) (leftRotate((a), 6)) +#define leftRotate7(a) (leftRotate((a), 7)) +#define leftRotate8(a) (leftRotate((a), 8)) +#define leftRotate9(a) (leftRotate((a), 9)) +#define leftRotate10(a) (leftRotate((a), 10)) +#define leftRotate11(a) (leftRotate((a), 11)) +#define leftRotate12(a) (leftRotate((a), 12)) +#define leftRotate13(a) (leftRotate((a), 13)) +#define leftRotate14(a) (leftRotate((a), 14)) +#define leftRotate15(a) (leftRotate((a), 15)) +#define leftRotate16(a) (leftRotate((a), 16)) +#define leftRotate17(a) (leftRotate((a), 17)) +#define leftRotate18(a) (leftRotate((a), 18)) +#define leftRotate19(a) (leftRotate((a), 19)) +#define leftRotate20(a) (leftRotate((a), 20)) +#define leftRotate21(a) (leftRotate((a), 21)) +#define leftRotate22(a) (leftRotate((a), 22)) +#define leftRotate23(a) (leftRotate((a), 23)) +#define leftRotate24(a) (leftRotate((a), 24)) +#define leftRotate25(a) (leftRotate((a), 25)) +#define leftRotate26(a) (leftRotate((a), 26)) +#define leftRotate27(a) (leftRotate((a), 27)) +#define leftRotate28(a) (leftRotate((a), 28)) +#define leftRotate29(a) (leftRotate((a), 29)) +#define leftRotate30(a) (leftRotate((a), 30)) +#define leftRotate31(a) (leftRotate((a), 31)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1(a) (rightRotate((a), 1)) +#define rightRotate2(a) (rightRotate((a), 2)) +#define rightRotate3(a) (rightRotate((a), 3)) +#define rightRotate4(a) (rightRotate((a), 4)) +#define rightRotate5(a) (rightRotate((a), 5)) +#define rightRotate6(a) (rightRotate((a), 6)) +#define rightRotate7(a) (rightRotate((a), 7)) +#define rightRotate8(a) (rightRotate((a), 8)) +#define rightRotate9(a) (rightRotate((a), 9)) +#define rightRotate10(a) (rightRotate((a), 10)) +#define rightRotate11(a) (rightRotate((a), 11)) +#define rightRotate12(a) (rightRotate((a), 12)) +#define rightRotate13(a) (rightRotate((a), 13)) +#define rightRotate14(a) (rightRotate((a), 14)) +#define rightRotate15(a) (rightRotate((a), 15)) +#define rightRotate16(a) (rightRotate((a), 16)) +#define rightRotate17(a) (rightRotate((a), 17)) +#define rightRotate18(a) (rightRotate((a), 18)) +#define rightRotate19(a) (rightRotate((a), 19)) +#define rightRotate20(a) (rightRotate((a), 20)) +#define rightRotate21(a) (rightRotate((a), 21)) +#define rightRotate22(a) (rightRotate((a), 22)) +#define rightRotate23(a) (rightRotate((a), 23)) +#define rightRotate24(a) (rightRotate((a), 24)) +#define rightRotate25(a) (rightRotate((a), 25)) +#define rightRotate26(a) (rightRotate((a), 26)) +#define rightRotate27(a) (rightRotate((a), 27)) +#define rightRotate28(a) (rightRotate((a), 28)) +#define rightRotate29(a) (rightRotate((a), 29)) +#define rightRotate30(a) (rightRotate((a), 30)) +#define rightRotate31(a) (rightRotate((a), 31)) + +#else /* LW_CRYPTO_ROTATE32_COMPOSED */ + +/* Composed rotation macros where 1 and 8 are fast, but others are slow */ + +/* Left rotate by 1 */ +#define leftRotate1(a) (leftRotate((a), 1)) + +/* Left rotate by 2 */ +#define leftRotate2(a) (leftRotate(leftRotate((a), 1), 1)) + +/* Left rotate by 3 */ +#define leftRotate3(a) (leftRotate(leftRotate(leftRotate((a), 1), 1), 1)) + +/* Left rotate by 4 */ +#define leftRotate4(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 1), 1), 1), 1)) + +/* Left rotate by 5: Rotate left by 8, then right by 3 */ +#define leftRotate5(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 8), 1), 1), 1)) + +/* Left rotate by 6: Rotate left by 8, then right by 2 */ +#define leftRotate6(a) (rightRotate(rightRotate(leftRotate((a), 8), 1), 1)) + +/* Left rotate by 7: Rotate left by 8, then right by 1 */ +#define leftRotate7(a) (rightRotate(leftRotate((a), 8), 1)) + +/* Left rotate by 8 */ +#define leftRotate8(a) (leftRotate((a), 8)) + +/* Left rotate by 9: Rotate left by 8, then left by 1 */ +#define leftRotate9(a) (leftRotate(leftRotate((a), 8), 1)) + +/* Left rotate by 10: Rotate left by 8, then left by 2 */ +#define leftRotate10(a) (leftRotate(leftRotate(leftRotate((a), 8), 1), 1)) + +/* Left rotate by 11: Rotate left by 8, then left by 3 */ +#define leftRotate11(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 8), 1), 1), 1)) + +/* Left rotate by 12: Rotate left by 16, then right by 4 */ +#define leftRotate12(a) (rightRotate(rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1), 1)) + +/* Left rotate by 13: Rotate left by 16, then right by 3 */ +#define leftRotate13(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1)) + +/* Left rotate by 14: Rotate left by 16, then right by 2 */ +#define leftRotate14(a) (rightRotate(rightRotate(leftRotate((a), 16), 1), 1)) + +/* Left rotate by 15: Rotate left by 16, then right by 1 */ +#define leftRotate15(a) (rightRotate(leftRotate((a), 16), 1)) + +/* Left rotate by 16 */ +#define leftRotate16(a) (leftRotate((a), 16)) + +/* Left rotate by 17: Rotate left by 16, then left by 1 */ +#define leftRotate17(a) (leftRotate(leftRotate((a), 16), 1)) + +/* Left rotate by 18: Rotate left by 16, then left by 2 */ +#define leftRotate18(a) (leftRotate(leftRotate(leftRotate((a), 16), 1), 1)) + +/* Left rotate by 19: Rotate left by 16, then left by 3 */ +#define leftRotate19(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1)) + +/* Left rotate by 20: Rotate left by 16, then left by 4 */ +#define leftRotate20(a) (leftRotate(leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1), 1)) + +/* Left rotate by 21: Rotate left by 24, then right by 3 */ +#define leftRotate21(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 24), 1), 1), 1)) + +/* Left rotate by 22: Rotate left by 24, then right by 2 */ +#define leftRotate22(a) (rightRotate(rightRotate(leftRotate((a), 24), 1), 1)) + +/* Left rotate by 23: Rotate left by 24, then right by 1 */ +#define leftRotate23(a) (rightRotate(leftRotate((a), 24), 1)) + +/* Left rotate by 24 */ +#define leftRotate24(a) (leftRotate((a), 24)) + +/* Left rotate by 25: Rotate left by 24, then left by 1 */ +#define leftRotate25(a) (leftRotate(leftRotate((a), 24), 1)) + +/* Left rotate by 26: Rotate left by 24, then left by 2 */ +#define leftRotate26(a) (leftRotate(leftRotate(leftRotate((a), 24), 1), 1)) + +/* Left rotate by 27: Rotate left by 24, then left by 3 */ +#define leftRotate27(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 24), 1), 1), 1)) + +/* Left rotate by 28: Rotate right by 4 */ +#define leftRotate28(a) (rightRotate(rightRotate(rightRotate(rightRotate((a), 1), 1), 1), 1)) + +/* Left rotate by 29: Rotate right by 3 */ +#define leftRotate29(a) (rightRotate(rightRotate(rightRotate((a), 1), 1), 1)) + +/* Left rotate by 30: Rotate right by 2 */ +#define leftRotate30(a) (rightRotate(rightRotate((a), 1), 1)) + +/* Left rotate by 31: Rotate right by 1 */ +#define leftRotate31(a) (rightRotate((a), 1)) + +/* Define the 32-bit right rotations in terms of left rotations */ +#define rightRotate1(a) (leftRotate31((a))) +#define rightRotate2(a) (leftRotate30((a))) +#define rightRotate3(a) (leftRotate29((a))) +#define rightRotate4(a) (leftRotate28((a))) +#define rightRotate5(a) (leftRotate27((a))) +#define rightRotate6(a) (leftRotate26((a))) +#define rightRotate7(a) (leftRotate25((a))) +#define rightRotate8(a) (leftRotate24((a))) +#define rightRotate9(a) (leftRotate23((a))) +#define rightRotate10(a) (leftRotate22((a))) +#define rightRotate11(a) (leftRotate21((a))) +#define rightRotate12(a) (leftRotate20((a))) +#define rightRotate13(a) (leftRotate19((a))) +#define rightRotate14(a) (leftRotate18((a))) +#define rightRotate15(a) (leftRotate17((a))) +#define rightRotate16(a) (leftRotate16((a))) +#define rightRotate17(a) (leftRotate15((a))) +#define rightRotate18(a) (leftRotate14((a))) +#define rightRotate19(a) (leftRotate13((a))) +#define rightRotate20(a) (leftRotate12((a))) +#define rightRotate21(a) (leftRotate11((a))) +#define rightRotate22(a) (leftRotate10((a))) +#define rightRotate23(a) (leftRotate9((a))) +#define rightRotate24(a) (leftRotate8((a))) +#define rightRotate25(a) (leftRotate7((a))) +#define rightRotate26(a) (leftRotate6((a))) +#define rightRotate27(a) (leftRotate5((a))) +#define rightRotate28(a) (leftRotate4((a))) +#define rightRotate29(a) (leftRotate3((a))) +#define rightRotate30(a) (leftRotate2((a))) +#define rightRotate31(a) (leftRotate1((a))) + +#endif /* LW_CRYPTO_ROTATE32_COMPOSED */ + +/* Rotation macros for 64-bit arguments */ + +/* Generic left rotate */ +#define leftRotate_64(a, bits) \ + (__extension__ ({ \ + uint64_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (64 - (bits))); \ + })) + +/* Generic right rotate */ +#define rightRotate_64(a, bits) \ + (__extension__ ({ \ + uint64_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (64 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_64(a) (leftRotate_64((a), 1)) +#define leftRotate2_64(a) (leftRotate_64((a), 2)) +#define leftRotate3_64(a) (leftRotate_64((a), 3)) +#define leftRotate4_64(a) (leftRotate_64((a), 4)) +#define leftRotate5_64(a) (leftRotate_64((a), 5)) +#define leftRotate6_64(a) (leftRotate_64((a), 6)) +#define leftRotate7_64(a) (leftRotate_64((a), 7)) +#define leftRotate8_64(a) (leftRotate_64((a), 8)) +#define leftRotate9_64(a) (leftRotate_64((a), 9)) +#define leftRotate10_64(a) (leftRotate_64((a), 10)) +#define leftRotate11_64(a) (leftRotate_64((a), 11)) +#define leftRotate12_64(a) (leftRotate_64((a), 12)) +#define leftRotate13_64(a) (leftRotate_64((a), 13)) +#define leftRotate14_64(a) (leftRotate_64((a), 14)) +#define leftRotate15_64(a) (leftRotate_64((a), 15)) +#define leftRotate16_64(a) (leftRotate_64((a), 16)) +#define leftRotate17_64(a) (leftRotate_64((a), 17)) +#define leftRotate18_64(a) (leftRotate_64((a), 18)) +#define leftRotate19_64(a) (leftRotate_64((a), 19)) +#define leftRotate20_64(a) (leftRotate_64((a), 20)) +#define leftRotate21_64(a) (leftRotate_64((a), 21)) +#define leftRotate22_64(a) (leftRotate_64((a), 22)) +#define leftRotate23_64(a) (leftRotate_64((a), 23)) +#define leftRotate24_64(a) (leftRotate_64((a), 24)) +#define leftRotate25_64(a) (leftRotate_64((a), 25)) +#define leftRotate26_64(a) (leftRotate_64((a), 26)) +#define leftRotate27_64(a) (leftRotate_64((a), 27)) +#define leftRotate28_64(a) (leftRotate_64((a), 28)) +#define leftRotate29_64(a) (leftRotate_64((a), 29)) +#define leftRotate30_64(a) (leftRotate_64((a), 30)) +#define leftRotate31_64(a) (leftRotate_64((a), 31)) +#define leftRotate32_64(a) (leftRotate_64((a), 32)) +#define leftRotate33_64(a) (leftRotate_64((a), 33)) +#define leftRotate34_64(a) (leftRotate_64((a), 34)) +#define leftRotate35_64(a) (leftRotate_64((a), 35)) +#define leftRotate36_64(a) (leftRotate_64((a), 36)) +#define leftRotate37_64(a) (leftRotate_64((a), 37)) +#define leftRotate38_64(a) (leftRotate_64((a), 38)) +#define leftRotate39_64(a) (leftRotate_64((a), 39)) +#define leftRotate40_64(a) (leftRotate_64((a), 40)) +#define leftRotate41_64(a) (leftRotate_64((a), 41)) +#define leftRotate42_64(a) (leftRotate_64((a), 42)) +#define leftRotate43_64(a) (leftRotate_64((a), 43)) +#define leftRotate44_64(a) (leftRotate_64((a), 44)) +#define leftRotate45_64(a) (leftRotate_64((a), 45)) +#define leftRotate46_64(a) (leftRotate_64((a), 46)) +#define leftRotate47_64(a) (leftRotate_64((a), 47)) +#define leftRotate48_64(a) (leftRotate_64((a), 48)) +#define leftRotate49_64(a) (leftRotate_64((a), 49)) +#define leftRotate50_64(a) (leftRotate_64((a), 50)) +#define leftRotate51_64(a) (leftRotate_64((a), 51)) +#define leftRotate52_64(a) (leftRotate_64((a), 52)) +#define leftRotate53_64(a) (leftRotate_64((a), 53)) +#define leftRotate54_64(a) (leftRotate_64((a), 54)) +#define leftRotate55_64(a) (leftRotate_64((a), 55)) +#define leftRotate56_64(a) (leftRotate_64((a), 56)) +#define leftRotate57_64(a) (leftRotate_64((a), 57)) +#define leftRotate58_64(a) (leftRotate_64((a), 58)) +#define leftRotate59_64(a) (leftRotate_64((a), 59)) +#define leftRotate60_64(a) (leftRotate_64((a), 60)) +#define leftRotate61_64(a) (leftRotate_64((a), 61)) +#define leftRotate62_64(a) (leftRotate_64((a), 62)) +#define leftRotate63_64(a) (leftRotate_64((a), 63)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_64(a) (rightRotate_64((a), 1)) +#define rightRotate2_64(a) (rightRotate_64((a), 2)) +#define rightRotate3_64(a) (rightRotate_64((a), 3)) +#define rightRotate4_64(a) (rightRotate_64((a), 4)) +#define rightRotate5_64(a) (rightRotate_64((a), 5)) +#define rightRotate6_64(a) (rightRotate_64((a), 6)) +#define rightRotate7_64(a) (rightRotate_64((a), 7)) +#define rightRotate8_64(a) (rightRotate_64((a), 8)) +#define rightRotate9_64(a) (rightRotate_64((a), 9)) +#define rightRotate10_64(a) (rightRotate_64((a), 10)) +#define rightRotate11_64(a) (rightRotate_64((a), 11)) +#define rightRotate12_64(a) (rightRotate_64((a), 12)) +#define rightRotate13_64(a) (rightRotate_64((a), 13)) +#define rightRotate14_64(a) (rightRotate_64((a), 14)) +#define rightRotate15_64(a) (rightRotate_64((a), 15)) +#define rightRotate16_64(a) (rightRotate_64((a), 16)) +#define rightRotate17_64(a) (rightRotate_64((a), 17)) +#define rightRotate18_64(a) (rightRotate_64((a), 18)) +#define rightRotate19_64(a) (rightRotate_64((a), 19)) +#define rightRotate20_64(a) (rightRotate_64((a), 20)) +#define rightRotate21_64(a) (rightRotate_64((a), 21)) +#define rightRotate22_64(a) (rightRotate_64((a), 22)) +#define rightRotate23_64(a) (rightRotate_64((a), 23)) +#define rightRotate24_64(a) (rightRotate_64((a), 24)) +#define rightRotate25_64(a) (rightRotate_64((a), 25)) +#define rightRotate26_64(a) (rightRotate_64((a), 26)) +#define rightRotate27_64(a) (rightRotate_64((a), 27)) +#define rightRotate28_64(a) (rightRotate_64((a), 28)) +#define rightRotate29_64(a) (rightRotate_64((a), 29)) +#define rightRotate30_64(a) (rightRotate_64((a), 30)) +#define rightRotate31_64(a) (rightRotate_64((a), 31)) +#define rightRotate32_64(a) (rightRotate_64((a), 32)) +#define rightRotate33_64(a) (rightRotate_64((a), 33)) +#define rightRotate34_64(a) (rightRotate_64((a), 34)) +#define rightRotate35_64(a) (rightRotate_64((a), 35)) +#define rightRotate36_64(a) (rightRotate_64((a), 36)) +#define rightRotate37_64(a) (rightRotate_64((a), 37)) +#define rightRotate38_64(a) (rightRotate_64((a), 38)) +#define rightRotate39_64(a) (rightRotate_64((a), 39)) +#define rightRotate40_64(a) (rightRotate_64((a), 40)) +#define rightRotate41_64(a) (rightRotate_64((a), 41)) +#define rightRotate42_64(a) (rightRotate_64((a), 42)) +#define rightRotate43_64(a) (rightRotate_64((a), 43)) +#define rightRotate44_64(a) (rightRotate_64((a), 44)) +#define rightRotate45_64(a) (rightRotate_64((a), 45)) +#define rightRotate46_64(a) (rightRotate_64((a), 46)) +#define rightRotate47_64(a) (rightRotate_64((a), 47)) +#define rightRotate48_64(a) (rightRotate_64((a), 48)) +#define rightRotate49_64(a) (rightRotate_64((a), 49)) +#define rightRotate50_64(a) (rightRotate_64((a), 50)) +#define rightRotate51_64(a) (rightRotate_64((a), 51)) +#define rightRotate52_64(a) (rightRotate_64((a), 52)) +#define rightRotate53_64(a) (rightRotate_64((a), 53)) +#define rightRotate54_64(a) (rightRotate_64((a), 54)) +#define rightRotate55_64(a) (rightRotate_64((a), 55)) +#define rightRotate56_64(a) (rightRotate_64((a), 56)) +#define rightRotate57_64(a) (rightRotate_64((a), 57)) +#define rightRotate58_64(a) (rightRotate_64((a), 58)) +#define rightRotate59_64(a) (rightRotate_64((a), 59)) +#define rightRotate60_64(a) (rightRotate_64((a), 60)) +#define rightRotate61_64(a) (rightRotate_64((a), 61)) +#define rightRotate62_64(a) (rightRotate_64((a), 62)) +#define rightRotate63_64(a) (rightRotate_64((a), 63)) + +/* Rotate a 16-bit value left by a number of bits */ +#define leftRotate_16(a, bits) \ + (__extension__ ({ \ + uint16_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (16 - (bits))); \ + })) + +/* Rotate a 16-bit value right by a number of bits */ +#define rightRotate_16(a, bits) \ + (__extension__ ({ \ + uint16_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (16 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_16(a) (leftRotate_16((a), 1)) +#define leftRotate2_16(a) (leftRotate_16((a), 2)) +#define leftRotate3_16(a) (leftRotate_16((a), 3)) +#define leftRotate4_16(a) (leftRotate_16((a), 4)) +#define leftRotate5_16(a) (leftRotate_16((a), 5)) +#define leftRotate6_16(a) (leftRotate_16((a), 6)) +#define leftRotate7_16(a) (leftRotate_16((a), 7)) +#define leftRotate8_16(a) (leftRotate_16((a), 8)) +#define leftRotate9_16(a) (leftRotate_16((a), 9)) +#define leftRotate10_16(a) (leftRotate_16((a), 10)) +#define leftRotate11_16(a) (leftRotate_16((a), 11)) +#define leftRotate12_16(a) (leftRotate_16((a), 12)) +#define leftRotate13_16(a) (leftRotate_16((a), 13)) +#define leftRotate14_16(a) (leftRotate_16((a), 14)) +#define leftRotate15_16(a) (leftRotate_16((a), 15)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_16(a) (rightRotate_16((a), 1)) +#define rightRotate2_16(a) (rightRotate_16((a), 2)) +#define rightRotate3_16(a) (rightRotate_16((a), 3)) +#define rightRotate4_16(a) (rightRotate_16((a), 4)) +#define rightRotate5_16(a) (rightRotate_16((a), 5)) +#define rightRotate6_16(a) (rightRotate_16((a), 6)) +#define rightRotate7_16(a) (rightRotate_16((a), 7)) +#define rightRotate8_16(a) (rightRotate_16((a), 8)) +#define rightRotate9_16(a) (rightRotate_16((a), 9)) +#define rightRotate10_16(a) (rightRotate_16((a), 10)) +#define rightRotate11_16(a) (rightRotate_16((a), 11)) +#define rightRotate12_16(a) (rightRotate_16((a), 12)) +#define rightRotate13_16(a) (rightRotate_16((a), 13)) +#define rightRotate14_16(a) (rightRotate_16((a), 14)) +#define rightRotate15_16(a) (rightRotate_16((a), 15)) + +/* Rotate an 8-bit value left by a number of bits */ +#define leftRotate_8(a, bits) \ + (__extension__ ({ \ + uint8_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (8 - (bits))); \ + })) + +/* Rotate an 8-bit value right by a number of bits */ +#define rightRotate_8(a, bits) \ + (__extension__ ({ \ + uint8_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (8 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_8(a) (leftRotate_8((a), 1)) +#define leftRotate2_8(a) (leftRotate_8((a), 2)) +#define leftRotate3_8(a) (leftRotate_8((a), 3)) +#define leftRotate4_8(a) (leftRotate_8((a), 4)) +#define leftRotate5_8(a) (leftRotate_8((a), 5)) +#define leftRotate6_8(a) (leftRotate_8((a), 6)) +#define leftRotate7_8(a) (leftRotate_8((a), 7)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_8(a) (rightRotate_8((a), 1)) +#define rightRotate2_8(a) (rightRotate_8((a), 2)) +#define rightRotate3_8(a) (rightRotate_8((a), 3)) +#define rightRotate4_8(a) (rightRotate_8((a), 4)) +#define rightRotate5_8(a) (rightRotate_8((a), 5)) +#define rightRotate6_8(a) (rightRotate_8((a), 6)) +#define rightRotate7_8(a) (rightRotate_8((a), 7)) + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/romulus.c b/romulus/Implementations/crypto_aead/romulusm1+/rhys/romulus.c new file mode 100644 index 0000000..bb19cc5 --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/romulus.c @@ -0,0 +1,1974 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "romulus.h" +#include "internal-skinny128.h" +#include "internal-util.h" +#include + +aead_cipher_t const romulus_n1_cipher = { + "Romulus-N1", + ROMULUS_KEY_SIZE, + ROMULUS1_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_n1_aead_encrypt, + romulus_n1_aead_decrypt +}; + +aead_cipher_t const romulus_n2_cipher = { + "Romulus-N2", + ROMULUS_KEY_SIZE, + ROMULUS2_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_n2_aead_encrypt, + romulus_n2_aead_decrypt +}; + +aead_cipher_t const romulus_n3_cipher = { + "Romulus-N3", + ROMULUS_KEY_SIZE, + ROMULUS3_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_n3_aead_encrypt, + romulus_n3_aead_decrypt +}; + +aead_cipher_t const romulus_m1_cipher = { + "Romulus-M1", + ROMULUS_KEY_SIZE, + ROMULUS1_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_m1_aead_encrypt, + romulus_m1_aead_decrypt +}; + +aead_cipher_t const romulus_m2_cipher = { + "Romulus-M2", + ROMULUS_KEY_SIZE, + ROMULUS2_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_m2_aead_encrypt, + romulus_m2_aead_decrypt +}; + +aead_cipher_t const romulus_m3_cipher = { + "Romulus-M3", + ROMULUS_KEY_SIZE, + ROMULUS3_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_m3_aead_encrypt, + romulus_m3_aead_decrypt +}; + +/** + * \brief Limit on the number of bytes of message or associated data (128Mb). + * + * Romulus-N1 and Romulus-M1 use a 56-bit block counter which allows for + * payloads well into the petabyte range. It is unlikely that an embedded + * device will have that much memory to store a contiguous packet! + * + * Romulus-N2 and Romulus-M2 use a 48-bit block counter but the upper + * 24 bits are difficult to modify in the key schedule. So we only + * update the low 24 bits and leave the high 24 bits fixed. + * + * Romulus-N3 and Romulus-M3 use a 24-bit block counter. + * + * For all algorithms, we limit the block counter to 2^23 so that the block + * counter can never exceed 2^24 - 1. + */ +#define ROMULUS_DATA_LIMIT \ + ((unsigned long long)((1ULL << 23) * SKINNY_128_BLOCK_SIZE)) + +/** + * \brief Initializes the key schedule for Romulus-N1 or Romulus-M1. + * + * \param ks Points to the key schedule to initialize. + * \param k Points to the 16 bytes of the key. + * \param npub Points to the 16 bytes of the nonce. May be NULL + * if the nonce will be updated on the fly. + */ +static void romulus1_init + (skinny_128_384_key_schedule_t *ks, + const unsigned char *k, const unsigned char *npub) +{ + unsigned char TK[48]; + TK[0] = 0x01; /* Initialize the 56-bit LFSR counter */ + memset(TK + 1, 0, 15); + if (npub) + memcpy(TK + 16, npub, 16); + else + memset(TK + 16, 0, 16); + memcpy(TK + 32, k, 16); + skinny_128_384_init(ks, TK); +} + +/** + * \brief Initializes the key schedule for Romulus-N2 or Romulus-M2. + * + * \param ks Points to the key schedule to initialize. + * \param k Points to the 16 bytes of the key. + * \param npub Points to the 12 bytes of the nonce. May be NULL + * if the nonce will be updated on the fly. + */ +static void romulus2_init + (skinny_128_384_key_schedule_t *ks, + const unsigned char *k, const unsigned char *npub) +{ + unsigned char TK[48]; + TK[0] = 0x01; /* Initialize the low 24 bits of the LFSR counter */ + if (npub) { + TK[1] = TK[2] = TK[3] = 0; + memcpy(TK + 4, npub, 12); + } else { + memset(TK + 1, 0, 15); + } + memcpy(TK + 16, k, 16); + TK[32] = 0x01; /* Initialize the high 24 bits of the LFSR counter */ + memset(TK + 33, 0, 15); + skinny_128_384_init(ks, TK); +} + +/** + * \brief Initializes the key schedule for Romulus-N3 or Romulus-M3. + * + * \param ks Points to the key schedule to initialize. + * \param k Points to the 16 bytes of the key. + * \param npub Points to the 12 bytes of the nonce. May be NULL + * if the nonce will be updated on the fly. + */ +static void romulus3_init + (skinny_128_256_key_schedule_t *ks, + const unsigned char *k, const unsigned char *npub) +{ + unsigned char TK[32]; + TK[0] = 0x01; /* Initialize the 24-bit LFSR counter */ + if (npub) { + TK[1] = TK[2] = TK[3] = 0; + memcpy(TK + 4, npub, 12); + } else { + memset(TK + 1, 0, 15); + } + memcpy(TK + 16, k, 16); + skinny_128_256_init(ks, TK); +} + +/** + * \brief Sets the domain separation value for Romulus-N1 and M1. + * + * \param ks The key schedule to set the domain separation value into. + * \param domain The domain separation value. + */ +#define romulus1_set_domain(ks, domain) ((ks)->TK1[7] = (domain)) + +/** + * \brief Sets the domain separation value for Romulus-N2 and M2. + * + * \param ks The key schedule to set the domain separation value into. + * \param domain The domain separation value. + */ +#define romulus2_set_domain(ks, domain) ((ks)->TK1[3] = (domain)) + +/** + * \brief Sets the domain separation value for Romulus-N3 and M3. + * + * \param ks The key schedule to set the domain separation value into. + * \param domain The domain separation value. + */ +#define romulus3_set_domain(ks, domain) ((ks)->TK1[3] = (domain)) + +/** + * \brief Updates the 56-bit LFSR block counter for Romulus-N1 and M1. + * + * \param TK1 Points to the TK1 part of the key schedule containing the LFSR. + */ +STATIC_INLINE void romulus1_update_counter(uint8_t TK1[16]) +{ + uint8_t mask = (uint8_t)(((int8_t)(TK1[6])) >> 7); + TK1[6] = (TK1[6] << 1) | (TK1[5] >> 7); + TK1[5] = (TK1[5] << 1) | (TK1[4] >> 7); + TK1[4] = (TK1[4] << 1) | (TK1[3] >> 7); + TK1[3] = (TK1[3] << 1) | (TK1[2] >> 7); + TK1[2] = (TK1[2] << 1) | (TK1[1] >> 7); + TK1[1] = (TK1[1] << 1) | (TK1[0] >> 7); + TK1[0] = (TK1[0] << 1) ^ (mask & 0x95); +} + +/** + * \brief Updates the 24-bit LFSR block counter for Romulus-N2 or M2. + * + * \param TK1 Points to the TK1 part of the key schedule containing the LFSR. + * + * For Romulus-N2 and Romulus-M2 this will only update the low 24 bits of + * the 48-bit LFSR. The high 24 bits are fixed due to ROMULUS_DATA_LIMIT. + */ +STATIC_INLINE void romulus2_update_counter(uint8_t TK1[16]) +{ + uint8_t mask = (uint8_t)(((int8_t)(TK1[2])) >> 7); + TK1[2] = (TK1[2] << 1) | (TK1[1] >> 7); + TK1[1] = (TK1[1] << 1) | (TK1[0] >> 7); + TK1[0] = (TK1[0] << 1) ^ (mask & 0x1B); +} + +/** + * \brief Updates the 24-bit LFSR block counter for Romulus-N3 or M3. + * + * \param TK1 Points to the TK1 part of the key schedule containing the LFSR. + */ +#define romulus3_update_counter(TK1) romulus2_update_counter((TK1)) + +/** + * \brief Process the asssociated data for Romulus-N1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void romulus_n1_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char temp; + + /* Handle the special case of no associated data */ + if (adlen == 0) { + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x1A); + skinny_128_384_encrypt_tk2(ks, S, S, npub); + return; + } + + /* Process all double blocks except the last */ + romulus1_set_domain(ks, 0x08); + while (adlen > 32) { + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + ad += 32; + adlen -= 32; + } + + /* Pad and process the left-over blocks */ + romulus1_update_counter(ks->TK1); + temp = (unsigned)adlen; + if (temp == 32) { + /* Left-over complete double block */ + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x18); + } else if (temp > 16) { + /* Left-over partial double block */ + unsigned char pad[16]; + temp -= 16; + lw_xor_block(S, ad, 16); + memcpy(pad, ad + 16, temp); + memset(pad + temp, 0, 15 - temp); + pad[15] = temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x1A); + } else if (temp == 16) { + /* Left-over complete single block */ + lw_xor_block(S, ad, temp); + romulus1_set_domain(ks, 0x18); + } else { + /* Left-over partial single block */ + lw_xor_block(S, ad, temp); + S[15] ^= temp; + romulus1_set_domain(ks, 0x1A); + } + skinny_128_384_encrypt_tk2(ks, S, S, npub); +} + +/** + * \brief Process the asssociated data for Romulus-N2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void romulus_n2_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char temp; + + /* Handle the special case of no associated data */ + if (adlen == 0) { + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x5A); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all double blocks except the last */ + romulus2_set_domain(ks, 0x48); + while (adlen > 28) { + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Pad and process the left-over blocks */ + romulus2_update_counter(ks->TK1); + temp = (unsigned)adlen; + if (temp == 28) { + /* Left-over complete double block */ + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x58); + } else if (temp > 16) { + /* Left-over partial double block */ + temp -= 16; + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp); + ks->TK1[15] = temp; + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x5A); + } else if (temp == 16) { + /* Left-over complete single block */ + lw_xor_block(S, ad, temp); + romulus2_set_domain(ks, 0x58); + } else { + /* Left-over partial single block */ + lw_xor_block(S, ad, temp); + S[15] ^= temp; + romulus2_set_domain(ks, 0x5A); + } + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Process the asssociated data for Romulus-N3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void romulus_n3_process_ad + (skinny_128_256_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char temp; + + /* Handle the special case of no associated data */ + if (adlen == 0) { + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x9A); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_256_encrypt(ks, S, S); + return; + } + + /* Process all double blocks except the last */ + romulus3_set_domain(ks, 0x88); + while (adlen > 28) { + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Pad and process the left-over blocks */ + romulus3_update_counter(ks->TK1); + temp = (unsigned)adlen; + if (temp == 28) { + /* Left-over complete double block */ + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x98); + } else if (temp > 16) { + /* Left-over partial double block */ + temp -= 16; + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp); + ks->TK1[15] = temp; + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x9A); + } else if (temp == 16) { + /* Left-over complete single block */ + lw_xor_block(S, ad, temp); + romulus3_set_domain(ks, 0x98); + } else { + /* Left-over partial single block */ + lw_xor_block(S, ad, temp); + S[15] ^= temp; + romulus3_set_domain(ks, 0x9A); + } + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Determine the domain separation value to use on the last + * block of the associated data processing. + * + * \param adlen Length of the associated data in bytes. + * \param mlen Length of the message in bytes. + * \param t Size of the second half of a double block; 12 or 16. + * + * \return The domain separation bits to use to finalize the last block. + */ +static uint8_t romulus_m_final_ad_domain + (unsigned long long adlen, unsigned long long mlen, unsigned t) +{ + uint8_t domain = 0; + unsigned split = 16U; + unsigned leftover; + + /* Determine which domain bits we need based on the length of the ad */ + if (adlen == 0) { + /* No associated data, so only 1 block with padding */ + domain ^= 0x02; + split = t; + } else { + /* Even or odd associated data length? */ + leftover = (unsigned)(adlen % (16U + t)); + if (leftover == 0) { + /* Even with a full double block at the end */ + domain ^= 0x08; + } else if (leftover < split) { + /* Odd with a partial single block at the end */ + domain ^= 0x02; + split = t; + } else if (leftover > split) { + /* Even with a partial double block at the end */ + domain ^= 0x0A; + } else { + /* Odd with a full single block at the end */ + split = t; + } + } + + /* Determine which domain bits we need based on the length of the message */ + if (mlen == 0) { + /* No message, so only 1 block with padding */ + domain ^= 0x01; + } else { + /* Even or odd message length? */ + leftover = (unsigned)(mlen % (16U + t)); + if (leftover == 0) { + /* Even with a full double block at the end */ + domain ^= 0x04; + } else if (leftover < split) { + /* Odd with a partial single block at the end */ + domain ^= 0x01; + } else if (leftover > split) { + /* Even with a partial double block at the end */ + domain ^= 0x05; + } + } + return domain; +} + +/** + * \brief Process the asssociated data for Romulus-M1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + * \param m Points to the message plaintext. + * \param mlen Length of the message plaintext. + */ +static void romulus_m1_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *m, unsigned long long mlen) +{ + unsigned char pad[16]; + uint8_t final_domain = 0x30; + unsigned temp; + + /* Determine the domain separator to use on the final block */ + final_domain ^= romulus_m_final_ad_domain(adlen, mlen, 16); + + /* Process all associated data double blocks except the last */ + romulus1_set_domain(ks, 0x28); + while (adlen > 32) { + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + ad += 32; + adlen -= 32; + } + + /* Process the last associated data double block */ + temp = (unsigned)adlen; + if (temp == 32) { + /* Last associated data double block is full */ + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + } else if (temp > 16) { + /* Last associated data double block is partial */ + temp -= 16; + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(pad, ad + 16, temp); + memset(pad + temp, 0, sizeof(pad) - temp - 1); + pad[sizeof(pad) - 1] = (unsigned char)temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + romulus1_update_counter(ks->TK1); + } else { + /* Last associated data block is single. Needs to be combined + * with the first block of the message payload */ + romulus1_set_domain(ks, 0x2C); + romulus1_update_counter(ks->TK1); + if (temp == 16) { + lw_xor_block(S, ad, 16); + } else { + lw_xor_block(S, ad, temp); + S[15] ^= (unsigned char)temp; + } + if (mlen > 16) { + skinny_128_384_encrypt_tk2(ks, S, S, m); + romulus1_update_counter(ks->TK1); + m += 16; + mlen -= 16; + } else if (mlen == 16) { + skinny_128_384_encrypt_tk2(ks, S, S, m); + m += 16; + mlen -= 16; + } else { + temp = (unsigned)mlen; + memcpy(pad, m, temp); + memset(pad + temp, 0, sizeof(pad) - temp - 1); + pad[sizeof(pad) - 1] = (unsigned char)temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + mlen = 0; + } + } + + /* Process all message double blocks except the last */ + romulus1_set_domain(ks, 0x2C); + while (mlen > 32) { + romulus1_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + skinny_128_384_encrypt_tk2(ks, S, S, m + 16); + romulus1_update_counter(ks->TK1); + m += 32; + mlen -= 32; + } + + /* Process the last message double block */ + temp = (unsigned)mlen; + if (temp == 32) { + /* Last message double block is full */ + romulus1_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + skinny_128_384_encrypt_tk2(ks, S, S, m + 16); + } else if (temp > 16) { + /* Last message double block is partial */ + temp -= 16; + romulus1_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(pad, m + 16, temp); + memset(pad + temp, 0, sizeof(pad) - temp - 1); + pad[sizeof(pad) - 1] = (unsigned char)temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + } else if (temp == 16) { + /* Last message single block is full */ + lw_xor_block(S, m, 16); + } else if (temp > 0) { + /* Last message single block is partial */ + lw_xor_block(S, m, temp); + S[15] ^= (unsigned char)temp; + } + + /* Process the last partial block */ + romulus1_set_domain(ks, final_domain); + romulus1_update_counter(ks->TK1); + skinny_128_384_encrypt_tk2(ks, S, S, npub); +} + +/** + * \brief Process the asssociated data for Romulus-M2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + * \param m Points to the message plaintext. + * \param mlen Length of the message plaintext. + */ +static void romulus_m2_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *m, unsigned long long mlen) +{ + uint8_t final_domain = 0x70; + unsigned temp; + + /* Determine the domain separator to use on the final block */ + final_domain ^= romulus_m_final_ad_domain(adlen, mlen, 12); + + /* Process all associated data double blocks except the last */ + romulus2_set_domain(ks, 0x68); + while (adlen > 28) { + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Process the last associated data double block */ + temp = (unsigned)adlen; + if (temp == 28) { + /* Last associated data double block is full */ + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + } else if (temp > 16) { + /* Last associated data double block is partial */ + temp -= 16; + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + } else { + /* Last associated data block is single. Needs to be combined + * with the first block of the message payload */ + romulus2_set_domain(ks, 0x6C); + romulus2_update_counter(ks->TK1); + if (temp == 16) { + lw_xor_block(S, ad, 16); + } else { + lw_xor_block(S, ad, temp); + S[15] ^= (unsigned char)temp; + } + if (mlen > 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + m += 12; + mlen -= 12; + } else if (mlen == 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_384_encrypt(ks, S, S); + m += 12; + mlen -= 12; + } else { + temp = (unsigned)mlen; + memcpy(ks->TK1 + 4, m, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_384_encrypt(ks, S, S); + mlen = 0; + } + } + + /* Process all message double blocks except the last */ + romulus2_set_domain(ks, 0x6C); + while (mlen > 28) { + romulus2_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + m += 28; + mlen -= 28; + } + + /* Process the last message double block */ + temp = (unsigned)mlen; + if (temp == 28) { + /* Last message double block is full */ + romulus2_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_384_encrypt(ks, S, S); + } else if (temp > 16) { + /* Last message double block is partial */ + temp -= 16; + romulus2_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_384_encrypt(ks, S, S); + } else if (temp == 16) { + /* Last message single block is full */ + lw_xor_block(S, m, 16); + } else if (temp > 0) { + /* Last message single block is partial */ + lw_xor_block(S, m, temp); + S[15] ^= (unsigned char)temp; + } + + /* Process the last partial block */ + romulus2_set_domain(ks, final_domain); + romulus2_update_counter(ks->TK1); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Process the asssociated data for Romulus-M3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + * \param m Points to the message plaintext. + * \param mlen Length of the message plaintext. + */ +static void romulus_m3_process_ad + (skinny_128_256_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *m, unsigned long long mlen) +{ + uint8_t final_domain = 0xB0; + unsigned temp; + + /* Determine the domain separator to use on the final block */ + final_domain ^= romulus_m_final_ad_domain(adlen, mlen, 12); + + /* Process all associated data double blocks except the last */ + romulus3_set_domain(ks, 0xA8); + while (adlen > 28) { + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Process the last associated data double block */ + temp = (unsigned)adlen; + if (temp == 28) { + /* Last associated data double block is full */ + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + } else if (temp > 16) { + /* Last associated data double block is partial */ + temp -= 16; + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + } else { + /* Last associated data block is single. Needs to be combined + * with the first block of the message payload */ + romulus3_set_domain(ks, 0xAC); + romulus3_update_counter(ks->TK1); + if (temp == 16) { + lw_xor_block(S, ad, 16); + } else { + lw_xor_block(S, ad, temp); + S[15] ^= (unsigned char)temp; + } + if (mlen > 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + m += 12; + mlen -= 12; + } else if (mlen == 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_256_encrypt(ks, S, S); + m += 12; + mlen -= 12; + } else { + temp = (unsigned)mlen; + memcpy(ks->TK1 + 4, m, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_256_encrypt(ks, S, S); + mlen = 0; + } + } + + /* Process all message double blocks except the last */ + romulus3_set_domain(ks, 0xAC); + while (mlen > 28) { + romulus3_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + m += 28; + mlen -= 28; + } + + /* Process the last message double block */ + temp = (unsigned)mlen; + if (temp == 28) { + /* Last message double block is full */ + romulus3_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_256_encrypt(ks, S, S); + } else if (temp > 16) { + /* Last message double block is partial */ + temp -= 16; + romulus3_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_256_encrypt(ks, S, S); + } else if (temp == 16) { + /* Last message single block is full */ + lw_xor_block(S, m, 16); + } else if (temp > 0) { + /* Last message single block is partial */ + lw_xor_block(S, m, temp); + S[15] ^= (unsigned char)temp; + } + + /* Process the last partial block */ + romulus3_set_domain(ks, final_domain); + romulus3_update_counter(ks->TK1); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Applies the Romulus rho function. + * + * \param S The rolling Romulus state. + * \param C Ciphertext message output block. + * \param M Plaintext message input block. + */ +STATIC_INLINE void romulus_rho + (unsigned char S[16], unsigned char C[16], const unsigned char M[16]) +{ + unsigned index; + for (index = 0; index < 16; ++index) { + unsigned char s = S[index]; + unsigned char m = M[index]; + S[index] ^= m; + C[index] = m ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + } +} + +/** + * \brief Applies the inverse of the Romulus rho function. + * + * \param S The rolling Romulus state. + * \param M Plaintext message output block. + * \param C Ciphertext message input block. + */ +STATIC_INLINE void romulus_rho_inverse + (unsigned char S[16], unsigned char M[16], const unsigned char C[16]) +{ + unsigned index; + for (index = 0; index < 16; ++index) { + unsigned char s = S[index]; + unsigned char m = C[index] ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + S[index] ^= m; + M[index] = m; + } +} + +/** + * \brief Applies the Romulus rho function to a short block. + * + * \param S The rolling Romulus state. + * \param C Ciphertext message output block. + * \param M Plaintext message input block. + * \param len Length of the short block, must be less than 16. + */ +STATIC_INLINE void romulus_rho_short + (unsigned char S[16], unsigned char C[16], + const unsigned char M[16], unsigned len) +{ + unsigned index; + for (index = 0; index < len; ++index) { + unsigned char s = S[index]; + unsigned char m = M[index]; + S[index] ^= m; + C[index] = m ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + } + S[15] ^= (unsigned char)len; /* Padding */ +} + +/** + * \brief Applies the inverse of the Romulus rho function to a short block. + * + * \param S The rolling Romulus state. + * \param M Plaintext message output block. + * \param C Ciphertext message input block. + * \param len Length of the short block, must be less than 16. + */ +STATIC_INLINE void romulus_rho_inverse_short + (unsigned char S[16], unsigned char M[16], + const unsigned char C[16], unsigned len) +{ + unsigned index; + for (index = 0; index < len; ++index) { + unsigned char s = S[index]; + unsigned char m = C[index] ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + S[index] ^= m; + M[index] = m; + } + S[15] ^= (unsigned char)len; /* Padding */ +} + +/** + * \brief Encrypts a plaintext message with Romulus-N1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n1_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no plaintext */ + if (mlen == 0) { + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x15); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus1_set_domain(ks, 0x04); + while (mlen > 16) { + romulus_rho(S, c, m); + romulus1_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus1_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_short(S, c, m, temp); + romulus1_set_domain(ks, 0x15); + } else { + romulus_rho(S, c, m); + romulus1_set_domain(ks, 0x14); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-N1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n1_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no ciphertext */ + if (mlen == 0) { + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x15); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus1_set_domain(ks, 0x04); + while (mlen > 16) { + romulus_rho_inverse(S, m, c); + romulus1_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus1_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_inverse_short(S, m, c, temp); + romulus1_set_domain(ks, 0x15); + } else { + romulus_rho_inverse(S, m, c); + romulus1_set_domain(ks, 0x14); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Encrypts a plaintext message with Romulus-N2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n2_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no plaintext */ + if (mlen == 0) { + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x55); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus2_set_domain(ks, 0x44); + while (mlen > 16) { + romulus_rho(S, c, m); + romulus2_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus2_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_short(S, c, m, temp); + romulus2_set_domain(ks, 0x55); + } else { + romulus_rho(S, c, m); + romulus2_set_domain(ks, 0x54); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-N2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n2_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no ciphertext */ + if (mlen == 0) { + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x55); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus2_set_domain(ks, 0x44); + while (mlen > 16) { + romulus_rho_inverse(S, m, c); + romulus2_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus2_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_inverse_short(S, m, c, temp); + romulus2_set_domain(ks, 0x55); + } else { + romulus_rho_inverse(S, m, c); + romulus2_set_domain(ks, 0x54); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Encrypts a plaintext message with Romulus-N3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n3_encrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no plaintext */ + if (mlen == 0) { + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x95); + skinny_128_256_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus3_set_domain(ks, 0x84); + while (mlen > 16) { + romulus_rho(S, c, m); + romulus3_update_counter(ks->TK1); + skinny_128_256_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus3_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_short(S, c, m, temp); + romulus3_set_domain(ks, 0x95); + } else { + romulus_rho(S, c, m); + romulus3_set_domain(ks, 0x94); + } + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-N3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n3_decrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no ciphertext */ + if (mlen == 0) { + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x95); + skinny_128_256_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus3_set_domain(ks, 0x84); + while (mlen > 16) { + romulus_rho_inverse(S, m, c); + romulus3_update_counter(ks->TK1); + skinny_128_256_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus3_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_inverse_short(S, m, c, temp); + romulus3_set_domain(ks, 0x95); + } else { + romulus_rho_inverse(S, m, c); + romulus3_set_domain(ks, 0x94); + } + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Encrypts a plaintext message with Romulus-M1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m1_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus1_set_domain(ks, 0x24); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho(S, c, m); + romulus1_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_short(S, c, m, (unsigned)mlen); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-M1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m1_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus1_set_domain(ks, 0x24); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse(S, m, c); + romulus1_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse_short(S, m, c, (unsigned)mlen); +} + +/** + * \brief Encrypts a plaintext message with Romulus-M2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m2_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus2_set_domain(ks, 0x64); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho(S, c, m); + romulus2_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_short(S, c, m, (unsigned)mlen); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-M2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m2_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus2_set_domain(ks, 0x64); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse(S, m, c); + romulus2_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse_short(S, m, c, (unsigned)mlen); +} + +/** + * \brief Encrypts a plaintext message with Romulus-M3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m3_encrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus3_set_domain(ks, 0xA4); + while (mlen > 16) { + skinny_128_256_encrypt(ks, S, S); + romulus_rho(S, c, m); + romulus3_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_256_encrypt(ks, S, S); + romulus_rho_short(S, c, m, (unsigned)mlen); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-M3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m3_decrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus3_set_domain(ks, 0xA4); + while (mlen > 16) { + skinny_128_256_encrypt(ks, S, S); + romulus_rho_inverse(S, m, c); + romulus3_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_256_encrypt(ks, S, S); + romulus_rho_inverse_short(S, m, c, (unsigned)mlen); +} + +/** + * \brief Generates the authentication tag from the rolling Romulus state. + * + * \param T Buffer to receive the generated tag; can be the same as S. + * \param S The rolling Romulus state. + */ +STATIC_INLINE void romulus_generate_tag + (unsigned char T[16], const unsigned char S[16]) +{ + unsigned index; + for (index = 0; index < 16; ++index) { + unsigned char s = S[index]; + T[index] = (s >> 1) ^ (s & 0x80) ^ (s << 7); + } +} + +int romulus_n1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n1_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Encrypts the plaintext to produce the ciphertext */ + romulus_n1_encrypt(&ks, S, c, m, mlen); + + /* Generate the authentication tag */ + romulus_generate_tag(c + mlen, S); + return 0; +} + +int romulus_n1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n1_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext */ + clen -= ROMULUS_TAG_SIZE; + romulus_n1_decrypt(&ks, S, m, c, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_n2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n2_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Encrypts the plaintext to produce the ciphertext */ + romulus_n2_encrypt(&ks, S, c, m, mlen); + + /* Generate the authentication tag */ + romulus_generate_tag(c + mlen, S); + return 0; +} + +int romulus_n2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n2_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext */ + clen -= ROMULUS_TAG_SIZE; + romulus_n2_decrypt(&ks, S, m, c, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_n3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n3_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Encrypts the plaintext to produce the ciphertext */ + romulus_n3_encrypt(&ks, S, c, m, mlen); + + /* Generate the authentication tag */ + romulus_generate_tag(c + mlen, S); + return 0; +} + +int romulus_n3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n3_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext */ + clen -= ROMULUS_TAG_SIZE; + romulus_n3_decrypt(&ks, S, m, c, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_m1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data and the plaintext message */ + memset(S, 0, sizeof(S)); + romulus_m1_process_ad(&ks, S, npub, ad, adlen, m, mlen); + + /* Generate the authentication tag, which is also the initialization + * vector for the encryption portion of the packet processing */ + romulus_generate_tag(S, S); + memcpy(c + mlen, S, ROMULUS_TAG_SIZE); + + /* Re-initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Encrypt the plaintext to produce the ciphertext */ + romulus_m1_encrypt(&ks, S, c, m, mlen); + return 0; +} + +int romulus_m1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext, using the + * authentication tag as the initialization vector for decryption */ + clen -= ROMULUS_TAG_SIZE; + memcpy(S, c + clen, ROMULUS_TAG_SIZE); + romulus_m1_decrypt(&ks, S, m, c, clen); + + /* Re-initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_m1_process_ad(&ks, S, npub, ad, adlen, m, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_m2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data and the plaintext message */ + memset(S, 0, sizeof(S)); + romulus_m2_process_ad(&ks, S, npub, ad, adlen, m, mlen); + + /* Generate the authentication tag, which is also the initialization + * vector for the encryption portion of the packet processing */ + romulus_generate_tag(S, S); + memcpy(c + mlen, S, ROMULUS_TAG_SIZE); + + /* Re-initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Encrypt the plaintext to produce the ciphertext */ + romulus_m2_encrypt(&ks, S, c, m, mlen); + return 0; +} + +int romulus_m2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext, using the + * authentication tag as the initialization vector for decryption */ + clen -= ROMULUS_TAG_SIZE; + memcpy(S, c + clen, ROMULUS_TAG_SIZE); + romulus_m2_decrypt(&ks, S, m, c, clen); + + /* Re-initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_m2_process_ad(&ks, S, npub, ad, adlen, m, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_m3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data and the plaintext message */ + memset(S, 0, sizeof(S)); + romulus_m3_process_ad(&ks, S, npub, ad, adlen, m, mlen); + + /* Generate the authentication tag, which is also the initialization + * vector for the encryption portion of the packet processing */ + romulus_generate_tag(S, S); + memcpy(c + mlen, S, ROMULUS_TAG_SIZE); + + /* Re-initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Encrypt the plaintext to produce the ciphertext */ + romulus_m3_encrypt(&ks, S, c, m, mlen); + return 0; +} + +int romulus_m3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext, using the + * authentication tag as the initialization vector for decryption */ + clen -= ROMULUS_TAG_SIZE; + memcpy(S, c + clen, ROMULUS_TAG_SIZE); + romulus_m3_decrypt(&ks, S, m, c, clen); + + /* Re-initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_m3_process_ad(&ks, S, npub, ad, adlen, m, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} diff --git a/romulus/Implementations/crypto_aead/romulusm1+/rhys/romulus.h b/romulus/Implementations/crypto_aead/romulusm1+/rhys/romulus.h new file mode 100644 index 0000000..e6da29d --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusm1+/rhys/romulus.h @@ -0,0 +1,476 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LWCRYPTO_ROMULUS_H +#define LWCRYPTO_ROMULUS_H + +#include "aead-common.h" + +/** + * \file romulus.h + * \brief Romulus authenticated encryption algorithm family. + * + * Romulus is a family of authenticated encryption algorithms that + * are built around the SKINNY-128 tweakable block cipher. There + * are six members in the family: + * + * \li Romulus-N1 has a 128-bit key, a 128-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. This is the + * primary member of the family. + * \li Romulus-N2 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li Romulus-N3 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-256 tweakable block cipher. + * \li Romulus-M1 has a 128-bit key, a 128-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li Romulus-M2 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li Romulus-M3 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-256 tweakable block cipher. + * + * The Romulus-M variants are resistant to nonce reuse as long as the + * combination of the associated data and plaintext is unique. If the + * same associated data and plaintext are reused under the same nonce, + * then the scheme will leak that the same plaintext has been sent for a + * second time but will not reveal the plaintext itself. + * + * References: https://romulusae.github.io/romulus/ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Size of the key for all Romulus family members. + */ +#define ROMULUS_KEY_SIZE 16 + +/** + * \brief Size of the authentication tag for all Romulus family members. + */ +#define ROMULUS_TAG_SIZE 16 + +/** + * \brief Size of the nonce for Romulus-N1 and Romulus-M1. + */ +#define ROMULUS1_NONCE_SIZE 16 + +/** + * \brief Size of the nonce for Romulus-N2 and Romulus-M2. + */ +#define ROMULUS2_NONCE_SIZE 12 + +/** + * \brief Size of the nonce for Romulus-N3 and Romulus-M3. + */ +#define ROMULUS3_NONCE_SIZE 12 + +/** + * \brief Meta-information block for the Romulus-N1 cipher. + */ +extern aead_cipher_t const romulus_n1_cipher; + +/** + * \brief Meta-information block for the Romulus-N2 cipher. + */ +extern aead_cipher_t const romulus_n2_cipher; + +/** + * \brief Meta-information block for the Romulus-N3 cipher. + */ +extern aead_cipher_t const romulus_n3_cipher; + +/** + * \brief Meta-information block for the Romulus-M1 cipher. + */ +extern aead_cipher_t const romulus_m1_cipher; + +/** + * \brief Meta-information block for the Romulus-M2 cipher. + */ +extern aead_cipher_t const romulus_m2_cipher; + +/** + * \brief Meta-information block for the Romulus-M3 cipher. + */ +extern aead_cipher_t const romulus_m3_cipher; + +/** + * \brief Encrypts and authenticates a packet with Romulus-N1. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_n1_aead_decrypt() + */ +int romulus_n1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-N1. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_n1_aead_encrypt() + */ +int romulus_n1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-N2. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_n2_aead_decrypt() + */ +int romulus_n2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-N2. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_n2_aead_encrypt() + */ +int romulus_n2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-N3. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_n3_aead_decrypt() + */ +int romulus_n3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-N3. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_n3_aead_encrypt() + */ +int romulus_n3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-M1. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_m1_aead_decrypt() + */ +int romulus_m1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-M1. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_m1_aead_encrypt() + */ +int romulus_m1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-M2. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_m2_aead_decrypt() + */ +int romulus_m2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-M2. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_m2_aead_encrypt() + */ +int romulus_m2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-M3. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_m3_aead_decrypt() + */ +int romulus_m3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-M3. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_m3_aead_encrypt() + */ +int romulus_m3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/aead-common.c b/romulus/Implementations/crypto_aead/romulusn1+/rhys/aead-common.c new file mode 100644 index 0000000..84fc53a --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/aead-common.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "aead-common.h" + +int aead_check_tag + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned size) +{ + /* Set "accum" to -1 if the tags match, or 0 if they don't match */ + int accum = 0; + while (size > 0) { + accum |= (*tag1++ ^ *tag2++); + --size; + } + accum = (accum - 1) >> 8; + + /* Destroy the plaintext if the tag match failed */ + while (plaintext_len > 0) { + *plaintext++ &= accum; + --plaintext_len; + } + + /* If "accum" is 0, return -1, otherwise return 0 */ + return ~accum; +} + +int aead_check_tag_precheck + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned size, int precheck) +{ + /* Set "accum" to -1 if the tags match, or 0 if they don't match */ + int accum = 0; + while (size > 0) { + accum |= (*tag1++ ^ *tag2++); + --size; + } + accum = ((accum - 1) >> 8) & precheck; + + /* Destroy the plaintext if the tag match failed */ + while (plaintext_len > 0) { + *plaintext++ &= accum; + --plaintext_len; + } + + /* If "accum" is 0, return -1, otherwise return 0 */ + return ~accum; +} diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/aead-common.h b/romulus/Implementations/crypto_aead/romulusn1+/rhys/aead-common.h new file mode 100644 index 0000000..2be95eb --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/aead-common.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LWCRYPTO_AEAD_COMMON_H +#define LWCRYPTO_AEAD_COMMON_H + +#include + +/** + * \file aead-common.h + * \brief Definitions that are common across AEAD schemes. + * + * AEAD stands for "Authenticated Encryption with Associated Data". + * It is a standard API pattern for securely encrypting and + * authenticating packets of data. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Encrypts and authenticates a packet with an AEAD scheme. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - normally not used by AEAD schemes. + * \param npub Points to the public nonce for the packet. + * \param k Points to the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + */ +typedef int (*aead_cipher_encrypt_t) + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with an AEAD scheme. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - normally not used by AEAD schemes. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet. + * \param k Points to the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + */ +typedef int (*aead_cipher_decrypt_t) + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Hashes a block of input data. + * + * \param out Buffer to receive the hash output. + * \param in Points to the input data to be hashed. + * \param inlen Length of the input data in bytes. + * + * \return Returns zero on success or -1 if there was an error in the + * parameters. + */ +typedef int (*aead_hash_t) + (unsigned char *out, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Initializes the state for a hashing operation. + * + * \param state Hash state to be initialized. + */ +typedef void (*aead_hash_init_t)(void *state); + +/** + * \brief Updates a hash state with more input data. + * + * \param state Hash state to be updated. + * \param in Points to the input data to be incorporated into the state. + * \param inlen Length of the input data to be incorporated into the state. + */ +typedef void (*aead_hash_update_t) + (void *state, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Returns the final hash value from a hashing operation. + * + * \param Hash state to be finalized. + * \param out Points to the output buffer to receive the hash value. + */ +typedef void (*aead_hash_finalize_t)(void *state, unsigned char *out); + +/** + * \brief Aborbs more input data into an XOF state. + * + * \param state XOF state to be updated. + * \param in Points to the input data to be absorbed into the state. + * \param inlen Length of the input data to be absorbed into the state. + * + * \sa ascon_xof_init(), ascon_xof_squeeze() + */ +typedef void (*aead_xof_absorb_t) + (void *state, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Squeezes output data from an XOF state. + * + * \param state XOF state to squeeze the output data from. + * \param out Points to the output buffer to receive the squeezed data. + * \param outlen Number of bytes of data to squeeze out of the state. + */ +typedef void (*aead_xof_squeeze_t) + (void *state, unsigned char *out, unsigned long long outlen); + +/** + * \brief No special AEAD features. + */ +#define AEAD_FLAG_NONE 0x0000 + +/** + * \brief The natural byte order of the AEAD cipher is little-endian. + * + * If this flag is not present, then the natural byte order of the + * AEAD cipher should be assumed to be big-endian. + * + * The natural byte order may be useful when formatting packet sequence + * numbers as nonces. The application needs to know whether the sequence + * number should be packed into the leading or trailing bytes of the nonce. + */ +#define AEAD_FLAG_LITTLE_ENDIAN 0x0001 + +/** + * \brief Meta-information about an AEAD cipher. + */ +typedef struct +{ + const char *name; /**< Name of the cipher */ + unsigned key_len; /**< Length of the key in bytes */ + unsigned nonce_len; /**< Length of the nonce in bytes */ + unsigned tag_len; /**< Length of the tag in bytes */ + unsigned flags; /**< Flags for extra features */ + aead_cipher_encrypt_t encrypt; /**< AEAD encryption function */ + aead_cipher_decrypt_t decrypt; /**< AEAD decryption function */ + +} aead_cipher_t; + +/** + * \brief Meta-information about a hash algorithm that is related to an AEAD. + * + * Regular hash algorithms should provide the "hash", "init", "update", + * and "finalize" functions. Extensible Output Functions (XOF's) should + * proivde the "hash", "init", "absorb", and "squeeze" functions. + */ +typedef struct +{ + const char *name; /**< Name of the hash algorithm */ + size_t state_size; /**< Size of the incremental state structure */ + unsigned hash_len; /**< Length of the hash in bytes */ + unsigned flags; /**< Flags for extra features */ + aead_hash_t hash; /**< All in one hashing function */ + aead_hash_init_t init; /**< Incremental hash/XOF init function */ + aead_hash_update_t update; /**< Incremental hash update function */ + aead_hash_finalize_t finalize; /**< Incremental hash finalize function */ + aead_xof_absorb_t absorb; /**< Incremental XOF absorb function */ + aead_xof_squeeze_t squeeze; /**< Incremental XOF squeeze function */ + +} aead_hash_algorithm_t; + +/** + * \brief Check an authentication tag in constant time. + * + * \param plaintext Points to the plaintext data. + * \param plaintext_len Length of the plaintext in bytes. + * \param tag1 First tag to compare. + * \param tag2 Second tag to compare. + * \param tag_len Length of the tags in bytes. + * + * \return Returns -1 if the tag check failed or 0 if the check succeeded. + * + * If the tag check fails, then the \a plaintext will also be zeroed to + * prevent it from being used accidentally by the application when the + * ciphertext was invalid. + */ +int aead_check_tag + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned tag_len); + +/** + * \brief Check an authentication tag in constant time with a previous check. + * + * \param plaintext Points to the plaintext data. + * \param plaintext_len Length of the plaintext in bytes. + * \param tag1 First tag to compare. + * \param tag2 Second tag to compare. + * \param tag_len Length of the tags in bytes. + * \param precheck Set to -1 if previous check succeeded or 0 if it failed. + * + * \return Returns -1 if the tag check failed or 0 if the check succeeded. + * + * If the tag check fails, then the \a plaintext will also be zeroed to + * prevent it from being used accidentally by the application when the + * ciphertext was invalid. + * + * This version can be used to incorporate other information about the + * correctness of the plaintext into the final result. + */ +int aead_check_tag_precheck + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned tag_len, int precheck); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/api.h b/romulus/Implementations/crypto_aead/romulusn1+/rhys/api.h new file mode 100644 index 0000000..b2f8a36 --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/api.h @@ -0,0 +1,5 @@ +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 16 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/encrypt.c b/romulus/Implementations/crypto_aead/romulusn1+/rhys/encrypt.c new file mode 100644 index 0000000..caf0c3f --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/encrypt.c @@ -0,0 +1,25 @@ +#include "romulus.h" + +int crypto_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + return romulus_n1_aead_encrypt + (c, clen, m, mlen, ad, adlen, nsec, npub, k); +} + +int crypto_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + return romulus_n1_aead_decrypt + (m, mlen, nsec, c, clen, ad, adlen, npub, k); +} diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128-avr.S b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128-avr.S new file mode 100644 index 0000000..0fafa4e --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128-avr.S @@ -0,0 +1,10099 @@ +#if defined(__AVR__) +#include +/* Automatically generated - do not edit */ + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_0, @object + .size table_0, 256 +table_0: + .byte 101 + .byte 76 + .byte 106 + .byte 66 + .byte 75 + .byte 99 + .byte 67 + .byte 107 + .byte 85 + .byte 117 + .byte 90 + .byte 122 + .byte 83 + .byte 115 + .byte 91 + .byte 123 + .byte 53 + .byte 140 + .byte 58 + .byte 129 + .byte 137 + .byte 51 + .byte 128 + .byte 59 + .byte 149 + .byte 37 + .byte 152 + .byte 42 + .byte 144 + .byte 35 + .byte 153 + .byte 43 + .byte 229 + .byte 204 + .byte 232 + .byte 193 + .byte 201 + .byte 224 + .byte 192 + .byte 233 + .byte 213 + .byte 245 + .byte 216 + .byte 248 + .byte 208 + .byte 240 + .byte 217 + .byte 249 + .byte 165 + .byte 28 + .byte 168 + .byte 18 + .byte 27 + .byte 160 + .byte 19 + .byte 169 + .byte 5 + .byte 181 + .byte 10 + .byte 184 + .byte 3 + .byte 176 + .byte 11 + .byte 185 + .byte 50 + .byte 136 + .byte 60 + .byte 133 + .byte 141 + .byte 52 + .byte 132 + .byte 61 + .byte 145 + .byte 34 + .byte 156 + .byte 44 + .byte 148 + .byte 36 + .byte 157 + .byte 45 + .byte 98 + .byte 74 + .byte 108 + .byte 69 + .byte 77 + .byte 100 + .byte 68 + .byte 109 + .byte 82 + .byte 114 + .byte 92 + .byte 124 + .byte 84 + .byte 116 + .byte 93 + .byte 125 + .byte 161 + .byte 26 + .byte 172 + .byte 21 + .byte 29 + .byte 164 + .byte 20 + .byte 173 + .byte 2 + .byte 177 + .byte 12 + .byte 188 + .byte 4 + .byte 180 + .byte 13 + .byte 189 + .byte 225 + .byte 200 + .byte 236 + .byte 197 + .byte 205 + .byte 228 + .byte 196 + .byte 237 + .byte 209 + .byte 241 + .byte 220 + .byte 252 + .byte 212 + .byte 244 + .byte 221 + .byte 253 + .byte 54 + .byte 142 + .byte 56 + .byte 130 + .byte 139 + .byte 48 + .byte 131 + .byte 57 + .byte 150 + .byte 38 + .byte 154 + .byte 40 + .byte 147 + .byte 32 + .byte 155 + .byte 41 + .byte 102 + .byte 78 + .byte 104 + .byte 65 + .byte 73 + .byte 96 + .byte 64 + .byte 105 + .byte 86 + .byte 118 + .byte 88 + .byte 120 + .byte 80 + .byte 112 + .byte 89 + .byte 121 + .byte 166 + .byte 30 + .byte 170 + .byte 17 + .byte 25 + .byte 163 + .byte 16 + .byte 171 + .byte 6 + .byte 182 + .byte 8 + .byte 186 + .byte 0 + .byte 179 + .byte 9 + .byte 187 + .byte 230 + .byte 206 + .byte 234 + .byte 194 + .byte 203 + .byte 227 + .byte 195 + .byte 235 + .byte 214 + .byte 246 + .byte 218 + .byte 250 + .byte 211 + .byte 243 + .byte 219 + .byte 251 + .byte 49 + .byte 138 + .byte 62 + .byte 134 + .byte 143 + .byte 55 + .byte 135 + .byte 63 + .byte 146 + .byte 33 + .byte 158 + .byte 46 + .byte 151 + .byte 39 + .byte 159 + .byte 47 + .byte 97 + .byte 72 + .byte 110 + .byte 70 + .byte 79 + .byte 103 + .byte 71 + .byte 111 + .byte 81 + .byte 113 + .byte 94 + .byte 126 + .byte 87 + .byte 119 + .byte 95 + .byte 127 + .byte 162 + .byte 24 + .byte 174 + .byte 22 + .byte 31 + .byte 167 + .byte 23 + .byte 175 + .byte 1 + .byte 178 + .byte 14 + .byte 190 + .byte 7 + .byte 183 + .byte 15 + .byte 191 + .byte 226 + .byte 202 + .byte 238 + .byte 198 + .byte 207 + .byte 231 + .byte 199 + .byte 239 + .byte 210 + .byte 242 + .byte 222 + .byte 254 + .byte 215 + .byte 247 + .byte 223 + .byte 255 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_1, @object + .size table_1, 256 +table_1: + .byte 172 + .byte 232 + .byte 104 + .byte 60 + .byte 108 + .byte 56 + .byte 168 + .byte 236 + .byte 170 + .byte 174 + .byte 58 + .byte 62 + .byte 106 + .byte 110 + .byte 234 + .byte 238 + .byte 166 + .byte 163 + .byte 51 + .byte 54 + .byte 102 + .byte 99 + .byte 227 + .byte 230 + .byte 225 + .byte 164 + .byte 97 + .byte 52 + .byte 49 + .byte 100 + .byte 161 + .byte 228 + .byte 141 + .byte 201 + .byte 73 + .byte 29 + .byte 77 + .byte 25 + .byte 137 + .byte 205 + .byte 139 + .byte 143 + .byte 27 + .byte 31 + .byte 75 + .byte 79 + .byte 203 + .byte 207 + .byte 133 + .byte 192 + .byte 64 + .byte 21 + .byte 69 + .byte 16 + .byte 128 + .byte 197 + .byte 130 + .byte 135 + .byte 18 + .byte 23 + .byte 66 + .byte 71 + .byte 194 + .byte 199 + .byte 150 + .byte 147 + .byte 3 + .byte 6 + .byte 86 + .byte 83 + .byte 211 + .byte 214 + .byte 209 + .byte 148 + .byte 81 + .byte 4 + .byte 1 + .byte 84 + .byte 145 + .byte 212 + .byte 156 + .byte 216 + .byte 88 + .byte 12 + .byte 92 + .byte 8 + .byte 152 + .byte 220 + .byte 154 + .byte 158 + .byte 10 + .byte 14 + .byte 90 + .byte 94 + .byte 218 + .byte 222 + .byte 149 + .byte 208 + .byte 80 + .byte 5 + .byte 85 + .byte 0 + .byte 144 + .byte 213 + .byte 146 + .byte 151 + .byte 2 + .byte 7 + .byte 82 + .byte 87 + .byte 210 + .byte 215 + .byte 157 + .byte 217 + .byte 89 + .byte 13 + .byte 93 + .byte 9 + .byte 153 + .byte 221 + .byte 155 + .byte 159 + .byte 11 + .byte 15 + .byte 91 + .byte 95 + .byte 219 + .byte 223 + .byte 22 + .byte 19 + .byte 131 + .byte 134 + .byte 70 + .byte 67 + .byte 195 + .byte 198 + .byte 65 + .byte 20 + .byte 193 + .byte 132 + .byte 17 + .byte 68 + .byte 129 + .byte 196 + .byte 28 + .byte 72 + .byte 200 + .byte 140 + .byte 76 + .byte 24 + .byte 136 + .byte 204 + .byte 26 + .byte 30 + .byte 138 + .byte 142 + .byte 74 + .byte 78 + .byte 202 + .byte 206 + .byte 53 + .byte 96 + .byte 224 + .byte 165 + .byte 101 + .byte 48 + .byte 160 + .byte 229 + .byte 50 + .byte 55 + .byte 162 + .byte 167 + .byte 98 + .byte 103 + .byte 226 + .byte 231 + .byte 61 + .byte 105 + .byte 233 + .byte 173 + .byte 109 + .byte 57 + .byte 169 + .byte 237 + .byte 59 + .byte 63 + .byte 171 + .byte 175 + .byte 107 + .byte 111 + .byte 235 + .byte 239 + .byte 38 + .byte 35 + .byte 179 + .byte 182 + .byte 118 + .byte 115 + .byte 243 + .byte 246 + .byte 113 + .byte 36 + .byte 241 + .byte 180 + .byte 33 + .byte 116 + .byte 177 + .byte 244 + .byte 44 + .byte 120 + .byte 248 + .byte 188 + .byte 124 + .byte 40 + .byte 184 + .byte 252 + .byte 42 + .byte 46 + .byte 186 + .byte 190 + .byte 122 + .byte 126 + .byte 250 + .byte 254 + .byte 37 + .byte 112 + .byte 240 + .byte 181 + .byte 117 + .byte 32 + .byte 176 + .byte 245 + .byte 34 + .byte 39 + .byte 178 + .byte 183 + .byte 114 + .byte 119 + .byte 242 + .byte 247 + .byte 45 + .byte 121 + .byte 249 + .byte 189 + .byte 125 + .byte 41 + .byte 185 + .byte 253 + .byte 43 + .byte 47 + .byte 187 + .byte 191 + .byte 123 + .byte 127 + .byte 251 + .byte 255 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_2, @object + .size table_2, 256 +table_2: + .byte 0 + .byte 2 + .byte 4 + .byte 6 + .byte 8 + .byte 10 + .byte 12 + .byte 14 + .byte 16 + .byte 18 + .byte 20 + .byte 22 + .byte 24 + .byte 26 + .byte 28 + .byte 30 + .byte 32 + .byte 34 + .byte 36 + .byte 38 + .byte 40 + .byte 42 + .byte 44 + .byte 46 + .byte 48 + .byte 50 + .byte 52 + .byte 54 + .byte 56 + .byte 58 + .byte 60 + .byte 62 + .byte 65 + .byte 67 + .byte 69 + .byte 71 + .byte 73 + .byte 75 + .byte 77 + .byte 79 + .byte 81 + .byte 83 + .byte 85 + .byte 87 + .byte 89 + .byte 91 + .byte 93 + .byte 95 + .byte 97 + .byte 99 + .byte 101 + .byte 103 + .byte 105 + .byte 107 + .byte 109 + .byte 111 + .byte 113 + .byte 115 + .byte 117 + .byte 119 + .byte 121 + .byte 123 + .byte 125 + .byte 127 + .byte 128 + .byte 130 + .byte 132 + .byte 134 + .byte 136 + .byte 138 + .byte 140 + .byte 142 + .byte 144 + .byte 146 + .byte 148 + .byte 150 + .byte 152 + .byte 154 + .byte 156 + .byte 158 + .byte 160 + .byte 162 + .byte 164 + .byte 166 + .byte 168 + .byte 170 + .byte 172 + .byte 174 + .byte 176 + .byte 178 + .byte 180 + .byte 182 + .byte 184 + .byte 186 + .byte 188 + .byte 190 + .byte 193 + .byte 195 + .byte 197 + .byte 199 + .byte 201 + .byte 203 + .byte 205 + .byte 207 + .byte 209 + .byte 211 + .byte 213 + .byte 215 + .byte 217 + .byte 219 + .byte 221 + .byte 223 + .byte 225 + .byte 227 + .byte 229 + .byte 231 + .byte 233 + .byte 235 + .byte 237 + .byte 239 + .byte 241 + .byte 243 + .byte 245 + .byte 247 + .byte 249 + .byte 251 + .byte 253 + .byte 255 + .byte 1 + .byte 3 + .byte 5 + .byte 7 + .byte 9 + .byte 11 + .byte 13 + .byte 15 + .byte 17 + .byte 19 + .byte 21 + .byte 23 + .byte 25 + .byte 27 + .byte 29 + .byte 31 + .byte 33 + .byte 35 + .byte 37 + .byte 39 + .byte 41 + .byte 43 + .byte 45 + .byte 47 + .byte 49 + .byte 51 + .byte 53 + .byte 55 + .byte 57 + .byte 59 + .byte 61 + .byte 63 + .byte 64 + .byte 66 + .byte 68 + .byte 70 + .byte 72 + .byte 74 + .byte 76 + .byte 78 + .byte 80 + .byte 82 + .byte 84 + .byte 86 + .byte 88 + .byte 90 + .byte 92 + .byte 94 + .byte 96 + .byte 98 + .byte 100 + .byte 102 + .byte 104 + .byte 106 + .byte 108 + .byte 110 + .byte 112 + .byte 114 + .byte 116 + .byte 118 + .byte 120 + .byte 122 + .byte 124 + .byte 126 + .byte 129 + .byte 131 + .byte 133 + .byte 135 + .byte 137 + .byte 139 + .byte 141 + .byte 143 + .byte 145 + .byte 147 + .byte 149 + .byte 151 + .byte 153 + .byte 155 + .byte 157 + .byte 159 + .byte 161 + .byte 163 + .byte 165 + .byte 167 + .byte 169 + .byte 171 + .byte 173 + .byte 175 + .byte 177 + .byte 179 + .byte 181 + .byte 183 + .byte 185 + .byte 187 + .byte 189 + .byte 191 + .byte 192 + .byte 194 + .byte 196 + .byte 198 + .byte 200 + .byte 202 + .byte 204 + .byte 206 + .byte 208 + .byte 210 + .byte 212 + .byte 214 + .byte 216 + .byte 218 + .byte 220 + .byte 222 + .byte 224 + .byte 226 + .byte 228 + .byte 230 + .byte 232 + .byte 234 + .byte 236 + .byte 238 + .byte 240 + .byte 242 + .byte 244 + .byte 246 + .byte 248 + .byte 250 + .byte 252 + .byte 254 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_3, @object + .size table_3, 256 +table_3: + .byte 0 + .byte 128 + .byte 1 + .byte 129 + .byte 2 + .byte 130 + .byte 3 + .byte 131 + .byte 4 + .byte 132 + .byte 5 + .byte 133 + .byte 6 + .byte 134 + .byte 7 + .byte 135 + .byte 8 + .byte 136 + .byte 9 + .byte 137 + .byte 10 + .byte 138 + .byte 11 + .byte 139 + .byte 12 + .byte 140 + .byte 13 + .byte 141 + .byte 14 + .byte 142 + .byte 15 + .byte 143 + .byte 16 + .byte 144 + .byte 17 + .byte 145 + .byte 18 + .byte 146 + .byte 19 + .byte 147 + .byte 20 + .byte 148 + .byte 21 + .byte 149 + .byte 22 + .byte 150 + .byte 23 + .byte 151 + .byte 24 + .byte 152 + .byte 25 + .byte 153 + .byte 26 + .byte 154 + .byte 27 + .byte 155 + .byte 28 + .byte 156 + .byte 29 + .byte 157 + .byte 30 + .byte 158 + .byte 31 + .byte 159 + .byte 160 + .byte 32 + .byte 161 + .byte 33 + .byte 162 + .byte 34 + .byte 163 + .byte 35 + .byte 164 + .byte 36 + .byte 165 + .byte 37 + .byte 166 + .byte 38 + .byte 167 + .byte 39 + .byte 168 + .byte 40 + .byte 169 + .byte 41 + .byte 170 + .byte 42 + .byte 171 + .byte 43 + .byte 172 + .byte 44 + .byte 173 + .byte 45 + .byte 174 + .byte 46 + .byte 175 + .byte 47 + .byte 176 + .byte 48 + .byte 177 + .byte 49 + .byte 178 + .byte 50 + .byte 179 + .byte 51 + .byte 180 + .byte 52 + .byte 181 + .byte 53 + .byte 182 + .byte 54 + .byte 183 + .byte 55 + .byte 184 + .byte 56 + .byte 185 + .byte 57 + .byte 186 + .byte 58 + .byte 187 + .byte 59 + .byte 188 + .byte 60 + .byte 189 + .byte 61 + .byte 190 + .byte 62 + .byte 191 + .byte 63 + .byte 64 + .byte 192 + .byte 65 + .byte 193 + .byte 66 + .byte 194 + .byte 67 + .byte 195 + .byte 68 + .byte 196 + .byte 69 + .byte 197 + .byte 70 + .byte 198 + .byte 71 + .byte 199 + .byte 72 + .byte 200 + .byte 73 + .byte 201 + .byte 74 + .byte 202 + .byte 75 + .byte 203 + .byte 76 + .byte 204 + .byte 77 + .byte 205 + .byte 78 + .byte 206 + .byte 79 + .byte 207 + .byte 80 + .byte 208 + .byte 81 + .byte 209 + .byte 82 + .byte 210 + .byte 83 + .byte 211 + .byte 84 + .byte 212 + .byte 85 + .byte 213 + .byte 86 + .byte 214 + .byte 87 + .byte 215 + .byte 88 + .byte 216 + .byte 89 + .byte 217 + .byte 90 + .byte 218 + .byte 91 + .byte 219 + .byte 92 + .byte 220 + .byte 93 + .byte 221 + .byte 94 + .byte 222 + .byte 95 + .byte 223 + .byte 224 + .byte 96 + .byte 225 + .byte 97 + .byte 226 + .byte 98 + .byte 227 + .byte 99 + .byte 228 + .byte 100 + .byte 229 + .byte 101 + .byte 230 + .byte 102 + .byte 231 + .byte 103 + .byte 232 + .byte 104 + .byte 233 + .byte 105 + .byte 234 + .byte 106 + .byte 235 + .byte 107 + .byte 236 + .byte 108 + .byte 237 + .byte 109 + .byte 238 + .byte 110 + .byte 239 + .byte 111 + .byte 240 + .byte 112 + .byte 241 + .byte 113 + .byte 242 + .byte 114 + .byte 243 + .byte 115 + .byte 244 + .byte 116 + .byte 245 + .byte 117 + .byte 246 + .byte 118 + .byte 247 + .byte 119 + .byte 248 + .byte 120 + .byte 249 + .byte 121 + .byte 250 + .byte 122 + .byte 251 + .byte 123 + .byte 252 + .byte 124 + .byte 253 + .byte 125 + .byte 254 + .byte 126 + .byte 255 + .byte 127 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_4, @object + .size table_4, 112 +table_4: + .byte 1 + .byte 0 + .byte 3 + .byte 0 + .byte 7 + .byte 0 + .byte 15 + .byte 0 + .byte 15 + .byte 1 + .byte 14 + .byte 3 + .byte 13 + .byte 3 + .byte 11 + .byte 3 + .byte 7 + .byte 3 + .byte 15 + .byte 2 + .byte 14 + .byte 1 + .byte 12 + .byte 3 + .byte 9 + .byte 3 + .byte 3 + .byte 3 + .byte 7 + .byte 2 + .byte 14 + .byte 0 + .byte 13 + .byte 1 + .byte 10 + .byte 3 + .byte 5 + .byte 3 + .byte 11 + .byte 2 + .byte 6 + .byte 1 + .byte 12 + .byte 2 + .byte 8 + .byte 1 + .byte 0 + .byte 3 + .byte 1 + .byte 2 + .byte 2 + .byte 0 + .byte 5 + .byte 0 + .byte 11 + .byte 0 + .byte 7 + .byte 1 + .byte 14 + .byte 2 + .byte 12 + .byte 1 + .byte 8 + .byte 3 + .byte 1 + .byte 3 + .byte 3 + .byte 2 + .byte 6 + .byte 0 + .byte 13 + .byte 0 + .byte 11 + .byte 1 + .byte 6 + .byte 3 + .byte 13 + .byte 2 + .byte 10 + .byte 1 + .byte 4 + .byte 3 + .byte 9 + .byte 2 + .byte 2 + .byte 1 + .byte 4 + .byte 2 + .byte 8 + .byte 0 + .byte 1 + .byte 1 + .byte 2 + .byte 2 + .byte 4 + .byte 0 + .byte 9 + .byte 0 + .byte 3 + .byte 1 + .byte 6 + .byte 2 + .byte 12 + .byte 0 + .byte 9 + .byte 1 + .byte 2 + .byte 3 + .byte 5 + .byte 2 + .byte 10 + .byte 0 + + .text +.global skinny_128_384_init + .type skinny_128_384_init, @function +skinny_128_384_init: + movw r30,r24 + movw r26,r22 +.L__stack_usage = 2 + ldi r22,12 +1: + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + st Z+,r18 + st Z+,r19 + st Z+,r20 + st Z+,r21 + dec r22 + brne 1b + ret + .size skinny_128_384_init, .-skinny_128_384_init + + .text +.global skinny_128_384_encrypt + .type skinny_128_384_encrypt, @function +skinny_128_384_encrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,48 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 68 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + ldd r18,Z+4 + ldd r19,Z+5 + ldd r20,Z+6 + ldd r21,Z+7 + std Y+5,r18 + std Y+6,r19 + std Y+7,r20 + std Y+8,r21 + ldd r18,Z+8 + ldd r19,Z+9 + ldd r20,Z+10 + ldd r21,Z+11 + std Y+9,r18 + std Y+10,r19 + std Y+11,r20 + std Y+12,r21 + ldd r18,Z+12 + ldd r19,Z+13 + ldd r20,Z+14 + ldd r21,Z+15 + std Y+13,r18 + std Y+14,r19 + std Y+15,r20 + std Y+16,r21 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + ldd r18,Z+20 + ldd r19,Z+21 + ldd r20,Z+22 + ldd r21,Z+23 + std Y+21,r18 + std Y+22,r19 + std Y+23,r20 + std Y+24,r21 + ldd r18,Z+24 + ldd r19,Z+25 + ldd r20,Z+26 + ldd r21,Z+27 + std Y+25,r18 + std Y+26,r19 + std Y+27,r20 + std Y+28,r21 + ldd r18,Z+28 + ldd r19,Z+29 + ldd r20,Z+30 + ldd r21,Z+31 + std Y+29,r18 + std Y+30,r19 + std Y+31,r20 + std Y+32,r21 + ldd r18,Z+32 + ldd r19,Z+33 + ldd r20,Z+34 + ldd r21,Z+35 + std Y+33,r18 + std Y+34,r19 + std Y+35,r20 + std Y+36,r21 + ldd r18,Z+36 + ldd r19,Z+37 + ldd r20,Z+38 + ldd r21,Z+39 + std Y+37,r18 + std Y+38,r19 + std Y+39,r20 + std Y+40,r21 + ldd r18,Z+40 + ldd r19,Z+41 + ldd r20,Z+42 + ldd r21,Z+43 + std Y+41,r18 + std Y+42,r19 + std Y+43,r20 + std Y+44,r21 + ldd r18,Z+44 + ldd r19,Z+45 + ldd r20,Z+46 + ldd r21,Z+47 + std Y+45,r18 + std Y+46,r19 + std Y+47,r20 + std Y+48,r21 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r26,hh8(table_0) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + mov r26,r1 +114: + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + ldi r27,2 + eor r4,r27 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+33 + eor r18,r0 + ldd r0,Y+34 + eor r19,r0 + ldd r0,Y+35 + eor r20,r0 + ldd r0,Y+36 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldd r0,Y+37 + eor r22,r0 + ldd r0,Y+38 + eor r23,r0 + ldd r0,Y+39 + eor r2,r0 + ldd r0,Y+40 + eor r3,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + mov r0,r6 + mov r6,r4 + mov r4,r0 + mov r0,r7 + mov r7,r5 + mov r5,r0 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r13 + std Y+42,r17 + std Y+43,r12 + std Y+44,r25 + std Y+45,r14 + std Y+46,r16 + std Y+47,r24 + std Y+48,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + ldi r27,2 + eor r22,r27 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+41 + eor r8,r0 + ldd r0,Y+42 + eor r9,r0 + ldd r0,Y+43 + eor r10,r0 + ldd r0,Y+44 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldd r0,Y+45 + eor r18,r0 + ldd r0,Y+46 + eor r19,r0 + ldd r0,Y+47 + eor r20,r0 + ldd r0,Y+48 + eor r21,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + mov r0,r2 + mov r2,r22 + mov r22,r0 + mov r0,r3 + mov r3,r23 + mov r23,r0 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r13 + std Y+34,r17 + std Y+35,r12 + std Y+36,r25 + std Y+37,r14 + std Y+38,r16 + std Y+39,r24 + std Y+40,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + ldi r27,2 + eor r18,r27 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+33 + eor r4,r0 + ldd r0,Y+34 + eor r5,r0 + ldd r0,Y+35 + eor r6,r0 + ldd r0,Y+36 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldd r0,Y+37 + eor r8,r0 + ldd r0,Y+38 + eor r9,r0 + ldd r0,Y+39 + eor r10,r0 + ldd r0,Y+40 + eor r11,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + mov r0,r20 + mov r20,r18 + mov r18,r0 + mov r0,r21 + mov r21,r19 + mov r19,r0 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r13 + std Y+42,r17 + std Y+43,r12 + std Y+44,r25 + std Y+45,r14 + std Y+46,r16 + std Y+47,r24 + std Y+48,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + ldi r27,2 + eor r8,r27 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+41 + eor r22,r0 + ldd r0,Y+42 + eor r23,r0 + ldd r0,Y+43 + eor r2,r0 + ldd r0,Y+44 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldd r0,Y+45 + eor r4,r0 + ldd r0,Y+46 + eor r5,r0 + ldd r0,Y+47 + eor r6,r0 + ldd r0,Y+48 + eor r7,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + mov r0,r10 + mov r10,r8 + mov r8,r0 + mov r0,r11 + mov r11,r9 + mov r9,r0 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + cpi r26,80 + brne 5721f + rjmp 790f +5721: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r13 + std Y+34,r17 + std Y+35,r12 + std Y+36,r25 + std Y+37,r14 + std Y+38,r16 + std Y+39,r24 + std Y+40,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 114b +790: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+49 + ldd r27,Y+50 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,50 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_384_encrypt, .-skinny_128_384_encrypt + +.global skinny_128_384_encrypt_tk_full + .set skinny_128_384_encrypt_tk_full,skinny_128_384_encrypt + + .text +.global skinny_128_384_decrypt + .type skinny_128_384_decrypt, @function +skinny_128_384_decrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,48 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 68 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + ldd r22,Z+4 + ldd r23,Z+5 + ldd r2,Z+6 + ldd r3,Z+7 + ldd r4,Z+8 + ldd r5,Z+9 + ldd r6,Z+10 + ldd r7,Z+11 + ldd r8,Z+12 + ldd r9,Z+13 + ldd r10,Z+14 + ldd r11,Z+15 + std Y+1,r23 + std Y+2,r2 + std Y+3,r21 + std Y+4,r20 + std Y+5,r3 + std Y+6,r18 + std Y+7,r19 + std Y+8,r22 + std Y+9,r9 + std Y+10,r10 + std Y+11,r7 + std Y+12,r6 + std Y+13,r11 + std Y+14,r4 + std Y+15,r5 + std Y+16,r8 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + ldd r22,Z+20 + ldd r23,Z+21 + ldd r2,Z+22 + ldd r3,Z+23 + ldd r4,Z+24 + ldd r5,Z+25 + ldd r6,Z+26 + ldd r7,Z+27 + ldd r8,Z+28 + ldd r9,Z+29 + ldd r10,Z+30 + ldd r11,Z+31 + std Y+17,r23 + std Y+18,r2 + std Y+19,r21 + std Y+20,r20 + std Y+21,r3 + std Y+22,r18 + std Y+23,r19 + std Y+24,r22 + std Y+25,r9 + std Y+26,r10 + std Y+27,r7 + std Y+28,r6 + std Y+29,r11 + std Y+30,r4 + std Y+31,r5 + std Y+32,r8 + ldd r18,Z+32 + ldd r19,Z+33 + ldd r20,Z+34 + ldd r21,Z+35 + ldd r22,Z+36 + ldd r23,Z+37 + ldd r2,Z+38 + ldd r3,Z+39 + ldd r4,Z+40 + ldd r5,Z+41 + ldd r6,Z+42 + ldd r7,Z+43 + ldd r8,Z+44 + ldd r9,Z+45 + ldd r10,Z+46 + ldd r11,Z+47 + std Y+33,r23 + std Y+34,r2 + std Y+35,r21 + std Y+36,r20 + std Y+37,r3 + std Y+38,r18 + std Y+39,r19 + std Y+40,r22 + std Y+41,r9 + std Y+42,r10 + std Y+43,r7 + std Y+44,r6 + std Y+45,r11 + std Y+46,r4 + std Y+47,r5 + std Y+48,r8 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r26,hh8(table_2) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,20 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 +122: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 122b + std Y+17,r12 + std Y+18,r13 + std Y+19,r14 + std Y+20,r15 + std Y+21,r24 + std Y+22,r25 + std Y+23,r16 + std Y+24,r17 + ldi r26,20 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 +150: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 150b + std Y+25,r12 + std Y+26,r13 + std Y+27,r14 + std Y+28,r15 + std Y+29,r24 + std Y+30,r25 + std Y+31,r16 + std Y+32,r17 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r26,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,20 + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 +179: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 179b + std Y+33,r12 + std Y+34,r13 + std Y+35,r14 + std Y+36,r15 + std Y+37,r24 + std Y+38,r25 + std Y+39,r16 + std Y+40,r17 + ldi r26,20 + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 +207: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 207b + std Y+41,r12 + std Y+42,r13 + std Y+43,r14 + std Y+44,r15 + std Y+45,r24 + std Y+46,r25 + std Y+47,r16 + std Y+48,r17 + ldi r26,80 +227: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r14 + std Y+34,r12 + std Y+35,r24 + std Y+36,r17 + std Y+37,r16 + std Y+38,r15 + std Y+39,r25 + std Y+40,r13 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + mov r0,r8 + mov r8,r10 + mov r10,r0 + mov r0,r9 + mov r9,r11 + mov r11,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+41 + eor r22,r0 + ldd r0,Y+42 + eor r23,r0 + ldd r0,Y+43 + eor r2,r0 + ldd r0,Y+44 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldd r0,Y+45 + eor r4,r0 + ldd r0,Y+46 + eor r5,r0 + ldd r0,Y+47 + eor r6,r0 + ldd r0,Y+48 + eor r7,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + ldi r27,2 + eor r8,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r14 + std Y+42,r12 + std Y+43,r24 + std Y+44,r17 + std Y+45,r16 + std Y+46,r15 + std Y+47,r25 + std Y+48,r13 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + mov r0,r18 + mov r18,r20 + mov r20,r0 + mov r0,r19 + mov r19,r21 + mov r21,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+33 + eor r4,r0 + ldd r0,Y+34 + eor r5,r0 + ldd r0,Y+35 + eor r6,r0 + ldd r0,Y+36 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldd r0,Y+37 + eor r8,r0 + ldd r0,Y+38 + eor r9,r0 + ldd r0,Y+39 + eor r10,r0 + ldd r0,Y+40 + eor r11,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + ldi r27,2 + eor r18,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r14 + std Y+34,r12 + std Y+35,r24 + std Y+36,r17 + std Y+37,r16 + std Y+38,r15 + std Y+39,r25 + std Y+40,r13 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + mov r0,r22 + mov r22,r2 + mov r2,r0 + mov r0,r23 + mov r23,r3 + mov r3,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+41 + eor r8,r0 + ldd r0,Y+42 + eor r9,r0 + ldd r0,Y+43 + eor r10,r0 + ldd r0,Y+44 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldd r0,Y+45 + eor r18,r0 + ldd r0,Y+46 + eor r19,r0 + ldd r0,Y+47 + eor r20,r0 + ldd r0,Y+48 + eor r21,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + ldi r27,2 + eor r22,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r14 + std Y+42,r12 + std Y+43,r24 + std Y+44,r17 + std Y+45,r16 + std Y+46,r15 + std Y+47,r25 + std Y+48,r13 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + mov r0,r4 + mov r4,r6 + mov r6,r0 + mov r0,r5 + mov r5,r7 + mov r7,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+33 + eor r18,r0 + ldd r0,Y+34 + eor r19,r0 + ldd r0,Y+35 + eor r20,r0 + ldd r0,Y+36 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldd r0,Y+37 + eor r22,r0 + ldd r0,Y+38 + eor r23,r0 + ldd r0,Y+39 + eor r2,r0 + ldd r0,Y+40 + eor r3,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + ldi r27,2 + eor r4,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + cp r26,r1 + breq 903f + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 227b +903: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+49 + ldd r27,Y+50 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,50 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_384_decrypt, .-skinny_128_384_decrypt + + .text +.global skinny_128_256_init + .type skinny_128_256_init, @function +skinny_128_256_init: + movw r30,r24 + movw r26,r22 +.L__stack_usage = 2 + ldi r22,8 +1: + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + st Z+,r18 + st Z+,r19 + st Z+,r20 + st Z+,r21 + dec r22 + brne 1b + ret + .size skinny_128_256_init, .-skinny_128_256_init + + .text +.global skinny_128_256_encrypt + .type skinny_128_256_encrypt, @function +skinny_128_256_encrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,32 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 52 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + ldd r18,Z+4 + ldd r19,Z+5 + ldd r20,Z+6 + ldd r21,Z+7 + std Y+5,r18 + std Y+6,r19 + std Y+7,r20 + std Y+8,r21 + ldd r18,Z+8 + ldd r19,Z+9 + ldd r20,Z+10 + ldd r21,Z+11 + std Y+9,r18 + std Y+10,r19 + std Y+11,r20 + std Y+12,r21 + ldd r18,Z+12 + ldd r19,Z+13 + ldd r20,Z+14 + ldd r21,Z+15 + std Y+13,r18 + std Y+14,r19 + std Y+15,r20 + std Y+16,r21 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + ldd r18,Z+20 + ldd r19,Z+21 + ldd r20,Z+22 + ldd r21,Z+23 + std Y+21,r18 + std Y+22,r19 + std Y+23,r20 + std Y+24,r21 + ldd r18,Z+24 + ldd r19,Z+25 + ldd r20,Z+26 + ldd r21,Z+27 + std Y+25,r18 + std Y+26,r19 + std Y+27,r20 + std Y+28,r21 + ldd r18,Z+28 + ldd r19,Z+29 + ldd r20,Z+30 + ldd r21,Z+31 + std Y+29,r18 + std Y+30,r19 + std Y+31,r20 + std Y+32,r21 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r26,hh8(table_0) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + mov r26,r1 +82: + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + ldi r27,2 + eor r4,r27 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + mov r0,r6 + mov r6,r4 + mov r4,r0 + mov r0,r7 + mov r7,r5 + mov r5,r0 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + ldi r27,2 + eor r22,r27 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + mov r0,r2 + mov r2,r22 + mov r22,r0 + mov r0,r3 + mov r3,r23 + mov r23,r0 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + ldi r27,2 + eor r18,r27 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + mov r0,r20 + mov r20,r18 + mov r18,r0 + mov r0,r21 + mov r21,r19 + mov r19,r0 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + ldi r27,2 + eor r8,r27 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + mov r0,r10 + mov r10,r8 + mov r8,r0 + mov r0,r11 + mov r11,r9 + mov r9,r0 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + cpi r26,96 + breq 594f + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 82b +594: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+33 + ldd r27,Y+34 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,34 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_256_encrypt, .-skinny_128_256_encrypt + +.global skinny_128_256_encrypt_tk_full + .set skinny_128_256_encrypt_tk_full,skinny_128_256_encrypt + + .text +.global skinny_128_256_decrypt + .type skinny_128_256_decrypt, @function +skinny_128_256_decrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,32 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 52 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + ldd r22,Z+4 + ldd r23,Z+5 + ldd r2,Z+6 + ldd r3,Z+7 + ldd r4,Z+8 + ldd r5,Z+9 + ldd r6,Z+10 + ldd r7,Z+11 + ldd r8,Z+12 + ldd r9,Z+13 + ldd r10,Z+14 + ldd r11,Z+15 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + std Y+5,r22 + std Y+6,r23 + std Y+7,r2 + std Y+8,r3 + std Y+9,r4 + std Y+10,r5 + std Y+11,r6 + std Y+12,r7 + std Y+13,r8 + std Y+14,r9 + std Y+15,r10 + std Y+16,r11 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + ldd r22,Z+20 + ldd r23,Z+21 + ldd r2,Z+22 + ldd r3,Z+23 + ldd r4,Z+24 + ldd r5,Z+25 + ldd r6,Z+26 + ldd r7,Z+27 + ldd r8,Z+28 + ldd r9,Z+29 + ldd r10,Z+30 + ldd r11,Z+31 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + std Y+21,r22 + std Y+22,r23 + std Y+23,r2 + std Y+24,r3 + std Y+25,r4 + std Y+26,r5 + std Y+27,r6 + std Y+28,r7 + std Y+29,r8 + std Y+30,r9 + std Y+31,r10 + std Y+32,r11 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r26,hh8(table_2) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,24 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 +90: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 90b + std Y+17,r12 + std Y+18,r13 + std Y+19,r14 + std Y+20,r15 + std Y+21,r24 + std Y+22,r25 + std Y+23,r16 + std Y+24,r17 + ldi r26,24 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 +118: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 118b + std Y+25,r12 + std Y+26,r13 + std Y+27,r14 + std Y+28,r15 + std Y+29,r24 + std Y+30,r25 + std Y+31,r16 + std Y+32,r17 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r26,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,96 +139: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + mov r0,r8 + mov r8,r10 + mov r10,r0 + mov r0,r9 + mov r9,r11 + mov r11,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + ldi r27,2 + eor r8,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + mov r0,r18 + mov r18,r20 + mov r20,r0 + mov r0,r19 + mov r19,r21 + mov r21,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + ldi r27,2 + eor r18,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + mov r0,r22 + mov r22,r2 + mov r2,r0 + mov r0,r23 + mov r23,r3 + mov r3,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + ldi r27,2 + eor r22,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + mov r0,r4 + mov r4,r6 + mov r6,r0 + mov r0,r5 + mov r5,r7 + mov r7,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + ldi r27,2 + eor r4,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + cp r26,r1 + breq 651f + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 139b +651: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+33 + ldd r27,Y+34 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,34 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_256_decrypt, .-skinny_128_256_decrypt + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128.c b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128.c new file mode 100644 index 0000000..cb1fbda --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128.c @@ -0,0 +1,801 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "internal-skinny128.h" +#include "internal-skinnyutil.h" +#include "internal-util.h" +#include + +#if !defined(__AVR__) + +STATIC_INLINE void skinny128_fast_forward_tk(uint32_t *tk) +{ + /* This function is used to fast-forward the TK1 tweak value + * to the value at the end of the key schedule for decryption. + * + * The tweak permutation repeats every 16 rounds, so SKINNY-128-256 + * with 48 rounds does not need any fast forwarding applied. + * SKINNY-128-128 with 40 rounds and SKINNY-128-384 with 56 rounds + * are equivalent to applying the permutation 8 times: + * + * PT*8 = [5, 6, 3, 2, 7, 0, 1, 4, 13, 14, 11, 10, 15, 8, 9, 12] + */ + uint32_t row0 = tk[0]; + uint32_t row1 = tk[1]; + uint32_t row2 = tk[2]; + uint32_t row3 = tk[3]; + tk[0] = ((row1 >> 8) & 0x0000FFFFU) | + ((row0 >> 8) & 0x00FF0000U) | + ((row0 << 8) & 0xFF000000U); + tk[1] = ((row1 >> 24) & 0x000000FFU) | + ((row0 << 8) & 0x00FFFF00U) | + ((row1 << 24) & 0xFF000000U); + tk[2] = ((row3 >> 8) & 0x0000FFFFU) | + ((row2 >> 8) & 0x00FF0000U) | + ((row2 << 8) & 0xFF000000U); + tk[3] = ((row3 >> 24) & 0x000000FFU) | + ((row2 << 8) & 0x00FFFF00U) | + ((row3 << 24) & 0xFF000000U); +} + +void skinny_128_384_init + (skinny_128_384_key_schedule_t *ks, const unsigned char key[48]) +{ +#if !SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint32_t *schedule; + unsigned round; + uint8_t rc; +#endif + +#if SKINNY_128_SMALL_SCHEDULE + /* Copy the input key as-is when using the small key schedule version */ + memcpy(ks->TK1, key, sizeof(ks->TK1)); + memcpy(ks->TK2, key + 16, sizeof(ks->TK2)); + memcpy(ks->TK3, key + 32, sizeof(ks->TK3)); +#else + /* Set the initial states of TK1, TK2, and TK3 */ + memcpy(ks->TK1, key, 16); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + TK3[0] = le_load_word32(key + 32); + TK3[1] = le_load_word32(key + 36); + TK3[2] = le_load_word32(key + 40); + TK3[3] = le_load_word32(key + 44); + + /* Set up the key schedule using TK2 and TK3. TK1 is not added + * to the key schedule because we will derive that part of the + * schedule during encryption operations */ + schedule = ks->k; + rc = 0; + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round, schedule += 2) { + /* XOR the round constants with the current schedule words. + * The round constants for the 3rd and 4th rows are + * fixed and will be applied during encryption. */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + schedule[0] = TK2[0] ^ TK3[0] ^ (rc & 0x0F); + schedule[1] = TK2[1] ^ TK3[1] ^ (rc >> 4); + + /* Permute TK2 and TK3 for the next round */ + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + + /* Apply the LFSR's to TK2 and TK3 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + } +#endif +} + +void skinny_128_384_encrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 for the next round */ + skinny128_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_decrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint8_t rc = 0x15; +#else + const uint32_t *schedule = &(ks->k[SKINNY_128_384_ROUNDS * 2 - 2]); +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1 */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Permute TK1 to fast-forward it to the end of the key schedule */ + skinny128_fast_forward_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_fast_forward_tk(TK2); + skinny128_fast_forward_tk(TK3); + for (round = 0; round < SKINNY_128_384_ROUNDS; round += 2) { + /* Also fast-forward the LFSR's on every byte of TK2 and TK3 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR2(TK2[2]); + skinny128_LFSR2(TK2[3]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + skinny128_LFSR3(TK3[2]); + skinny128_LFSR3(TK3[3]); + } +#endif + + /* Perform all decryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Inverse permutation on TK1 for this round */ + skinny128_inv_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_inv_permute_tk(TK2); + skinny128_inv_permute_tk(TK3); + skinny128_LFSR3(TK2[2]); + skinny128_LFSR3(TK2[3]); + skinny128_LFSR2(TK3[2]); + skinny128_LFSR2(TK3[3]); +#endif + + /* Inverse mix of the columns */ + temp = s3; + s3 = s0; + s0 = s1; + s1 = s2; + s3 ^= temp; + s2 = temp ^ s0; + s1 ^= s2; + + /* Inverse shift of the rows */ + s1 = leftRotate24(s1); + s2 = leftRotate16(s2); + s3 = leftRotate8(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc >> 1) ^ (((rc << 5) ^ rc ^ 0x20) & 0x20); + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; + schedule -= 2; +#endif + s2 ^= 0x02; + + /* Apply the inverse of the S-box to all bytes in the state */ + skinny128_inv_sbox(s0); + skinny128_inv_sbox(s1); + skinny128_inv_sbox(s2); + skinny128_inv_sbox(s3); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK3[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); + TK2[0] = le_load_word32(tk2); + TK2[1] = le_load_word32(tk2 + 4); + TK2[2] = le_load_word32(tk2 + 8); + TK2[3] = le_load_word32(tk2 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0] ^ TK2[0]; + s1 ^= schedule[1] ^ TK1[1] ^ TK2[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK3); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_encrypt_tk_full + (const unsigned char key[48], unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; + uint32_t TK3[4]; + uint32_t temp; + unsigned round; + uint8_t rc = 0; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakey */ + TK1[0] = le_load_word32(key); + TK1[1] = le_load_word32(key + 4); + TK1[2] = le_load_word32(key + 8); + TK1[3] = le_load_word32(key + 12); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + TK3[0] = le_load_word32(key + 32); + TK3[1] = le_load_word32(key + 36); + TK3[2] = le_load_word32(key + 40); + TK3[3] = le_load_word32(key + 44); + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1, TK2, and TK3 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_init + (skinny_128_256_key_schedule_t *ks, const unsigned char key[32]) +{ +#if !SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t *schedule; + unsigned round; + uint8_t rc; +#endif + +#if SKINNY_128_SMALL_SCHEDULE + /* Copy the input key as-is when using the small key schedule version */ + memcpy(ks->TK1, key, sizeof(ks->TK1)); + memcpy(ks->TK2, key + 16, sizeof(ks->TK2)); +#else + /* Set the initial states of TK1 and TK2 */ + memcpy(ks->TK1, key, 16); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + + /* Set up the key schedule using TK2. TK1 is not added + * to the key schedule because we will derive that part of the + * schedule during encryption operations */ + schedule = ks->k; + rc = 0; + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round, schedule += 2) { + /* XOR the round constants with the current schedule words. + * The round constants for the 3rd and 4th rows are + * fixed and will be applied during encryption. */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + schedule[0] = TK2[0] ^ (rc & 0x0F); + schedule[1] = TK2[1] ^ (rc >> 4); + + /* Permute TK2 for the next round */ + skinny128_permute_tk(TK2); + + /* Apply the LFSR to TK2 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + } +#endif +} + +void skinny_128_256_encrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1 */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_decrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint8_t rc = 0x09; +#else + const uint32_t *schedule = &(ks->k[SKINNY_128_256_ROUNDS * 2 - 2]); +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1. + * There is no need to fast-forward TK1 because the value at + * the end of the key schedule is the same as at the start */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + for (round = 0; round < SKINNY_128_256_ROUNDS; round += 2) { + /* Also fast-forward the LFSR's on every byte of TK2 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR2(TK2[2]); + skinny128_LFSR2(TK2[3]); + } +#endif + + /* Perform all decryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Inverse permutation on TK1 for this round */ + skinny128_inv_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_inv_permute_tk(TK2); + skinny128_LFSR3(TK2[2]); + skinny128_LFSR3(TK2[3]); +#endif + + /* Inverse mix of the columns */ + temp = s3; + s3 = s0; + s0 = s1; + s1 = s2; + s3 ^= temp; + s2 = temp ^ s0; + s1 ^= s2; + + /* Inverse shift of the rows */ + s1 = leftRotate24(s1); + s2 = leftRotate16(s2); + s3 = leftRotate8(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc >> 1) ^ (((rc << 5) ^ rc ^ 0x20) & 0x20); + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; + schedule -= 2; +#endif + s2 ^= 0x02; + + /* Apply the inverse of the S-box to all bytes in the state */ + skinny128_inv_sbox(s0); + skinny128_inv_sbox(s1); + skinny128_inv_sbox(s2); + skinny128_inv_sbox(s3); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_encrypt_tk_full + (const unsigned char key[32], unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; + uint32_t temp; + unsigned round; + uint8_t rc = 0; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakey */ + TK1[0] = le_load_word32(key); + TK1[1] = le_load_word32(key + 4); + TK1[2] = le_load_word32(key + 8); + TK1[3] = le_load_word32(key + 12); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +#else /* __AVR__ */ + +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2) +{ + memcpy(ks->TK2, tk2, 16); + skinny_128_384_encrypt(ks, output, input); +} + +#endif /* __AVR__ */ diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128.h b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128.h new file mode 100644 index 0000000..2bfda3c --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinny128.h @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_SKINNY128_H +#define LW_INTERNAL_SKINNY128_H + +/** + * \file internal-skinny128.h + * \brief SKINNY-128 block cipher family. + * + * References: https://eprint.iacr.org/2016/660.pdf, + * https://sites.google.com/site/skinnycipher/ + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \def SKINNY_128_SMALL_SCHEDULE + * \brief Defined to 1 to use the small key schedule version of SKINNY-128. + */ +#if defined(__AVR__) +#define SKINNY_128_SMALL_SCHEDULE 1 +#else +#define SKINNY_128_SMALL_SCHEDULE 0 +#endif + +/** + * \brief Size of a block for SKINNY-128 block ciphers. + */ +#define SKINNY_128_BLOCK_SIZE 16 + +/** + * \brief Number of rounds for SKINNY-128-384. + */ +#define SKINNY_128_384_ROUNDS 56 + +/** + * \brief Structure of the key schedule for SKINNY-128-384. + */ +typedef struct +{ + /** TK1 for the tweakable part of the key schedule */ + uint8_t TK1[16]; + +#if SKINNY_128_SMALL_SCHEDULE + /** TK2 for the small key schedule */ + uint8_t TK2[16]; + + /** TK3 for the small key schedule */ + uint8_t TK3[16]; +#else + /** Words of the full key schedule */ + uint32_t k[SKINNY_128_384_ROUNDS * 2]; +#endif + +} skinny_128_384_key_schedule_t; + +/** + * \brief Initializes the key schedule for SKINNY-128-384. + * + * \param ks Points to the key schedule to initialize. + * \param key Points to the key data. + */ +void skinny_128_384_init + (skinny_128_384_key_schedule_t *ks, const unsigned char key[48]); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_384_encrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Decrypts a 128-bit block with SKINNY-128-384. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_384_decrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384 and an explicitly + * provided TK2 value. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * \param tk2 TK2 value that should be updated on the fly. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when both TK1 and TK2 change from block to block. + * When the key is initialized with skinny_128_384_init(), the TK2 part of + * the key value should be set to zero. + * + * \note Some versions of this function may modify the key schedule to + * copy tk2 into place. + */ +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384 and a + * fully specified tweakey value. + * + * \param key Points to the 384-bit tweakey value. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when the entire tweakey changes from block to + * block. It is slower than the other versions of SKINNY-128-384 but + * more memory-efficient. + */ +void skinny_128_384_encrypt_tk_full + (const unsigned char key[48], unsigned char *output, + const unsigned char *input); + +/** + * \brief Number of rounds for SKINNY-128-256. + */ +#define SKINNY_128_256_ROUNDS 48 + +/** + * \brief Structure of the key schedule for SKINNY-128-256. + */ +typedef struct +{ + /** TK1 for the tweakable part of the key schedule */ + uint8_t TK1[16]; + +#if SKINNY_128_SMALL_SCHEDULE + /** TK2 for the small key schedule */ + uint8_t TK2[16]; +#else + /** Words of the full key schedule */ + uint32_t k[SKINNY_128_256_ROUNDS * 2]; +#endif + +} skinny_128_256_key_schedule_t; + +/** + * \brief Initializes the key schedule for SKINNY-128-256. + * + * \param ks Points to the key schedule to initialize. + * \param key Points to the key data. + */ +void skinny_128_256_init + (skinny_128_256_key_schedule_t *ks, const unsigned char key[32]); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-256. + * + * \param ks Points to the SKINNY-128-256 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_256_encrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Decrypts a 128-bit block with SKINNY-128-256. + * + * \param ks Points to the SKINNY-128-256 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_256_decrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-256 and a + * fully specified tweakey value. + * + * \param key Points to the 256-bit tweakey value. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when the entire tweakey changes from block to + * block. It is slower than the other versions of SKINNY-128-256 but + * more memory-efficient. + */ +void skinny_128_256_encrypt_tk_full + (const unsigned char key[32], unsigned char *output, + const unsigned char *input); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinnyutil.h b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinnyutil.h new file mode 100644 index 0000000..83136cb --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-skinnyutil.h @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_SKINNYUTIL_H +#define LW_INTERNAL_SKINNYUTIL_H + +/** + * \file internal-skinnyutil.h + * \brief Utilities to help implement SKINNY and its variants. + */ + +#include "internal-util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond skinnyutil */ + +/* Utilities for implementing SKINNY-128 */ + +#define skinny128_LFSR2(x) \ + do { \ + uint32_t _x = (x); \ + (x) = ((_x << 1) & 0xFEFEFEFEU) ^ \ + (((_x >> 7) ^ (_x >> 5)) & 0x01010101U); \ + } while (0) + + +#define skinny128_LFSR3(x) \ + do { \ + uint32_t _x = (x); \ + (x) = ((_x >> 1) & 0x7F7F7F7FU) ^ \ + (((_x << 7) ^ (_x << 1)) & 0x80808080U); \ + } while (0) + +/* LFSR2 and LFSR3 are inverses of each other */ +#define skinny128_inv_LFSR2(x) skinny128_LFSR3(x) +#define skinny128_inv_LFSR3(x) skinny128_LFSR2(x) + +#define skinny128_permute_tk(tk) \ + do { \ + /* PT = [9, 15, 8, 13, 10, 14, 12, 11, 0, 1, 2, 3, 4, 5, 6, 7] */ \ + uint32_t row2 = tk[2]; \ + uint32_t row3 = tk[3]; \ + tk[2] = tk[0]; \ + tk[3] = tk[1]; \ + row3 = (row3 << 16) | (row3 >> 16); \ + tk[0] = ((row2 >> 8) & 0x000000FFU) | \ + ((row2 << 16) & 0x00FF0000U) | \ + ( row3 & 0xFF00FF00U); \ + tk[1] = ((row2 >> 16) & 0x000000FFU) | \ + (row2 & 0xFF000000U) | \ + ((row3 << 8) & 0x0000FF00U) | \ + ( row3 & 0x00FF0000U); \ + } while (0) + +#define skinny128_inv_permute_tk(tk) \ + do { \ + /* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \ + uint32_t row0 = tk[0]; \ + uint32_t row1 = tk[1]; \ + tk[0] = tk[2]; \ + tk[1] = tk[3]; \ + tk[2] = ((row0 >> 16) & 0x000000FFU) | \ + ((row0 << 8) & 0x0000FF00U) | \ + ((row1 << 16) & 0x00FF0000U) | \ + ( row1 & 0xFF000000U); \ + tk[3] = ((row0 >> 16) & 0x0000FF00U) | \ + ((row0 << 16) & 0xFF000000U) | \ + ((row1 >> 16) & 0x000000FFU) | \ + ((row1 << 8) & 0x00FF0000U); \ + } while (0) + +/* + * Apply the SKINNY sbox. The original version from the specification is + * equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x11111111U) ^ (x)) + * #define SBOX_SWAP(x) + * (((x) & 0xF9F9F9F9U) | + * (((x) >> 1) & 0x02020202U) | + * (((x) << 1) & 0x04040404U)) + * #define SBOX_PERMUTE(x) + * ((((x) & 0x01010101U) << 2) | + * (((x) & 0x06060606U) << 5) | + * (((x) & 0x20202020U) >> 5) | + * (((x) & 0xC8C8C8C8U) >> 2) | + * (((x) & 0x10101010U) >> 1)) + * + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * return SBOX_SWAP(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_PERMUTE and SBOX_SWAP steps to be performed with one + * final permuatation. This reduces the number of shift operations. + */ +#define skinny128_sbox(x) \ +do { \ + uint32_t y; \ + \ + /* Mix the bits */ \ + x = ~x; \ + x ^= (((x >> 2) & (x >> 3)) & 0x11111111U); \ + y = (((x << 5) & (x << 1)) & 0x20202020U); \ + x ^= (((x << 5) & (x << 4)) & 0x40404040U) ^ y; \ + y = (((x << 2) & (x << 1)) & 0x80808080U); \ + x ^= (((x >> 2) & (x << 1)) & 0x02020202U) ^ y; \ + y = (((x >> 5) & (x << 1)) & 0x04040404U); \ + x ^= (((x >> 1) & (x >> 2)) & 0x08080808U) ^ y; \ + x = ~x; \ + \ + /* Permutation generated by http://programming.sirrida.de/calcperm.php */ \ + /* The final permutation for each byte is [2 7 6 1 3 0 4 5] */ \ + x = ((x & 0x08080808U) << 1) | \ + ((x & 0x32323232U) << 2) | \ + ((x & 0x01010101U) << 5) | \ + ((x & 0x80808080U) >> 6) | \ + ((x & 0x40404040U) >> 4) | \ + ((x & 0x04040404U) >> 2); \ +} while (0) + +/* + * Apply the inverse of the SKINNY sbox. The original version from the + * specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x11111111U) ^ (x)) + * #define SBOX_SWAP(x) + * (((x) & 0xF9F9F9F9U) | + * (((x) >> 1) & 0x02020202U) | + * (((x) << 1) & 0x04040404U)) + * #define SBOX_PERMUTE_INV(x) + * ((((x) & 0x08080808U) << 1) | + * (((x) & 0x32323232U) << 2) | + * (((x) & 0x01010101U) << 5) | + * (((x) & 0xC0C0C0C0U) >> 5) | + * (((x) & 0x04040404U) >> 2)) + * + * x = SBOX_SWAP(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * return SBOX_MIX(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_PERMUTE_INV and SBOX_SWAP steps to be performed with one + * final permuatation. This reduces the number of shift operations. + */ +#define skinny128_inv_sbox(x) \ +do { \ + uint32_t y; \ + \ + /* Mix the bits */ \ + x = ~x; \ + y = (((x >> 1) & (x >> 3)) & 0x01010101U); \ + x ^= (((x >> 2) & (x >> 3)) & 0x10101010U) ^ y; \ + y = (((x >> 6) & (x >> 1)) & 0x02020202U); \ + x ^= (((x >> 1) & (x >> 2)) & 0x08080808U) ^ y; \ + y = (((x << 2) & (x << 1)) & 0x80808080U); \ + x ^= (((x >> 1) & (x << 2)) & 0x04040404U) ^ y; \ + y = (((x << 5) & (x << 1)) & 0x20202020U); \ + x ^= (((x << 4) & (x << 5)) & 0x40404040U) ^ y; \ + x = ~x; \ + \ + /* Permutation generated by http://programming.sirrida.de/calcperm.php */ \ + /* The final permutation for each byte is [5 3 0 4 6 7 2 1] */ \ + x = ((x & 0x01010101U) << 2) | \ + ((x & 0x04040404U) << 4) | \ + ((x & 0x02020202U) << 6) | \ + ((x & 0x20202020U) >> 5) | \ + ((x & 0xC8C8C8C8U) >> 2) | \ + ((x & 0x10101010U) >> 1); \ +} while (0) + +/* Utilities for implementing SKINNY-64 */ + +#define skinny64_LFSR2(x) \ + do { \ + uint16_t _x = (x); \ + (x) = ((_x << 1) & 0xEEEEU) ^ (((_x >> 3) ^ (_x >> 2)) & 0x1111U); \ + } while (0) + +#define skinny64_LFSR3(x) \ + do { \ + uint16_t _x = (x); \ + (x) = ((_x >> 1) & 0x7777U) ^ ((_x ^ (_x << 3)) & 0x8888U); \ + } while (0) + +/* LFSR2 and LFSR3 are inverses of each other */ +#define skinny64_inv_LFSR2(x) skinny64_LFSR3(x) +#define skinny64_inv_LFSR3(x) skinny64_LFSR2(x) + +#define skinny64_permute_tk(tk) \ + do { \ + /* PT = [9, 15, 8, 13, 10, 14, 12, 11, 0, 1, 2, 3, 4, 5, 6, 7] */ \ + uint16_t row2 = tk[2]; \ + uint16_t row3 = tk[3]; \ + tk[2] = tk[0]; \ + tk[3] = tk[1]; \ + row3 = (row3 << 8) | (row3 >> 8); \ + tk[0] = ((row2 << 4) & 0xF000U) | \ + ((row2 >> 8) & 0x00F0U) | \ + ( row3 & 0x0F0FU); \ + tk[1] = ((row2 << 8) & 0xF000U) | \ + ((row3 >> 4) & 0x0F00U) | \ + ( row3 & 0x00F0U) | \ + ( row2 & 0x000FU); \ + } while (0) + +#define skinny64_inv_permute_tk(tk) \ + do { \ + /* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \ + uint16_t row0 = tk[0]; \ + uint16_t row1 = tk[1]; \ + tk[0] = tk[2]; \ + tk[1] = tk[3]; \ + tk[2] = ((row0 << 8) & 0xF000U) | \ + ((row0 >> 4) & 0x0F00U) | \ + ((row1 >> 8) & 0x00F0U) | \ + ( row1 & 0x000FU); \ + tk[3] = ((row1 << 8) & 0xF000U) | \ + ((row0 << 8) & 0x0F00U) | \ + ((row1 >> 4) & 0x00F0U) | \ + ((row0 >> 8) & 0x000FU); \ + } while (0) + +/* + * Apply the SKINNY-64 sbox. The original version from the + * specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x1111U) ^ (x)) + * #define SBOX_SHIFT(x) + * ((((x) << 1) & 0xEEEEU) | (((x) >> 3) & 0x1111U)) + * + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * return SBOX_MIX(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_SHIFT steps to be performed with one final rotation. + * This reduces the number of required shift operations from 14 to 10. + * + * We can further reduce the number of NOT operations from 4 to 2 + * using the technique from https://github.com/kste/skinny_avx to + * convert NOR-XOR operations into AND-XOR operations by converting + * the S-box into its NOT-inverse. + */ +#define skinny64_sbox(x) \ +do { \ + x = ~x; \ + x = (((x >> 3) & (x >> 2)) & 0x1111U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x8888U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x4444U) ^ x; \ + x = (((x >> 2) & (x << 1)) & 0x2222U) ^ x; \ + x = ~x; \ + x = ((x >> 1) & 0x7777U) | ((x << 3) & 0x8888U); \ +} while (0) + +/* + * Apply the inverse of the SKINNY-64 sbox. The original version + * from the specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x1111U) ^ (x)) + * #define SBOX_SHIFT_INV(x) + * ((((x) >> 1) & 0x7777U) | (((x) << 3) & 0x8888U)) + * + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * return SBOX_MIX(x); + */ +#define skinny64_inv_sbox(x) \ +do { \ + x = ~x; \ + x = (((x >> 3) & (x >> 2)) & 0x1111U) ^ x; \ + x = (((x << 1) & (x >> 2)) & 0x2222U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x4444U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x8888U) ^ x; \ + x = ~x; \ + x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \ +} while (0) + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-util.h b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-util.h new file mode 100644 index 0000000..e30166d --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/internal-util.h @@ -0,0 +1,702 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_UTIL_H +#define LW_INTERNAL_UTIL_H + +#include + +/* Figure out how to inline functions using this C compiler */ +#if defined(__STDC__) && __STDC_VERSION__ >= 199901L +#define STATIC_INLINE static inline +#elif defined(__GNUC__) || defined(__clang__) +#define STATIC_INLINE static __inline__ +#else +#define STATIC_INLINE static +#endif + +/* Try to figure out whether the CPU is little-endian or big-endian. + * May need to modify this to include new compiler-specific defines. + * Alternatively, define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ in your + * compiler flags when you compile this library */ +#if defined(__x86_64) || defined(__x86_64__) || \ + defined(__i386) || defined(__i386__) || \ + defined(__AVR__) || defined(__arm) || defined(__arm__) || \ + defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86) || \ + defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM_FP) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 1234) || \ + defined(__LITTLE_ENDIAN__) +#define LW_UTIL_LITTLE_ENDIAN 1 +#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 4321) || \ + defined(__BIG_ENDIAN__) +/* Big endian */ +#else +#error "Cannot determine the endianess of this platform" +#endif + +/* Helper macros to load and store values while converting endian-ness */ + +/* Load a big-endian 32-bit word from a byte buffer */ +#define be_load_word32(ptr) \ + ((((uint32_t)((ptr)[0])) << 24) | \ + (((uint32_t)((ptr)[1])) << 16) | \ + (((uint32_t)((ptr)[2])) << 8) | \ + ((uint32_t)((ptr)[3]))) + +/* Store a big-endian 32-bit word into a byte buffer */ +#define be_store_word32(ptr, x) \ + do { \ + uint32_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 24); \ + (ptr)[1] = (uint8_t)(_x >> 16); \ + (ptr)[2] = (uint8_t)(_x >> 8); \ + (ptr)[3] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 32-bit word from a byte buffer */ +#define le_load_word32(ptr) \ + ((((uint32_t)((ptr)[3])) << 24) | \ + (((uint32_t)((ptr)[2])) << 16) | \ + (((uint32_t)((ptr)[1])) << 8) | \ + ((uint32_t)((ptr)[0]))) + +/* Store a little-endian 32-bit word into a byte buffer */ +#define le_store_word32(ptr, x) \ + do { \ + uint32_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + (ptr)[2] = (uint8_t)(_x >> 16); \ + (ptr)[3] = (uint8_t)(_x >> 24); \ + } while (0) + +/* Load a big-endian 64-bit word from a byte buffer */ +#define be_load_word64(ptr) \ + ((((uint64_t)((ptr)[0])) << 56) | \ + (((uint64_t)((ptr)[1])) << 48) | \ + (((uint64_t)((ptr)[2])) << 40) | \ + (((uint64_t)((ptr)[3])) << 32) | \ + (((uint64_t)((ptr)[4])) << 24) | \ + (((uint64_t)((ptr)[5])) << 16) | \ + (((uint64_t)((ptr)[6])) << 8) | \ + ((uint64_t)((ptr)[7]))) + +/* Store a big-endian 64-bit word into a byte buffer */ +#define be_store_word64(ptr, x) \ + do { \ + uint64_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 56); \ + (ptr)[1] = (uint8_t)(_x >> 48); \ + (ptr)[2] = (uint8_t)(_x >> 40); \ + (ptr)[3] = (uint8_t)(_x >> 32); \ + (ptr)[4] = (uint8_t)(_x >> 24); \ + (ptr)[5] = (uint8_t)(_x >> 16); \ + (ptr)[6] = (uint8_t)(_x >> 8); \ + (ptr)[7] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 64-bit word from a byte buffer */ +#define le_load_word64(ptr) \ + ((((uint64_t)((ptr)[7])) << 56) | \ + (((uint64_t)((ptr)[6])) << 48) | \ + (((uint64_t)((ptr)[5])) << 40) | \ + (((uint64_t)((ptr)[4])) << 32) | \ + (((uint64_t)((ptr)[3])) << 24) | \ + (((uint64_t)((ptr)[2])) << 16) | \ + (((uint64_t)((ptr)[1])) << 8) | \ + ((uint64_t)((ptr)[0]))) + +/* Store a little-endian 64-bit word into a byte buffer */ +#define le_store_word64(ptr, x) \ + do { \ + uint64_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + (ptr)[2] = (uint8_t)(_x >> 16); \ + (ptr)[3] = (uint8_t)(_x >> 24); \ + (ptr)[4] = (uint8_t)(_x >> 32); \ + (ptr)[5] = (uint8_t)(_x >> 40); \ + (ptr)[6] = (uint8_t)(_x >> 48); \ + (ptr)[7] = (uint8_t)(_x >> 56); \ + } while (0) + +/* Load a big-endian 16-bit word from a byte buffer */ +#define be_load_word16(ptr) \ + ((((uint16_t)((ptr)[0])) << 8) | \ + ((uint16_t)((ptr)[1]))) + +/* Store a big-endian 16-bit word into a byte buffer */ +#define be_store_word16(ptr, x) \ + do { \ + uint16_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 8); \ + (ptr)[1] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 16-bit word from a byte buffer */ +#define le_load_word16(ptr) \ + ((((uint16_t)((ptr)[1])) << 8) | \ + ((uint16_t)((ptr)[0]))) + +/* Store a little-endian 16-bit word into a byte buffer */ +#define le_store_word16(ptr, x) \ + do { \ + uint16_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + } while (0) + +/* XOR a source byte buffer against a destination */ +#define lw_xor_block(dest, src, len) \ + do { \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest++ ^= *_src++; \ + --_len; \ + } \ + } while (0) + +/* XOR two source byte buffers and put the result in a destination buffer */ +#define lw_xor_block_2_src(dest, src1, src2, len) \ + do { \ + unsigned char *_dest = (dest); \ + const unsigned char *_src1 = (src1); \ + const unsigned char *_src2 = (src2); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest++ = *_src1++ ^ *_src2++; \ + --_len; \ + } \ + } while (0) + +/* XOR a source byte buffer against a destination and write to another + * destination at the same time */ +#define lw_xor_block_2_dest(dest2, dest, src, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest2++ = (*_dest++ ^= *_src++); \ + --_len; \ + } \ + } while (0) + +/* XOR two byte buffers and write to a destination which at the same + * time copying the contents of src2 to dest2 */ +#define lw_xor_block_copy_src(dest2, dest, src1, src2, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src1 = (src1); \ + const unsigned char *_src2 = (src2); \ + unsigned _len = (len); \ + while (_len > 0) { \ + unsigned char _temp = *_src2++; \ + *_dest2++ = _temp; \ + *_dest++ = *_src1++ ^ _temp; \ + --_len; \ + } \ + } while (0) + +/* XOR a source byte buffer against a destination and write to another + * destination at the same time. This version swaps the source value + * into the "dest" buffer */ +#define lw_xor_block_swap(dest2, dest, src, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + unsigned char _temp = *_src++; \ + *_dest2++ = *_dest ^ _temp; \ + *_dest++ = _temp; \ + --_len; \ + } \ + } while (0) + +/* Rotation functions need to be optimised for best performance on AVR. + * The most efficient rotations are where the number of bits is 1 or a + * multiple of 8, so we compose the efficient rotations to produce all + * other rotation counts of interest. */ + +#if defined(__AVR__) +#define LW_CRYPTO_ROTATE32_COMPOSED 1 +#else +#define LW_CRYPTO_ROTATE32_COMPOSED 0 +#endif + +/* Rotation macros for 32-bit arguments */ + +/* Generic left rotate */ +#define leftRotate(a, bits) \ + (__extension__ ({ \ + uint32_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (32 - (bits))); \ + })) + +/* Generic right rotate */ +#define rightRotate(a, bits) \ + (__extension__ ({ \ + uint32_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (32 - (bits))); \ + })) + +#if !LW_CRYPTO_ROTATE32_COMPOSED + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1(a) (leftRotate((a), 1)) +#define leftRotate2(a) (leftRotate((a), 2)) +#define leftRotate3(a) (leftRotate((a), 3)) +#define leftRotate4(a) (leftRotate((a), 4)) +#define leftRotate5(a) (leftRotate((a), 5)) +#define leftRotate6(a) (leftRotate((a), 6)) +#define leftRotate7(a) (leftRotate((a), 7)) +#define leftRotate8(a) (leftRotate((a), 8)) +#define leftRotate9(a) (leftRotate((a), 9)) +#define leftRotate10(a) (leftRotate((a), 10)) +#define leftRotate11(a) (leftRotate((a), 11)) +#define leftRotate12(a) (leftRotate((a), 12)) +#define leftRotate13(a) (leftRotate((a), 13)) +#define leftRotate14(a) (leftRotate((a), 14)) +#define leftRotate15(a) (leftRotate((a), 15)) +#define leftRotate16(a) (leftRotate((a), 16)) +#define leftRotate17(a) (leftRotate((a), 17)) +#define leftRotate18(a) (leftRotate((a), 18)) +#define leftRotate19(a) (leftRotate((a), 19)) +#define leftRotate20(a) (leftRotate((a), 20)) +#define leftRotate21(a) (leftRotate((a), 21)) +#define leftRotate22(a) (leftRotate((a), 22)) +#define leftRotate23(a) (leftRotate((a), 23)) +#define leftRotate24(a) (leftRotate((a), 24)) +#define leftRotate25(a) (leftRotate((a), 25)) +#define leftRotate26(a) (leftRotate((a), 26)) +#define leftRotate27(a) (leftRotate((a), 27)) +#define leftRotate28(a) (leftRotate((a), 28)) +#define leftRotate29(a) (leftRotate((a), 29)) +#define leftRotate30(a) (leftRotate((a), 30)) +#define leftRotate31(a) (leftRotate((a), 31)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1(a) (rightRotate((a), 1)) +#define rightRotate2(a) (rightRotate((a), 2)) +#define rightRotate3(a) (rightRotate((a), 3)) +#define rightRotate4(a) (rightRotate((a), 4)) +#define rightRotate5(a) (rightRotate((a), 5)) +#define rightRotate6(a) (rightRotate((a), 6)) +#define rightRotate7(a) (rightRotate((a), 7)) +#define rightRotate8(a) (rightRotate((a), 8)) +#define rightRotate9(a) (rightRotate((a), 9)) +#define rightRotate10(a) (rightRotate((a), 10)) +#define rightRotate11(a) (rightRotate((a), 11)) +#define rightRotate12(a) (rightRotate((a), 12)) +#define rightRotate13(a) (rightRotate((a), 13)) +#define rightRotate14(a) (rightRotate((a), 14)) +#define rightRotate15(a) (rightRotate((a), 15)) +#define rightRotate16(a) (rightRotate((a), 16)) +#define rightRotate17(a) (rightRotate((a), 17)) +#define rightRotate18(a) (rightRotate((a), 18)) +#define rightRotate19(a) (rightRotate((a), 19)) +#define rightRotate20(a) (rightRotate((a), 20)) +#define rightRotate21(a) (rightRotate((a), 21)) +#define rightRotate22(a) (rightRotate((a), 22)) +#define rightRotate23(a) (rightRotate((a), 23)) +#define rightRotate24(a) (rightRotate((a), 24)) +#define rightRotate25(a) (rightRotate((a), 25)) +#define rightRotate26(a) (rightRotate((a), 26)) +#define rightRotate27(a) (rightRotate((a), 27)) +#define rightRotate28(a) (rightRotate((a), 28)) +#define rightRotate29(a) (rightRotate((a), 29)) +#define rightRotate30(a) (rightRotate((a), 30)) +#define rightRotate31(a) (rightRotate((a), 31)) + +#else /* LW_CRYPTO_ROTATE32_COMPOSED */ + +/* Composed rotation macros where 1 and 8 are fast, but others are slow */ + +/* Left rotate by 1 */ +#define leftRotate1(a) (leftRotate((a), 1)) + +/* Left rotate by 2 */ +#define leftRotate2(a) (leftRotate(leftRotate((a), 1), 1)) + +/* Left rotate by 3 */ +#define leftRotate3(a) (leftRotate(leftRotate(leftRotate((a), 1), 1), 1)) + +/* Left rotate by 4 */ +#define leftRotate4(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 1), 1), 1), 1)) + +/* Left rotate by 5: Rotate left by 8, then right by 3 */ +#define leftRotate5(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 8), 1), 1), 1)) + +/* Left rotate by 6: Rotate left by 8, then right by 2 */ +#define leftRotate6(a) (rightRotate(rightRotate(leftRotate((a), 8), 1), 1)) + +/* Left rotate by 7: Rotate left by 8, then right by 1 */ +#define leftRotate7(a) (rightRotate(leftRotate((a), 8), 1)) + +/* Left rotate by 8 */ +#define leftRotate8(a) (leftRotate((a), 8)) + +/* Left rotate by 9: Rotate left by 8, then left by 1 */ +#define leftRotate9(a) (leftRotate(leftRotate((a), 8), 1)) + +/* Left rotate by 10: Rotate left by 8, then left by 2 */ +#define leftRotate10(a) (leftRotate(leftRotate(leftRotate((a), 8), 1), 1)) + +/* Left rotate by 11: Rotate left by 8, then left by 3 */ +#define leftRotate11(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 8), 1), 1), 1)) + +/* Left rotate by 12: Rotate left by 16, then right by 4 */ +#define leftRotate12(a) (rightRotate(rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1), 1)) + +/* Left rotate by 13: Rotate left by 16, then right by 3 */ +#define leftRotate13(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1)) + +/* Left rotate by 14: Rotate left by 16, then right by 2 */ +#define leftRotate14(a) (rightRotate(rightRotate(leftRotate((a), 16), 1), 1)) + +/* Left rotate by 15: Rotate left by 16, then right by 1 */ +#define leftRotate15(a) (rightRotate(leftRotate((a), 16), 1)) + +/* Left rotate by 16 */ +#define leftRotate16(a) (leftRotate((a), 16)) + +/* Left rotate by 17: Rotate left by 16, then left by 1 */ +#define leftRotate17(a) (leftRotate(leftRotate((a), 16), 1)) + +/* Left rotate by 18: Rotate left by 16, then left by 2 */ +#define leftRotate18(a) (leftRotate(leftRotate(leftRotate((a), 16), 1), 1)) + +/* Left rotate by 19: Rotate left by 16, then left by 3 */ +#define leftRotate19(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1)) + +/* Left rotate by 20: Rotate left by 16, then left by 4 */ +#define leftRotate20(a) (leftRotate(leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1), 1)) + +/* Left rotate by 21: Rotate left by 24, then right by 3 */ +#define leftRotate21(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 24), 1), 1), 1)) + +/* Left rotate by 22: Rotate left by 24, then right by 2 */ +#define leftRotate22(a) (rightRotate(rightRotate(leftRotate((a), 24), 1), 1)) + +/* Left rotate by 23: Rotate left by 24, then right by 1 */ +#define leftRotate23(a) (rightRotate(leftRotate((a), 24), 1)) + +/* Left rotate by 24 */ +#define leftRotate24(a) (leftRotate((a), 24)) + +/* Left rotate by 25: Rotate left by 24, then left by 1 */ +#define leftRotate25(a) (leftRotate(leftRotate((a), 24), 1)) + +/* Left rotate by 26: Rotate left by 24, then left by 2 */ +#define leftRotate26(a) (leftRotate(leftRotate(leftRotate((a), 24), 1), 1)) + +/* Left rotate by 27: Rotate left by 24, then left by 3 */ +#define leftRotate27(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 24), 1), 1), 1)) + +/* Left rotate by 28: Rotate right by 4 */ +#define leftRotate28(a) (rightRotate(rightRotate(rightRotate(rightRotate((a), 1), 1), 1), 1)) + +/* Left rotate by 29: Rotate right by 3 */ +#define leftRotate29(a) (rightRotate(rightRotate(rightRotate((a), 1), 1), 1)) + +/* Left rotate by 30: Rotate right by 2 */ +#define leftRotate30(a) (rightRotate(rightRotate((a), 1), 1)) + +/* Left rotate by 31: Rotate right by 1 */ +#define leftRotate31(a) (rightRotate((a), 1)) + +/* Define the 32-bit right rotations in terms of left rotations */ +#define rightRotate1(a) (leftRotate31((a))) +#define rightRotate2(a) (leftRotate30((a))) +#define rightRotate3(a) (leftRotate29((a))) +#define rightRotate4(a) (leftRotate28((a))) +#define rightRotate5(a) (leftRotate27((a))) +#define rightRotate6(a) (leftRotate26((a))) +#define rightRotate7(a) (leftRotate25((a))) +#define rightRotate8(a) (leftRotate24((a))) +#define rightRotate9(a) (leftRotate23((a))) +#define rightRotate10(a) (leftRotate22((a))) +#define rightRotate11(a) (leftRotate21((a))) +#define rightRotate12(a) (leftRotate20((a))) +#define rightRotate13(a) (leftRotate19((a))) +#define rightRotate14(a) (leftRotate18((a))) +#define rightRotate15(a) (leftRotate17((a))) +#define rightRotate16(a) (leftRotate16((a))) +#define rightRotate17(a) (leftRotate15((a))) +#define rightRotate18(a) (leftRotate14((a))) +#define rightRotate19(a) (leftRotate13((a))) +#define rightRotate20(a) (leftRotate12((a))) +#define rightRotate21(a) (leftRotate11((a))) +#define rightRotate22(a) (leftRotate10((a))) +#define rightRotate23(a) (leftRotate9((a))) +#define rightRotate24(a) (leftRotate8((a))) +#define rightRotate25(a) (leftRotate7((a))) +#define rightRotate26(a) (leftRotate6((a))) +#define rightRotate27(a) (leftRotate5((a))) +#define rightRotate28(a) (leftRotate4((a))) +#define rightRotate29(a) (leftRotate3((a))) +#define rightRotate30(a) (leftRotate2((a))) +#define rightRotate31(a) (leftRotate1((a))) + +#endif /* LW_CRYPTO_ROTATE32_COMPOSED */ + +/* Rotation macros for 64-bit arguments */ + +/* Generic left rotate */ +#define leftRotate_64(a, bits) \ + (__extension__ ({ \ + uint64_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (64 - (bits))); \ + })) + +/* Generic right rotate */ +#define rightRotate_64(a, bits) \ + (__extension__ ({ \ + uint64_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (64 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_64(a) (leftRotate_64((a), 1)) +#define leftRotate2_64(a) (leftRotate_64((a), 2)) +#define leftRotate3_64(a) (leftRotate_64((a), 3)) +#define leftRotate4_64(a) (leftRotate_64((a), 4)) +#define leftRotate5_64(a) (leftRotate_64((a), 5)) +#define leftRotate6_64(a) (leftRotate_64((a), 6)) +#define leftRotate7_64(a) (leftRotate_64((a), 7)) +#define leftRotate8_64(a) (leftRotate_64((a), 8)) +#define leftRotate9_64(a) (leftRotate_64((a), 9)) +#define leftRotate10_64(a) (leftRotate_64((a), 10)) +#define leftRotate11_64(a) (leftRotate_64((a), 11)) +#define leftRotate12_64(a) (leftRotate_64((a), 12)) +#define leftRotate13_64(a) (leftRotate_64((a), 13)) +#define leftRotate14_64(a) (leftRotate_64((a), 14)) +#define leftRotate15_64(a) (leftRotate_64((a), 15)) +#define leftRotate16_64(a) (leftRotate_64((a), 16)) +#define leftRotate17_64(a) (leftRotate_64((a), 17)) +#define leftRotate18_64(a) (leftRotate_64((a), 18)) +#define leftRotate19_64(a) (leftRotate_64((a), 19)) +#define leftRotate20_64(a) (leftRotate_64((a), 20)) +#define leftRotate21_64(a) (leftRotate_64((a), 21)) +#define leftRotate22_64(a) (leftRotate_64((a), 22)) +#define leftRotate23_64(a) (leftRotate_64((a), 23)) +#define leftRotate24_64(a) (leftRotate_64((a), 24)) +#define leftRotate25_64(a) (leftRotate_64((a), 25)) +#define leftRotate26_64(a) (leftRotate_64((a), 26)) +#define leftRotate27_64(a) (leftRotate_64((a), 27)) +#define leftRotate28_64(a) (leftRotate_64((a), 28)) +#define leftRotate29_64(a) (leftRotate_64((a), 29)) +#define leftRotate30_64(a) (leftRotate_64((a), 30)) +#define leftRotate31_64(a) (leftRotate_64((a), 31)) +#define leftRotate32_64(a) (leftRotate_64((a), 32)) +#define leftRotate33_64(a) (leftRotate_64((a), 33)) +#define leftRotate34_64(a) (leftRotate_64((a), 34)) +#define leftRotate35_64(a) (leftRotate_64((a), 35)) +#define leftRotate36_64(a) (leftRotate_64((a), 36)) +#define leftRotate37_64(a) (leftRotate_64((a), 37)) +#define leftRotate38_64(a) (leftRotate_64((a), 38)) +#define leftRotate39_64(a) (leftRotate_64((a), 39)) +#define leftRotate40_64(a) (leftRotate_64((a), 40)) +#define leftRotate41_64(a) (leftRotate_64((a), 41)) +#define leftRotate42_64(a) (leftRotate_64((a), 42)) +#define leftRotate43_64(a) (leftRotate_64((a), 43)) +#define leftRotate44_64(a) (leftRotate_64((a), 44)) +#define leftRotate45_64(a) (leftRotate_64((a), 45)) +#define leftRotate46_64(a) (leftRotate_64((a), 46)) +#define leftRotate47_64(a) (leftRotate_64((a), 47)) +#define leftRotate48_64(a) (leftRotate_64((a), 48)) +#define leftRotate49_64(a) (leftRotate_64((a), 49)) +#define leftRotate50_64(a) (leftRotate_64((a), 50)) +#define leftRotate51_64(a) (leftRotate_64((a), 51)) +#define leftRotate52_64(a) (leftRotate_64((a), 52)) +#define leftRotate53_64(a) (leftRotate_64((a), 53)) +#define leftRotate54_64(a) (leftRotate_64((a), 54)) +#define leftRotate55_64(a) (leftRotate_64((a), 55)) +#define leftRotate56_64(a) (leftRotate_64((a), 56)) +#define leftRotate57_64(a) (leftRotate_64((a), 57)) +#define leftRotate58_64(a) (leftRotate_64((a), 58)) +#define leftRotate59_64(a) (leftRotate_64((a), 59)) +#define leftRotate60_64(a) (leftRotate_64((a), 60)) +#define leftRotate61_64(a) (leftRotate_64((a), 61)) +#define leftRotate62_64(a) (leftRotate_64((a), 62)) +#define leftRotate63_64(a) (leftRotate_64((a), 63)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_64(a) (rightRotate_64((a), 1)) +#define rightRotate2_64(a) (rightRotate_64((a), 2)) +#define rightRotate3_64(a) (rightRotate_64((a), 3)) +#define rightRotate4_64(a) (rightRotate_64((a), 4)) +#define rightRotate5_64(a) (rightRotate_64((a), 5)) +#define rightRotate6_64(a) (rightRotate_64((a), 6)) +#define rightRotate7_64(a) (rightRotate_64((a), 7)) +#define rightRotate8_64(a) (rightRotate_64((a), 8)) +#define rightRotate9_64(a) (rightRotate_64((a), 9)) +#define rightRotate10_64(a) (rightRotate_64((a), 10)) +#define rightRotate11_64(a) (rightRotate_64((a), 11)) +#define rightRotate12_64(a) (rightRotate_64((a), 12)) +#define rightRotate13_64(a) (rightRotate_64((a), 13)) +#define rightRotate14_64(a) (rightRotate_64((a), 14)) +#define rightRotate15_64(a) (rightRotate_64((a), 15)) +#define rightRotate16_64(a) (rightRotate_64((a), 16)) +#define rightRotate17_64(a) (rightRotate_64((a), 17)) +#define rightRotate18_64(a) (rightRotate_64((a), 18)) +#define rightRotate19_64(a) (rightRotate_64((a), 19)) +#define rightRotate20_64(a) (rightRotate_64((a), 20)) +#define rightRotate21_64(a) (rightRotate_64((a), 21)) +#define rightRotate22_64(a) (rightRotate_64((a), 22)) +#define rightRotate23_64(a) (rightRotate_64((a), 23)) +#define rightRotate24_64(a) (rightRotate_64((a), 24)) +#define rightRotate25_64(a) (rightRotate_64((a), 25)) +#define rightRotate26_64(a) (rightRotate_64((a), 26)) +#define rightRotate27_64(a) (rightRotate_64((a), 27)) +#define rightRotate28_64(a) (rightRotate_64((a), 28)) +#define rightRotate29_64(a) (rightRotate_64((a), 29)) +#define rightRotate30_64(a) (rightRotate_64((a), 30)) +#define rightRotate31_64(a) (rightRotate_64((a), 31)) +#define rightRotate32_64(a) (rightRotate_64((a), 32)) +#define rightRotate33_64(a) (rightRotate_64((a), 33)) +#define rightRotate34_64(a) (rightRotate_64((a), 34)) +#define rightRotate35_64(a) (rightRotate_64((a), 35)) +#define rightRotate36_64(a) (rightRotate_64((a), 36)) +#define rightRotate37_64(a) (rightRotate_64((a), 37)) +#define rightRotate38_64(a) (rightRotate_64((a), 38)) +#define rightRotate39_64(a) (rightRotate_64((a), 39)) +#define rightRotate40_64(a) (rightRotate_64((a), 40)) +#define rightRotate41_64(a) (rightRotate_64((a), 41)) +#define rightRotate42_64(a) (rightRotate_64((a), 42)) +#define rightRotate43_64(a) (rightRotate_64((a), 43)) +#define rightRotate44_64(a) (rightRotate_64((a), 44)) +#define rightRotate45_64(a) (rightRotate_64((a), 45)) +#define rightRotate46_64(a) (rightRotate_64((a), 46)) +#define rightRotate47_64(a) (rightRotate_64((a), 47)) +#define rightRotate48_64(a) (rightRotate_64((a), 48)) +#define rightRotate49_64(a) (rightRotate_64((a), 49)) +#define rightRotate50_64(a) (rightRotate_64((a), 50)) +#define rightRotate51_64(a) (rightRotate_64((a), 51)) +#define rightRotate52_64(a) (rightRotate_64((a), 52)) +#define rightRotate53_64(a) (rightRotate_64((a), 53)) +#define rightRotate54_64(a) (rightRotate_64((a), 54)) +#define rightRotate55_64(a) (rightRotate_64((a), 55)) +#define rightRotate56_64(a) (rightRotate_64((a), 56)) +#define rightRotate57_64(a) (rightRotate_64((a), 57)) +#define rightRotate58_64(a) (rightRotate_64((a), 58)) +#define rightRotate59_64(a) (rightRotate_64((a), 59)) +#define rightRotate60_64(a) (rightRotate_64((a), 60)) +#define rightRotate61_64(a) (rightRotate_64((a), 61)) +#define rightRotate62_64(a) (rightRotate_64((a), 62)) +#define rightRotate63_64(a) (rightRotate_64((a), 63)) + +/* Rotate a 16-bit value left by a number of bits */ +#define leftRotate_16(a, bits) \ + (__extension__ ({ \ + uint16_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (16 - (bits))); \ + })) + +/* Rotate a 16-bit value right by a number of bits */ +#define rightRotate_16(a, bits) \ + (__extension__ ({ \ + uint16_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (16 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_16(a) (leftRotate_16((a), 1)) +#define leftRotate2_16(a) (leftRotate_16((a), 2)) +#define leftRotate3_16(a) (leftRotate_16((a), 3)) +#define leftRotate4_16(a) (leftRotate_16((a), 4)) +#define leftRotate5_16(a) (leftRotate_16((a), 5)) +#define leftRotate6_16(a) (leftRotate_16((a), 6)) +#define leftRotate7_16(a) (leftRotate_16((a), 7)) +#define leftRotate8_16(a) (leftRotate_16((a), 8)) +#define leftRotate9_16(a) (leftRotate_16((a), 9)) +#define leftRotate10_16(a) (leftRotate_16((a), 10)) +#define leftRotate11_16(a) (leftRotate_16((a), 11)) +#define leftRotate12_16(a) (leftRotate_16((a), 12)) +#define leftRotate13_16(a) (leftRotate_16((a), 13)) +#define leftRotate14_16(a) (leftRotate_16((a), 14)) +#define leftRotate15_16(a) (leftRotate_16((a), 15)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_16(a) (rightRotate_16((a), 1)) +#define rightRotate2_16(a) (rightRotate_16((a), 2)) +#define rightRotate3_16(a) (rightRotate_16((a), 3)) +#define rightRotate4_16(a) (rightRotate_16((a), 4)) +#define rightRotate5_16(a) (rightRotate_16((a), 5)) +#define rightRotate6_16(a) (rightRotate_16((a), 6)) +#define rightRotate7_16(a) (rightRotate_16((a), 7)) +#define rightRotate8_16(a) (rightRotate_16((a), 8)) +#define rightRotate9_16(a) (rightRotate_16((a), 9)) +#define rightRotate10_16(a) (rightRotate_16((a), 10)) +#define rightRotate11_16(a) (rightRotate_16((a), 11)) +#define rightRotate12_16(a) (rightRotate_16((a), 12)) +#define rightRotate13_16(a) (rightRotate_16((a), 13)) +#define rightRotate14_16(a) (rightRotate_16((a), 14)) +#define rightRotate15_16(a) (rightRotate_16((a), 15)) + +/* Rotate an 8-bit value left by a number of bits */ +#define leftRotate_8(a, bits) \ + (__extension__ ({ \ + uint8_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (8 - (bits))); \ + })) + +/* Rotate an 8-bit value right by a number of bits */ +#define rightRotate_8(a, bits) \ + (__extension__ ({ \ + uint8_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (8 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_8(a) (leftRotate_8((a), 1)) +#define leftRotate2_8(a) (leftRotate_8((a), 2)) +#define leftRotate3_8(a) (leftRotate_8((a), 3)) +#define leftRotate4_8(a) (leftRotate_8((a), 4)) +#define leftRotate5_8(a) (leftRotate_8((a), 5)) +#define leftRotate6_8(a) (leftRotate_8((a), 6)) +#define leftRotate7_8(a) (leftRotate_8((a), 7)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_8(a) (rightRotate_8((a), 1)) +#define rightRotate2_8(a) (rightRotate_8((a), 2)) +#define rightRotate3_8(a) (rightRotate_8((a), 3)) +#define rightRotate4_8(a) (rightRotate_8((a), 4)) +#define rightRotate5_8(a) (rightRotate_8((a), 5)) +#define rightRotate6_8(a) (rightRotate_8((a), 6)) +#define rightRotate7_8(a) (rightRotate_8((a), 7)) + +#endif diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/romulus.c b/romulus/Implementations/crypto_aead/romulusn1+/rhys/romulus.c new file mode 100644 index 0000000..bb19cc5 --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/romulus.c @@ -0,0 +1,1974 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "romulus.h" +#include "internal-skinny128.h" +#include "internal-util.h" +#include + +aead_cipher_t const romulus_n1_cipher = { + "Romulus-N1", + ROMULUS_KEY_SIZE, + ROMULUS1_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_n1_aead_encrypt, + romulus_n1_aead_decrypt +}; + +aead_cipher_t const romulus_n2_cipher = { + "Romulus-N2", + ROMULUS_KEY_SIZE, + ROMULUS2_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_n2_aead_encrypt, + romulus_n2_aead_decrypt +}; + +aead_cipher_t const romulus_n3_cipher = { + "Romulus-N3", + ROMULUS_KEY_SIZE, + ROMULUS3_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_n3_aead_encrypt, + romulus_n3_aead_decrypt +}; + +aead_cipher_t const romulus_m1_cipher = { + "Romulus-M1", + ROMULUS_KEY_SIZE, + ROMULUS1_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_m1_aead_encrypt, + romulus_m1_aead_decrypt +}; + +aead_cipher_t const romulus_m2_cipher = { + "Romulus-M2", + ROMULUS_KEY_SIZE, + ROMULUS2_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_m2_aead_encrypt, + romulus_m2_aead_decrypt +}; + +aead_cipher_t const romulus_m3_cipher = { + "Romulus-M3", + ROMULUS_KEY_SIZE, + ROMULUS3_NONCE_SIZE, + ROMULUS_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + romulus_m3_aead_encrypt, + romulus_m3_aead_decrypt +}; + +/** + * \brief Limit on the number of bytes of message or associated data (128Mb). + * + * Romulus-N1 and Romulus-M1 use a 56-bit block counter which allows for + * payloads well into the petabyte range. It is unlikely that an embedded + * device will have that much memory to store a contiguous packet! + * + * Romulus-N2 and Romulus-M2 use a 48-bit block counter but the upper + * 24 bits are difficult to modify in the key schedule. So we only + * update the low 24 bits and leave the high 24 bits fixed. + * + * Romulus-N3 and Romulus-M3 use a 24-bit block counter. + * + * For all algorithms, we limit the block counter to 2^23 so that the block + * counter can never exceed 2^24 - 1. + */ +#define ROMULUS_DATA_LIMIT \ + ((unsigned long long)((1ULL << 23) * SKINNY_128_BLOCK_SIZE)) + +/** + * \brief Initializes the key schedule for Romulus-N1 or Romulus-M1. + * + * \param ks Points to the key schedule to initialize. + * \param k Points to the 16 bytes of the key. + * \param npub Points to the 16 bytes of the nonce. May be NULL + * if the nonce will be updated on the fly. + */ +static void romulus1_init + (skinny_128_384_key_schedule_t *ks, + const unsigned char *k, const unsigned char *npub) +{ + unsigned char TK[48]; + TK[0] = 0x01; /* Initialize the 56-bit LFSR counter */ + memset(TK + 1, 0, 15); + if (npub) + memcpy(TK + 16, npub, 16); + else + memset(TK + 16, 0, 16); + memcpy(TK + 32, k, 16); + skinny_128_384_init(ks, TK); +} + +/** + * \brief Initializes the key schedule for Romulus-N2 or Romulus-M2. + * + * \param ks Points to the key schedule to initialize. + * \param k Points to the 16 bytes of the key. + * \param npub Points to the 12 bytes of the nonce. May be NULL + * if the nonce will be updated on the fly. + */ +static void romulus2_init + (skinny_128_384_key_schedule_t *ks, + const unsigned char *k, const unsigned char *npub) +{ + unsigned char TK[48]; + TK[0] = 0x01; /* Initialize the low 24 bits of the LFSR counter */ + if (npub) { + TK[1] = TK[2] = TK[3] = 0; + memcpy(TK + 4, npub, 12); + } else { + memset(TK + 1, 0, 15); + } + memcpy(TK + 16, k, 16); + TK[32] = 0x01; /* Initialize the high 24 bits of the LFSR counter */ + memset(TK + 33, 0, 15); + skinny_128_384_init(ks, TK); +} + +/** + * \brief Initializes the key schedule for Romulus-N3 or Romulus-M3. + * + * \param ks Points to the key schedule to initialize. + * \param k Points to the 16 bytes of the key. + * \param npub Points to the 12 bytes of the nonce. May be NULL + * if the nonce will be updated on the fly. + */ +static void romulus3_init + (skinny_128_256_key_schedule_t *ks, + const unsigned char *k, const unsigned char *npub) +{ + unsigned char TK[32]; + TK[0] = 0x01; /* Initialize the 24-bit LFSR counter */ + if (npub) { + TK[1] = TK[2] = TK[3] = 0; + memcpy(TK + 4, npub, 12); + } else { + memset(TK + 1, 0, 15); + } + memcpy(TK + 16, k, 16); + skinny_128_256_init(ks, TK); +} + +/** + * \brief Sets the domain separation value for Romulus-N1 and M1. + * + * \param ks The key schedule to set the domain separation value into. + * \param domain The domain separation value. + */ +#define romulus1_set_domain(ks, domain) ((ks)->TK1[7] = (domain)) + +/** + * \brief Sets the domain separation value for Romulus-N2 and M2. + * + * \param ks The key schedule to set the domain separation value into. + * \param domain The domain separation value. + */ +#define romulus2_set_domain(ks, domain) ((ks)->TK1[3] = (domain)) + +/** + * \brief Sets the domain separation value for Romulus-N3 and M3. + * + * \param ks The key schedule to set the domain separation value into. + * \param domain The domain separation value. + */ +#define romulus3_set_domain(ks, domain) ((ks)->TK1[3] = (domain)) + +/** + * \brief Updates the 56-bit LFSR block counter for Romulus-N1 and M1. + * + * \param TK1 Points to the TK1 part of the key schedule containing the LFSR. + */ +STATIC_INLINE void romulus1_update_counter(uint8_t TK1[16]) +{ + uint8_t mask = (uint8_t)(((int8_t)(TK1[6])) >> 7); + TK1[6] = (TK1[6] << 1) | (TK1[5] >> 7); + TK1[5] = (TK1[5] << 1) | (TK1[4] >> 7); + TK1[4] = (TK1[4] << 1) | (TK1[3] >> 7); + TK1[3] = (TK1[3] << 1) | (TK1[2] >> 7); + TK1[2] = (TK1[2] << 1) | (TK1[1] >> 7); + TK1[1] = (TK1[1] << 1) | (TK1[0] >> 7); + TK1[0] = (TK1[0] << 1) ^ (mask & 0x95); +} + +/** + * \brief Updates the 24-bit LFSR block counter for Romulus-N2 or M2. + * + * \param TK1 Points to the TK1 part of the key schedule containing the LFSR. + * + * For Romulus-N2 and Romulus-M2 this will only update the low 24 bits of + * the 48-bit LFSR. The high 24 bits are fixed due to ROMULUS_DATA_LIMIT. + */ +STATIC_INLINE void romulus2_update_counter(uint8_t TK1[16]) +{ + uint8_t mask = (uint8_t)(((int8_t)(TK1[2])) >> 7); + TK1[2] = (TK1[2] << 1) | (TK1[1] >> 7); + TK1[1] = (TK1[1] << 1) | (TK1[0] >> 7); + TK1[0] = (TK1[0] << 1) ^ (mask & 0x1B); +} + +/** + * \brief Updates the 24-bit LFSR block counter for Romulus-N3 or M3. + * + * \param TK1 Points to the TK1 part of the key schedule containing the LFSR. + */ +#define romulus3_update_counter(TK1) romulus2_update_counter((TK1)) + +/** + * \brief Process the asssociated data for Romulus-N1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void romulus_n1_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char temp; + + /* Handle the special case of no associated data */ + if (adlen == 0) { + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x1A); + skinny_128_384_encrypt_tk2(ks, S, S, npub); + return; + } + + /* Process all double blocks except the last */ + romulus1_set_domain(ks, 0x08); + while (adlen > 32) { + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + ad += 32; + adlen -= 32; + } + + /* Pad and process the left-over blocks */ + romulus1_update_counter(ks->TK1); + temp = (unsigned)adlen; + if (temp == 32) { + /* Left-over complete double block */ + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x18); + } else if (temp > 16) { + /* Left-over partial double block */ + unsigned char pad[16]; + temp -= 16; + lw_xor_block(S, ad, 16); + memcpy(pad, ad + 16, temp); + memset(pad + temp, 0, 15 - temp); + pad[15] = temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x1A); + } else if (temp == 16) { + /* Left-over complete single block */ + lw_xor_block(S, ad, temp); + romulus1_set_domain(ks, 0x18); + } else { + /* Left-over partial single block */ + lw_xor_block(S, ad, temp); + S[15] ^= temp; + romulus1_set_domain(ks, 0x1A); + } + skinny_128_384_encrypt_tk2(ks, S, S, npub); +} + +/** + * \brief Process the asssociated data for Romulus-N2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void romulus_n2_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char temp; + + /* Handle the special case of no associated data */ + if (adlen == 0) { + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x5A); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all double blocks except the last */ + romulus2_set_domain(ks, 0x48); + while (adlen > 28) { + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Pad and process the left-over blocks */ + romulus2_update_counter(ks->TK1); + temp = (unsigned)adlen; + if (temp == 28) { + /* Left-over complete double block */ + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x58); + } else if (temp > 16) { + /* Left-over partial double block */ + temp -= 16; + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp); + ks->TK1[15] = temp; + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x5A); + } else if (temp == 16) { + /* Left-over complete single block */ + lw_xor_block(S, ad, temp); + romulus2_set_domain(ks, 0x58); + } else { + /* Left-over partial single block */ + lw_xor_block(S, ad, temp); + S[15] ^= temp; + romulus2_set_domain(ks, 0x5A); + } + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Process the asssociated data for Romulus-N3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void romulus_n3_process_ad + (skinny_128_256_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char temp; + + /* Handle the special case of no associated data */ + if (adlen == 0) { + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x9A); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_256_encrypt(ks, S, S); + return; + } + + /* Process all double blocks except the last */ + romulus3_set_domain(ks, 0x88); + while (adlen > 28) { + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Pad and process the left-over blocks */ + romulus3_update_counter(ks->TK1); + temp = (unsigned)adlen; + if (temp == 28) { + /* Left-over complete double block */ + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x98); + } else if (temp > 16) { + /* Left-over partial double block */ + temp -= 16; + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp); + ks->TK1[15] = temp; + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x9A); + } else if (temp == 16) { + /* Left-over complete single block */ + lw_xor_block(S, ad, temp); + romulus3_set_domain(ks, 0x98); + } else { + /* Left-over partial single block */ + lw_xor_block(S, ad, temp); + S[15] ^= temp; + romulus3_set_domain(ks, 0x9A); + } + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Determine the domain separation value to use on the last + * block of the associated data processing. + * + * \param adlen Length of the associated data in bytes. + * \param mlen Length of the message in bytes. + * \param t Size of the second half of a double block; 12 or 16. + * + * \return The domain separation bits to use to finalize the last block. + */ +static uint8_t romulus_m_final_ad_domain + (unsigned long long adlen, unsigned long long mlen, unsigned t) +{ + uint8_t domain = 0; + unsigned split = 16U; + unsigned leftover; + + /* Determine which domain bits we need based on the length of the ad */ + if (adlen == 0) { + /* No associated data, so only 1 block with padding */ + domain ^= 0x02; + split = t; + } else { + /* Even or odd associated data length? */ + leftover = (unsigned)(adlen % (16U + t)); + if (leftover == 0) { + /* Even with a full double block at the end */ + domain ^= 0x08; + } else if (leftover < split) { + /* Odd with a partial single block at the end */ + domain ^= 0x02; + split = t; + } else if (leftover > split) { + /* Even with a partial double block at the end */ + domain ^= 0x0A; + } else { + /* Odd with a full single block at the end */ + split = t; + } + } + + /* Determine which domain bits we need based on the length of the message */ + if (mlen == 0) { + /* No message, so only 1 block with padding */ + domain ^= 0x01; + } else { + /* Even or odd message length? */ + leftover = (unsigned)(mlen % (16U + t)); + if (leftover == 0) { + /* Even with a full double block at the end */ + domain ^= 0x04; + } else if (leftover < split) { + /* Odd with a partial single block at the end */ + domain ^= 0x01; + } else if (leftover > split) { + /* Even with a partial double block at the end */ + domain ^= 0x05; + } + } + return domain; +} + +/** + * \brief Process the asssociated data for Romulus-M1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + * \param m Points to the message plaintext. + * \param mlen Length of the message plaintext. + */ +static void romulus_m1_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *m, unsigned long long mlen) +{ + unsigned char pad[16]; + uint8_t final_domain = 0x30; + unsigned temp; + + /* Determine the domain separator to use on the final block */ + final_domain ^= romulus_m_final_ad_domain(adlen, mlen, 16); + + /* Process all associated data double blocks except the last */ + romulus1_set_domain(ks, 0x28); + while (adlen > 32) { + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + ad += 32; + adlen -= 32; + } + + /* Process the last associated data double block */ + temp = (unsigned)adlen; + if (temp == 32) { + /* Last associated data double block is full */ + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + skinny_128_384_encrypt_tk2(ks, S, S, ad + 16); + romulus1_update_counter(ks->TK1); + } else if (temp > 16) { + /* Last associated data double block is partial */ + temp -= 16; + romulus1_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(pad, ad + 16, temp); + memset(pad + temp, 0, sizeof(pad) - temp - 1); + pad[sizeof(pad) - 1] = (unsigned char)temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + romulus1_update_counter(ks->TK1); + } else { + /* Last associated data block is single. Needs to be combined + * with the first block of the message payload */ + romulus1_set_domain(ks, 0x2C); + romulus1_update_counter(ks->TK1); + if (temp == 16) { + lw_xor_block(S, ad, 16); + } else { + lw_xor_block(S, ad, temp); + S[15] ^= (unsigned char)temp; + } + if (mlen > 16) { + skinny_128_384_encrypt_tk2(ks, S, S, m); + romulus1_update_counter(ks->TK1); + m += 16; + mlen -= 16; + } else if (mlen == 16) { + skinny_128_384_encrypt_tk2(ks, S, S, m); + m += 16; + mlen -= 16; + } else { + temp = (unsigned)mlen; + memcpy(pad, m, temp); + memset(pad + temp, 0, sizeof(pad) - temp - 1); + pad[sizeof(pad) - 1] = (unsigned char)temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + mlen = 0; + } + } + + /* Process all message double blocks except the last */ + romulus1_set_domain(ks, 0x2C); + while (mlen > 32) { + romulus1_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + skinny_128_384_encrypt_tk2(ks, S, S, m + 16); + romulus1_update_counter(ks->TK1); + m += 32; + mlen -= 32; + } + + /* Process the last message double block */ + temp = (unsigned)mlen; + if (temp == 32) { + /* Last message double block is full */ + romulus1_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + skinny_128_384_encrypt_tk2(ks, S, S, m + 16); + } else if (temp > 16) { + /* Last message double block is partial */ + temp -= 16; + romulus1_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(pad, m + 16, temp); + memset(pad + temp, 0, sizeof(pad) - temp - 1); + pad[sizeof(pad) - 1] = (unsigned char)temp; + skinny_128_384_encrypt_tk2(ks, S, S, pad); + } else if (temp == 16) { + /* Last message single block is full */ + lw_xor_block(S, m, 16); + } else if (temp > 0) { + /* Last message single block is partial */ + lw_xor_block(S, m, temp); + S[15] ^= (unsigned char)temp; + } + + /* Process the last partial block */ + romulus1_set_domain(ks, final_domain); + romulus1_update_counter(ks->TK1); + skinny_128_384_encrypt_tk2(ks, S, S, npub); +} + +/** + * \brief Process the asssociated data for Romulus-M2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + * \param m Points to the message plaintext. + * \param mlen Length of the message plaintext. + */ +static void romulus_m2_process_ad + (skinny_128_384_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *m, unsigned long long mlen) +{ + uint8_t final_domain = 0x70; + unsigned temp; + + /* Determine the domain separator to use on the final block */ + final_domain ^= romulus_m_final_ad_domain(adlen, mlen, 12); + + /* Process all associated data double blocks except the last */ + romulus2_set_domain(ks, 0x68); + while (adlen > 28) { + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Process the last associated data double block */ + temp = (unsigned)adlen; + if (temp == 28) { + /* Last associated data double block is full */ + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + } else if (temp > 16) { + /* Last associated data double block is partial */ + temp -= 16; + romulus2_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + } else { + /* Last associated data block is single. Needs to be combined + * with the first block of the message payload */ + romulus2_set_domain(ks, 0x6C); + romulus2_update_counter(ks->TK1); + if (temp == 16) { + lw_xor_block(S, ad, 16); + } else { + lw_xor_block(S, ad, temp); + S[15] ^= (unsigned char)temp; + } + if (mlen > 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + m += 12; + mlen -= 12; + } else if (mlen == 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_384_encrypt(ks, S, S); + m += 12; + mlen -= 12; + } else { + temp = (unsigned)mlen; + memcpy(ks->TK1 + 4, m, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_384_encrypt(ks, S, S); + mlen = 0; + } + } + + /* Process all message double blocks except the last */ + romulus2_set_domain(ks, 0x6C); + while (mlen > 28) { + romulus2_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_384_encrypt(ks, S, S); + romulus2_update_counter(ks->TK1); + m += 28; + mlen -= 28; + } + + /* Process the last message double block */ + temp = (unsigned)mlen; + if (temp == 28) { + /* Last message double block is full */ + romulus2_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_384_encrypt(ks, S, S); + } else if (temp > 16) { + /* Last message double block is partial */ + temp -= 16; + romulus2_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_384_encrypt(ks, S, S); + } else if (temp == 16) { + /* Last message single block is full */ + lw_xor_block(S, m, 16); + } else if (temp > 0) { + /* Last message single block is partial */ + lw_xor_block(S, m, temp); + S[15] ^= (unsigned char)temp; + } + + /* Process the last partial block */ + romulus2_set_domain(ks, final_domain); + romulus2_update_counter(ks->TK1); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Process the asssociated data for Romulus-M3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param npub Points to the nonce. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + * \param m Points to the message plaintext. + * \param mlen Length of the message plaintext. + */ +static void romulus_m3_process_ad + (skinny_128_256_key_schedule_t *ks, + unsigned char S[16], const unsigned char *npub, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *m, unsigned long long mlen) +{ + uint8_t final_domain = 0xB0; + unsigned temp; + + /* Determine the domain separator to use on the final block */ + final_domain ^= romulus_m_final_ad_domain(adlen, mlen, 12); + + /* Process all associated data double blocks except the last */ + romulus3_set_domain(ks, 0xA8); + while (adlen > 28) { + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + ad += 28; + adlen -= 28; + } + + /* Process the last associated data double block */ + temp = (unsigned)adlen; + if (temp == 28) { + /* Last associated data double block is full */ + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + } else if (temp > 16) { + /* Last associated data double block is partial */ + temp -= 16; + romulus3_update_counter(ks->TK1); + lw_xor_block(S, ad, 16); + memcpy(ks->TK1 + 4, ad + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + } else { + /* Last associated data block is single. Needs to be combined + * with the first block of the message payload */ + romulus3_set_domain(ks, 0xAC); + romulus3_update_counter(ks->TK1); + if (temp == 16) { + lw_xor_block(S, ad, 16); + } else { + lw_xor_block(S, ad, temp); + S[15] ^= (unsigned char)temp; + } + if (mlen > 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + m += 12; + mlen -= 12; + } else if (mlen == 12) { + memcpy(ks->TK1 + 4, m, 12); + skinny_128_256_encrypt(ks, S, S); + m += 12; + mlen -= 12; + } else { + temp = (unsigned)mlen; + memcpy(ks->TK1 + 4, m, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_256_encrypt(ks, S, S); + mlen = 0; + } + } + + /* Process all message double blocks except the last */ + romulus3_set_domain(ks, 0xAC); + while (mlen > 28) { + romulus3_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_256_encrypt(ks, S, S); + romulus3_update_counter(ks->TK1); + m += 28; + mlen -= 28; + } + + /* Process the last message double block */ + temp = (unsigned)mlen; + if (temp == 28) { + /* Last message double block is full */ + romulus3_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, 12); + skinny_128_256_encrypt(ks, S, S); + } else if (temp > 16) { + /* Last message double block is partial */ + temp -= 16; + romulus3_update_counter(ks->TK1); + lw_xor_block(S, m, 16); + memcpy(ks->TK1 + 4, m + 16, temp); + memset(ks->TK1 + 4 + temp, 0, 12 - temp - 1); + ks->TK1[15] = (unsigned char)temp; + skinny_128_256_encrypt(ks, S, S); + } else if (temp == 16) { + /* Last message single block is full */ + lw_xor_block(S, m, 16); + } else if (temp > 0) { + /* Last message single block is partial */ + lw_xor_block(S, m, temp); + S[15] ^= (unsigned char)temp; + } + + /* Process the last partial block */ + romulus3_set_domain(ks, final_domain); + romulus3_update_counter(ks->TK1); + memcpy(ks->TK1 + 4, npub, 12); + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Applies the Romulus rho function. + * + * \param S The rolling Romulus state. + * \param C Ciphertext message output block. + * \param M Plaintext message input block. + */ +STATIC_INLINE void romulus_rho + (unsigned char S[16], unsigned char C[16], const unsigned char M[16]) +{ + unsigned index; + for (index = 0; index < 16; ++index) { + unsigned char s = S[index]; + unsigned char m = M[index]; + S[index] ^= m; + C[index] = m ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + } +} + +/** + * \brief Applies the inverse of the Romulus rho function. + * + * \param S The rolling Romulus state. + * \param M Plaintext message output block. + * \param C Ciphertext message input block. + */ +STATIC_INLINE void romulus_rho_inverse + (unsigned char S[16], unsigned char M[16], const unsigned char C[16]) +{ + unsigned index; + for (index = 0; index < 16; ++index) { + unsigned char s = S[index]; + unsigned char m = C[index] ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + S[index] ^= m; + M[index] = m; + } +} + +/** + * \brief Applies the Romulus rho function to a short block. + * + * \param S The rolling Romulus state. + * \param C Ciphertext message output block. + * \param M Plaintext message input block. + * \param len Length of the short block, must be less than 16. + */ +STATIC_INLINE void romulus_rho_short + (unsigned char S[16], unsigned char C[16], + const unsigned char M[16], unsigned len) +{ + unsigned index; + for (index = 0; index < len; ++index) { + unsigned char s = S[index]; + unsigned char m = M[index]; + S[index] ^= m; + C[index] = m ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + } + S[15] ^= (unsigned char)len; /* Padding */ +} + +/** + * \brief Applies the inverse of the Romulus rho function to a short block. + * + * \param S The rolling Romulus state. + * \param M Plaintext message output block. + * \param C Ciphertext message input block. + * \param len Length of the short block, must be less than 16. + */ +STATIC_INLINE void romulus_rho_inverse_short + (unsigned char S[16], unsigned char M[16], + const unsigned char C[16], unsigned len) +{ + unsigned index; + for (index = 0; index < len; ++index) { + unsigned char s = S[index]; + unsigned char m = C[index] ^ ((s >> 1) ^ (s & 0x80) ^ (s << 7)); + S[index] ^= m; + M[index] = m; + } + S[15] ^= (unsigned char)len; /* Padding */ +} + +/** + * \brief Encrypts a plaintext message with Romulus-N1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n1_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no plaintext */ + if (mlen == 0) { + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x15); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus1_set_domain(ks, 0x04); + while (mlen > 16) { + romulus_rho(S, c, m); + romulus1_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus1_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_short(S, c, m, temp); + romulus1_set_domain(ks, 0x15); + } else { + romulus_rho(S, c, m); + romulus1_set_domain(ks, 0x14); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-N1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n1_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no ciphertext */ + if (mlen == 0) { + romulus1_update_counter(ks->TK1); + romulus1_set_domain(ks, 0x15); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus1_set_domain(ks, 0x04); + while (mlen > 16) { + romulus_rho_inverse(S, m, c); + romulus1_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus1_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_inverse_short(S, m, c, temp); + romulus1_set_domain(ks, 0x15); + } else { + romulus_rho_inverse(S, m, c); + romulus1_set_domain(ks, 0x14); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Encrypts a plaintext message with Romulus-N2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n2_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no plaintext */ + if (mlen == 0) { + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x55); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus2_set_domain(ks, 0x44); + while (mlen > 16) { + romulus_rho(S, c, m); + romulus2_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus2_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_short(S, c, m, temp); + romulus2_set_domain(ks, 0x55); + } else { + romulus_rho(S, c, m); + romulus2_set_domain(ks, 0x54); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-N2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n2_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no ciphertext */ + if (mlen == 0) { + romulus2_update_counter(ks->TK1); + romulus2_set_domain(ks, 0x55); + skinny_128_384_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus2_set_domain(ks, 0x44); + while (mlen > 16) { + romulus_rho_inverse(S, m, c); + romulus2_update_counter(ks->TK1); + skinny_128_384_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus2_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_inverse_short(S, m, c, temp); + romulus2_set_domain(ks, 0x55); + } else { + romulus_rho_inverse(S, m, c); + romulus2_set_domain(ks, 0x54); + } + skinny_128_384_encrypt(ks, S, S); +} + +/** + * \brief Encrypts a plaintext message with Romulus-N3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n3_encrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no plaintext */ + if (mlen == 0) { + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x95); + skinny_128_256_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus3_set_domain(ks, 0x84); + while (mlen > 16) { + romulus_rho(S, c, m); + romulus3_update_counter(ks->TK1); + skinny_128_256_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus3_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_short(S, c, m, temp); + romulus3_set_domain(ks, 0x95); + } else { + romulus_rho(S, c, m); + romulus3_set_domain(ks, 0x94); + } + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-N3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_n3_decrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + unsigned temp; + + /* Handle the special case of no ciphertext */ + if (mlen == 0) { + romulus3_update_counter(ks->TK1); + romulus3_set_domain(ks, 0x95); + skinny_128_256_encrypt(ks, S, S); + return; + } + + /* Process all blocks except the last */ + romulus3_set_domain(ks, 0x84); + while (mlen > 16) { + romulus_rho_inverse(S, m, c); + romulus3_update_counter(ks->TK1); + skinny_128_256_encrypt(ks, S, S); + c += 16; + m += 16; + mlen -= 16; + } + + /* Pad and process the last block */ + temp = (unsigned)mlen; + romulus3_update_counter(ks->TK1); + if (temp < 16) { + romulus_rho_inverse_short(S, m, c, temp); + romulus3_set_domain(ks, 0x95); + } else { + romulus_rho_inverse(S, m, c); + romulus3_set_domain(ks, 0x94); + } + skinny_128_256_encrypt(ks, S, S); +} + +/** + * \brief Encrypts a plaintext message with Romulus-M1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m1_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus1_set_domain(ks, 0x24); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho(S, c, m); + romulus1_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_short(S, c, m, (unsigned)mlen); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-M1. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m1_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus1_set_domain(ks, 0x24); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse(S, m, c); + romulus1_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse_short(S, m, c, (unsigned)mlen); +} + +/** + * \brief Encrypts a plaintext message with Romulus-M2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m2_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus2_set_domain(ks, 0x64); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho(S, c, m); + romulus2_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_short(S, c, m, (unsigned)mlen); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-M2. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m2_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus2_set_domain(ks, 0x64); + while (mlen > 16) { + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse(S, m, c); + romulus2_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_384_encrypt(ks, S, S); + romulus_rho_inverse_short(S, m, c, (unsigned)mlen); +} + +/** + * \brief Encrypts a plaintext message with Romulus-M3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the buffer containing the plaintext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m3_encrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *c, const unsigned char *m, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus3_set_domain(ks, 0xA4); + while (mlen > 16) { + skinny_128_256_encrypt(ks, S, S); + romulus_rho(S, c, m); + romulus3_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_256_encrypt(ks, S, S); + romulus_rho_short(S, c, m, (unsigned)mlen); +} + +/** + * \brief Decrypts a ciphertext message with Romulus-M3. + * + * \param ks Points to the key schedule. + * \param S The rolling Romulus state. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the buffer containing the ciphertext. + * \param mlen Length of the plaintext in bytes. + */ +static void romulus_m3_decrypt + (skinny_128_256_key_schedule_t *ks, unsigned char S[16], + unsigned char *m, const unsigned char *c, unsigned long long mlen) +{ + /* Nothing to do if the message is empty */ + if (!mlen) + return; + + /* Process all block except the last */ + romulus3_set_domain(ks, 0xA4); + while (mlen > 16) { + skinny_128_256_encrypt(ks, S, S); + romulus_rho_inverse(S, m, c); + romulus3_update_counter(ks->TK1); + c += 16; + m += 16; + mlen -= 16; + } + + /* Handle the last block */ + skinny_128_256_encrypt(ks, S, S); + romulus_rho_inverse_short(S, m, c, (unsigned)mlen); +} + +/** + * \brief Generates the authentication tag from the rolling Romulus state. + * + * \param T Buffer to receive the generated tag; can be the same as S. + * \param S The rolling Romulus state. + */ +STATIC_INLINE void romulus_generate_tag + (unsigned char T[16], const unsigned char S[16]) +{ + unsigned index; + for (index = 0; index < 16; ++index) { + unsigned char s = S[index]; + T[index] = (s >> 1) ^ (s & 0x80) ^ (s << 7); + } +} + +int romulus_n1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n1_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Encrypts the plaintext to produce the ciphertext */ + romulus_n1_encrypt(&ks, S, c, m, mlen); + + /* Generate the authentication tag */ + romulus_generate_tag(c + mlen, S); + return 0; +} + +int romulus_n1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n1_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext */ + clen -= ROMULUS_TAG_SIZE; + romulus_n1_decrypt(&ks, S, m, c, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_n2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n2_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Encrypts the plaintext to produce the ciphertext */ + romulus_n2_encrypt(&ks, S, c, m, mlen); + + /* Generate the authentication tag */ + romulus_generate_tag(c + mlen, S); + return 0; +} + +int romulus_n2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n2_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext */ + clen -= ROMULUS_TAG_SIZE; + romulus_n2_decrypt(&ks, S, m, c, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_n3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n3_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Encrypts the plaintext to produce the ciphertext */ + romulus_n3_encrypt(&ks, S, c, m, mlen); + + /* Generate the authentication tag */ + romulus_generate_tag(c + mlen, S); + return 0; +} + +int romulus_n3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_n3_process_ad(&ks, S, npub, ad, adlen); + + /* Re-initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext */ + clen -= ROMULUS_TAG_SIZE; + romulus_n3_decrypt(&ks, S, m, c, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_m1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data and the plaintext message */ + memset(S, 0, sizeof(S)); + romulus_m1_process_ad(&ks, S, npub, ad, adlen, m, mlen); + + /* Generate the authentication tag, which is also the initialization + * vector for the encryption portion of the packet processing */ + romulus_generate_tag(S, S); + memcpy(c + mlen, S, ROMULUS_TAG_SIZE); + + /* Re-initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Encrypt the plaintext to produce the ciphertext */ + romulus_m1_encrypt(&ks, S, c, m, mlen); + return 0; +} + +int romulus_m1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus1_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext, using the + * authentication tag as the initialization vector for decryption */ + clen -= ROMULUS_TAG_SIZE; + memcpy(S, c + clen, ROMULUS_TAG_SIZE); + romulus_m1_decrypt(&ks, S, m, c, clen); + + /* Re-initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus1_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_m1_process_ad(&ks, S, npub, ad, adlen, m, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_m2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data and the plaintext message */ + memset(S, 0, sizeof(S)); + romulus_m2_process_ad(&ks, S, npub, ad, adlen, m, mlen); + + /* Generate the authentication tag, which is also the initialization + * vector for the encryption portion of the packet processing */ + romulus_generate_tag(S, S); + memcpy(c + mlen, S, ROMULUS_TAG_SIZE); + + /* Re-initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Encrypt the plaintext to produce the ciphertext */ + romulus_m2_encrypt(&ks, S, c, m, mlen); + return 0; +} + +int romulus_m2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus2_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext, using the + * authentication tag as the initialization vector for decryption */ + clen -= ROMULUS_TAG_SIZE; + memcpy(S, c + clen, ROMULUS_TAG_SIZE); + romulus_m2_decrypt(&ks, S, m, c, clen); + + /* Re-initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus2_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_m2_process_ad(&ks, S, npub, ad, adlen, m, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} + +int romulus_m3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || mlen > ROMULUS_DATA_LIMIT) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data and the plaintext message */ + memset(S, 0, sizeof(S)); + romulus_m3_process_ad(&ks, S, npub, ad, adlen, m, mlen); + + /* Generate the authentication tag, which is also the initialization + * vector for the encryption portion of the packet processing */ + romulus_generate_tag(S, S); + memcpy(c + mlen, S, ROMULUS_TAG_SIZE); + + /* Re-initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Encrypt the plaintext to produce the ciphertext */ + romulus_m3_encrypt(&ks, S, c, m, mlen); + return 0; +} + +int romulus_m3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char S[16]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < ROMULUS_TAG_SIZE) + return -1; + *mlen = clen - ROMULUS_TAG_SIZE; + + /* Validate the length of the associated data and message */ + if (adlen > ROMULUS_DATA_LIMIT || + clen > (ROMULUS_DATA_LIMIT + ROMULUS_TAG_SIZE)) + return -2; + + /* Initialize the key schedule with the key and nonce */ + romulus3_init(&ks, k, npub); + + /* Decrypt the ciphertext to produce the plaintext, using the + * authentication tag as the initialization vector for decryption */ + clen -= ROMULUS_TAG_SIZE; + memcpy(S, c + clen, ROMULUS_TAG_SIZE); + romulus_m3_decrypt(&ks, S, m, c, clen); + + /* Re-initialize the key schedule with the key and no nonce. Associated + * data processing varies the nonce from block to block */ + romulus3_init(&ks, k, 0); + + /* Process the associated data */ + memset(S, 0, sizeof(S)); + romulus_m3_process_ad(&ks, S, npub, ad, adlen, m, clen); + + /* Check the authentication tag */ + romulus_generate_tag(S, S); + return aead_check_tag(m, clen, S, c + clen, ROMULUS_TAG_SIZE); +} diff --git a/romulus/Implementations/crypto_aead/romulusn1+/rhys/romulus.h b/romulus/Implementations/crypto_aead/romulusn1+/rhys/romulus.h new file mode 100644 index 0000000..e6da29d --- /dev/null +++ b/romulus/Implementations/crypto_aead/romulusn1+/rhys/romulus.h @@ -0,0 +1,476 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LWCRYPTO_ROMULUS_H +#define LWCRYPTO_ROMULUS_H + +#include "aead-common.h" + +/** + * \file romulus.h + * \brief Romulus authenticated encryption algorithm family. + * + * Romulus is a family of authenticated encryption algorithms that + * are built around the SKINNY-128 tweakable block cipher. There + * are six members in the family: + * + * \li Romulus-N1 has a 128-bit key, a 128-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. This is the + * primary member of the family. + * \li Romulus-N2 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li Romulus-N3 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-256 tweakable block cipher. + * \li Romulus-M1 has a 128-bit key, a 128-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li Romulus-M2 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li Romulus-M3 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-256 tweakable block cipher. + * + * The Romulus-M variants are resistant to nonce reuse as long as the + * combination of the associated data and plaintext is unique. If the + * same associated data and plaintext are reused under the same nonce, + * then the scheme will leak that the same plaintext has been sent for a + * second time but will not reveal the plaintext itself. + * + * References: https://romulusae.github.io/romulus/ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Size of the key for all Romulus family members. + */ +#define ROMULUS_KEY_SIZE 16 + +/** + * \brief Size of the authentication tag for all Romulus family members. + */ +#define ROMULUS_TAG_SIZE 16 + +/** + * \brief Size of the nonce for Romulus-N1 and Romulus-M1. + */ +#define ROMULUS1_NONCE_SIZE 16 + +/** + * \brief Size of the nonce for Romulus-N2 and Romulus-M2. + */ +#define ROMULUS2_NONCE_SIZE 12 + +/** + * \brief Size of the nonce for Romulus-N3 and Romulus-M3. + */ +#define ROMULUS3_NONCE_SIZE 12 + +/** + * \brief Meta-information block for the Romulus-N1 cipher. + */ +extern aead_cipher_t const romulus_n1_cipher; + +/** + * \brief Meta-information block for the Romulus-N2 cipher. + */ +extern aead_cipher_t const romulus_n2_cipher; + +/** + * \brief Meta-information block for the Romulus-N3 cipher. + */ +extern aead_cipher_t const romulus_n3_cipher; + +/** + * \brief Meta-information block for the Romulus-M1 cipher. + */ +extern aead_cipher_t const romulus_m1_cipher; + +/** + * \brief Meta-information block for the Romulus-M2 cipher. + */ +extern aead_cipher_t const romulus_m2_cipher; + +/** + * \brief Meta-information block for the Romulus-M3 cipher. + */ +extern aead_cipher_t const romulus_m3_cipher; + +/** + * \brief Encrypts and authenticates a packet with Romulus-N1. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_n1_aead_decrypt() + */ +int romulus_n1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-N1. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_n1_aead_encrypt() + */ +int romulus_n1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-N2. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_n2_aead_decrypt() + */ +int romulus_n2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-N2. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_n2_aead_encrypt() + */ +int romulus_n2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-N3. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_n3_aead_decrypt() + */ +int romulus_n3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-N3. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_n3_aead_encrypt() + */ +int romulus_n3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-M1. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_m1_aead_decrypt() + */ +int romulus_m1_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-M1. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_m1_aead_encrypt() + */ +int romulus_m1_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-M2. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_m2_aead_decrypt() + */ +int romulus_m2_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-M2. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_m2_aead_encrypt() + */ +int romulus_m2_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with Romulus-M3. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa romulus_m3_aead_decrypt() + */ +int romulus_m3_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with Romulus-M3. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa romulus_m3_aead_encrypt() + */ +int romulus_m3_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/aead-common.c b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/aead-common.c new file mode 100644 index 0000000..84fc53a --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/aead-common.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "aead-common.h" + +int aead_check_tag + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned size) +{ + /* Set "accum" to -1 if the tags match, or 0 if they don't match */ + int accum = 0; + while (size > 0) { + accum |= (*tag1++ ^ *tag2++); + --size; + } + accum = (accum - 1) >> 8; + + /* Destroy the plaintext if the tag match failed */ + while (plaintext_len > 0) { + *plaintext++ &= accum; + --plaintext_len; + } + + /* If "accum" is 0, return -1, otherwise return 0 */ + return ~accum; +} + +int aead_check_tag_precheck + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned size, int precheck) +{ + /* Set "accum" to -1 if the tags match, or 0 if they don't match */ + int accum = 0; + while (size > 0) { + accum |= (*tag1++ ^ *tag2++); + --size; + } + accum = ((accum - 1) >> 8) & precheck; + + /* Destroy the plaintext if the tag match failed */ + while (plaintext_len > 0) { + *plaintext++ &= accum; + --plaintext_len; + } + + /* If "accum" is 0, return -1, otherwise return 0 */ + return ~accum; +} diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/aead-common.h b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/aead-common.h new file mode 100644 index 0000000..2be95eb --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/aead-common.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LWCRYPTO_AEAD_COMMON_H +#define LWCRYPTO_AEAD_COMMON_H + +#include + +/** + * \file aead-common.h + * \brief Definitions that are common across AEAD schemes. + * + * AEAD stands for "Authenticated Encryption with Associated Data". + * It is a standard API pattern for securely encrypting and + * authenticating packets of data. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Encrypts and authenticates a packet with an AEAD scheme. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - normally not used by AEAD schemes. + * \param npub Points to the public nonce for the packet. + * \param k Points to the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + */ +typedef int (*aead_cipher_encrypt_t) + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with an AEAD scheme. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - normally not used by AEAD schemes. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet. + * \param k Points to the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + */ +typedef int (*aead_cipher_decrypt_t) + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Hashes a block of input data. + * + * \param out Buffer to receive the hash output. + * \param in Points to the input data to be hashed. + * \param inlen Length of the input data in bytes. + * + * \return Returns zero on success or -1 if there was an error in the + * parameters. + */ +typedef int (*aead_hash_t) + (unsigned char *out, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Initializes the state for a hashing operation. + * + * \param state Hash state to be initialized. + */ +typedef void (*aead_hash_init_t)(void *state); + +/** + * \brief Updates a hash state with more input data. + * + * \param state Hash state to be updated. + * \param in Points to the input data to be incorporated into the state. + * \param inlen Length of the input data to be incorporated into the state. + */ +typedef void (*aead_hash_update_t) + (void *state, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Returns the final hash value from a hashing operation. + * + * \param Hash state to be finalized. + * \param out Points to the output buffer to receive the hash value. + */ +typedef void (*aead_hash_finalize_t)(void *state, unsigned char *out); + +/** + * \brief Aborbs more input data into an XOF state. + * + * \param state XOF state to be updated. + * \param in Points to the input data to be absorbed into the state. + * \param inlen Length of the input data to be absorbed into the state. + * + * \sa ascon_xof_init(), ascon_xof_squeeze() + */ +typedef void (*aead_xof_absorb_t) + (void *state, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Squeezes output data from an XOF state. + * + * \param state XOF state to squeeze the output data from. + * \param out Points to the output buffer to receive the squeezed data. + * \param outlen Number of bytes of data to squeeze out of the state. + */ +typedef void (*aead_xof_squeeze_t) + (void *state, unsigned char *out, unsigned long long outlen); + +/** + * \brief No special AEAD features. + */ +#define AEAD_FLAG_NONE 0x0000 + +/** + * \brief The natural byte order of the AEAD cipher is little-endian. + * + * If this flag is not present, then the natural byte order of the + * AEAD cipher should be assumed to be big-endian. + * + * The natural byte order may be useful when formatting packet sequence + * numbers as nonces. The application needs to know whether the sequence + * number should be packed into the leading or trailing bytes of the nonce. + */ +#define AEAD_FLAG_LITTLE_ENDIAN 0x0001 + +/** + * \brief Meta-information about an AEAD cipher. + */ +typedef struct +{ + const char *name; /**< Name of the cipher */ + unsigned key_len; /**< Length of the key in bytes */ + unsigned nonce_len; /**< Length of the nonce in bytes */ + unsigned tag_len; /**< Length of the tag in bytes */ + unsigned flags; /**< Flags for extra features */ + aead_cipher_encrypt_t encrypt; /**< AEAD encryption function */ + aead_cipher_decrypt_t decrypt; /**< AEAD decryption function */ + +} aead_cipher_t; + +/** + * \brief Meta-information about a hash algorithm that is related to an AEAD. + * + * Regular hash algorithms should provide the "hash", "init", "update", + * and "finalize" functions. Extensible Output Functions (XOF's) should + * proivde the "hash", "init", "absorb", and "squeeze" functions. + */ +typedef struct +{ + const char *name; /**< Name of the hash algorithm */ + size_t state_size; /**< Size of the incremental state structure */ + unsigned hash_len; /**< Length of the hash in bytes */ + unsigned flags; /**< Flags for extra features */ + aead_hash_t hash; /**< All in one hashing function */ + aead_hash_init_t init; /**< Incremental hash/XOF init function */ + aead_hash_update_t update; /**< Incremental hash update function */ + aead_hash_finalize_t finalize; /**< Incremental hash finalize function */ + aead_xof_absorb_t absorb; /**< Incremental XOF absorb function */ + aead_xof_squeeze_t squeeze; /**< Incremental XOF squeeze function */ + +} aead_hash_algorithm_t; + +/** + * \brief Check an authentication tag in constant time. + * + * \param plaintext Points to the plaintext data. + * \param plaintext_len Length of the plaintext in bytes. + * \param tag1 First tag to compare. + * \param tag2 Second tag to compare. + * \param tag_len Length of the tags in bytes. + * + * \return Returns -1 if the tag check failed or 0 if the check succeeded. + * + * If the tag check fails, then the \a plaintext will also be zeroed to + * prevent it from being used accidentally by the application when the + * ciphertext was invalid. + */ +int aead_check_tag + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned tag_len); + +/** + * \brief Check an authentication tag in constant time with a previous check. + * + * \param plaintext Points to the plaintext data. + * \param plaintext_len Length of the plaintext in bytes. + * \param tag1 First tag to compare. + * \param tag2 Second tag to compare. + * \param tag_len Length of the tags in bytes. + * \param precheck Set to -1 if previous check succeeded or 0 if it failed. + * + * \return Returns -1 if the tag check failed or 0 if the check succeeded. + * + * If the tag check fails, then the \a plaintext will also be zeroed to + * prevent it from being used accidentally by the application when the + * ciphertext was invalid. + * + * This version can be used to incorporate other information about the + * correctness of the plaintext into the final result. + */ +int aead_check_tag_precheck + (unsigned char *plaintext, unsigned long long plaintext_len, + const unsigned char *tag1, const unsigned char *tag2, + unsigned tag_len, int precheck); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/api.h b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/api.h new file mode 100644 index 0000000..b2f8a36 --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/api.h @@ -0,0 +1,5 @@ +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 16 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/encrypt.c b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/encrypt.c new file mode 100644 index 0000000..97f599f --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/encrypt.c @@ -0,0 +1,25 @@ +#include "skinny-aead.h" + +int crypto_aead_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + return skinny_aead_m1_encrypt + (c, clen, m, mlen, ad, adlen, nsec, npub, k); +} + +int crypto_aead_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + return skinny_aead_m1_decrypt + (m, mlen, nsec, c, clen, ad, adlen, npub, k); +} diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128-avr.S b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128-avr.S new file mode 100644 index 0000000..0fafa4e --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128-avr.S @@ -0,0 +1,10099 @@ +#if defined(__AVR__) +#include +/* Automatically generated - do not edit */ + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_0, @object + .size table_0, 256 +table_0: + .byte 101 + .byte 76 + .byte 106 + .byte 66 + .byte 75 + .byte 99 + .byte 67 + .byte 107 + .byte 85 + .byte 117 + .byte 90 + .byte 122 + .byte 83 + .byte 115 + .byte 91 + .byte 123 + .byte 53 + .byte 140 + .byte 58 + .byte 129 + .byte 137 + .byte 51 + .byte 128 + .byte 59 + .byte 149 + .byte 37 + .byte 152 + .byte 42 + .byte 144 + .byte 35 + .byte 153 + .byte 43 + .byte 229 + .byte 204 + .byte 232 + .byte 193 + .byte 201 + .byte 224 + .byte 192 + .byte 233 + .byte 213 + .byte 245 + .byte 216 + .byte 248 + .byte 208 + .byte 240 + .byte 217 + .byte 249 + .byte 165 + .byte 28 + .byte 168 + .byte 18 + .byte 27 + .byte 160 + .byte 19 + .byte 169 + .byte 5 + .byte 181 + .byte 10 + .byte 184 + .byte 3 + .byte 176 + .byte 11 + .byte 185 + .byte 50 + .byte 136 + .byte 60 + .byte 133 + .byte 141 + .byte 52 + .byte 132 + .byte 61 + .byte 145 + .byte 34 + .byte 156 + .byte 44 + .byte 148 + .byte 36 + .byte 157 + .byte 45 + .byte 98 + .byte 74 + .byte 108 + .byte 69 + .byte 77 + .byte 100 + .byte 68 + .byte 109 + .byte 82 + .byte 114 + .byte 92 + .byte 124 + .byte 84 + .byte 116 + .byte 93 + .byte 125 + .byte 161 + .byte 26 + .byte 172 + .byte 21 + .byte 29 + .byte 164 + .byte 20 + .byte 173 + .byte 2 + .byte 177 + .byte 12 + .byte 188 + .byte 4 + .byte 180 + .byte 13 + .byte 189 + .byte 225 + .byte 200 + .byte 236 + .byte 197 + .byte 205 + .byte 228 + .byte 196 + .byte 237 + .byte 209 + .byte 241 + .byte 220 + .byte 252 + .byte 212 + .byte 244 + .byte 221 + .byte 253 + .byte 54 + .byte 142 + .byte 56 + .byte 130 + .byte 139 + .byte 48 + .byte 131 + .byte 57 + .byte 150 + .byte 38 + .byte 154 + .byte 40 + .byte 147 + .byte 32 + .byte 155 + .byte 41 + .byte 102 + .byte 78 + .byte 104 + .byte 65 + .byte 73 + .byte 96 + .byte 64 + .byte 105 + .byte 86 + .byte 118 + .byte 88 + .byte 120 + .byte 80 + .byte 112 + .byte 89 + .byte 121 + .byte 166 + .byte 30 + .byte 170 + .byte 17 + .byte 25 + .byte 163 + .byte 16 + .byte 171 + .byte 6 + .byte 182 + .byte 8 + .byte 186 + .byte 0 + .byte 179 + .byte 9 + .byte 187 + .byte 230 + .byte 206 + .byte 234 + .byte 194 + .byte 203 + .byte 227 + .byte 195 + .byte 235 + .byte 214 + .byte 246 + .byte 218 + .byte 250 + .byte 211 + .byte 243 + .byte 219 + .byte 251 + .byte 49 + .byte 138 + .byte 62 + .byte 134 + .byte 143 + .byte 55 + .byte 135 + .byte 63 + .byte 146 + .byte 33 + .byte 158 + .byte 46 + .byte 151 + .byte 39 + .byte 159 + .byte 47 + .byte 97 + .byte 72 + .byte 110 + .byte 70 + .byte 79 + .byte 103 + .byte 71 + .byte 111 + .byte 81 + .byte 113 + .byte 94 + .byte 126 + .byte 87 + .byte 119 + .byte 95 + .byte 127 + .byte 162 + .byte 24 + .byte 174 + .byte 22 + .byte 31 + .byte 167 + .byte 23 + .byte 175 + .byte 1 + .byte 178 + .byte 14 + .byte 190 + .byte 7 + .byte 183 + .byte 15 + .byte 191 + .byte 226 + .byte 202 + .byte 238 + .byte 198 + .byte 207 + .byte 231 + .byte 199 + .byte 239 + .byte 210 + .byte 242 + .byte 222 + .byte 254 + .byte 215 + .byte 247 + .byte 223 + .byte 255 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_1, @object + .size table_1, 256 +table_1: + .byte 172 + .byte 232 + .byte 104 + .byte 60 + .byte 108 + .byte 56 + .byte 168 + .byte 236 + .byte 170 + .byte 174 + .byte 58 + .byte 62 + .byte 106 + .byte 110 + .byte 234 + .byte 238 + .byte 166 + .byte 163 + .byte 51 + .byte 54 + .byte 102 + .byte 99 + .byte 227 + .byte 230 + .byte 225 + .byte 164 + .byte 97 + .byte 52 + .byte 49 + .byte 100 + .byte 161 + .byte 228 + .byte 141 + .byte 201 + .byte 73 + .byte 29 + .byte 77 + .byte 25 + .byte 137 + .byte 205 + .byte 139 + .byte 143 + .byte 27 + .byte 31 + .byte 75 + .byte 79 + .byte 203 + .byte 207 + .byte 133 + .byte 192 + .byte 64 + .byte 21 + .byte 69 + .byte 16 + .byte 128 + .byte 197 + .byte 130 + .byte 135 + .byte 18 + .byte 23 + .byte 66 + .byte 71 + .byte 194 + .byte 199 + .byte 150 + .byte 147 + .byte 3 + .byte 6 + .byte 86 + .byte 83 + .byte 211 + .byte 214 + .byte 209 + .byte 148 + .byte 81 + .byte 4 + .byte 1 + .byte 84 + .byte 145 + .byte 212 + .byte 156 + .byte 216 + .byte 88 + .byte 12 + .byte 92 + .byte 8 + .byte 152 + .byte 220 + .byte 154 + .byte 158 + .byte 10 + .byte 14 + .byte 90 + .byte 94 + .byte 218 + .byte 222 + .byte 149 + .byte 208 + .byte 80 + .byte 5 + .byte 85 + .byte 0 + .byte 144 + .byte 213 + .byte 146 + .byte 151 + .byte 2 + .byte 7 + .byte 82 + .byte 87 + .byte 210 + .byte 215 + .byte 157 + .byte 217 + .byte 89 + .byte 13 + .byte 93 + .byte 9 + .byte 153 + .byte 221 + .byte 155 + .byte 159 + .byte 11 + .byte 15 + .byte 91 + .byte 95 + .byte 219 + .byte 223 + .byte 22 + .byte 19 + .byte 131 + .byte 134 + .byte 70 + .byte 67 + .byte 195 + .byte 198 + .byte 65 + .byte 20 + .byte 193 + .byte 132 + .byte 17 + .byte 68 + .byte 129 + .byte 196 + .byte 28 + .byte 72 + .byte 200 + .byte 140 + .byte 76 + .byte 24 + .byte 136 + .byte 204 + .byte 26 + .byte 30 + .byte 138 + .byte 142 + .byte 74 + .byte 78 + .byte 202 + .byte 206 + .byte 53 + .byte 96 + .byte 224 + .byte 165 + .byte 101 + .byte 48 + .byte 160 + .byte 229 + .byte 50 + .byte 55 + .byte 162 + .byte 167 + .byte 98 + .byte 103 + .byte 226 + .byte 231 + .byte 61 + .byte 105 + .byte 233 + .byte 173 + .byte 109 + .byte 57 + .byte 169 + .byte 237 + .byte 59 + .byte 63 + .byte 171 + .byte 175 + .byte 107 + .byte 111 + .byte 235 + .byte 239 + .byte 38 + .byte 35 + .byte 179 + .byte 182 + .byte 118 + .byte 115 + .byte 243 + .byte 246 + .byte 113 + .byte 36 + .byte 241 + .byte 180 + .byte 33 + .byte 116 + .byte 177 + .byte 244 + .byte 44 + .byte 120 + .byte 248 + .byte 188 + .byte 124 + .byte 40 + .byte 184 + .byte 252 + .byte 42 + .byte 46 + .byte 186 + .byte 190 + .byte 122 + .byte 126 + .byte 250 + .byte 254 + .byte 37 + .byte 112 + .byte 240 + .byte 181 + .byte 117 + .byte 32 + .byte 176 + .byte 245 + .byte 34 + .byte 39 + .byte 178 + .byte 183 + .byte 114 + .byte 119 + .byte 242 + .byte 247 + .byte 45 + .byte 121 + .byte 249 + .byte 189 + .byte 125 + .byte 41 + .byte 185 + .byte 253 + .byte 43 + .byte 47 + .byte 187 + .byte 191 + .byte 123 + .byte 127 + .byte 251 + .byte 255 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_2, @object + .size table_2, 256 +table_2: + .byte 0 + .byte 2 + .byte 4 + .byte 6 + .byte 8 + .byte 10 + .byte 12 + .byte 14 + .byte 16 + .byte 18 + .byte 20 + .byte 22 + .byte 24 + .byte 26 + .byte 28 + .byte 30 + .byte 32 + .byte 34 + .byte 36 + .byte 38 + .byte 40 + .byte 42 + .byte 44 + .byte 46 + .byte 48 + .byte 50 + .byte 52 + .byte 54 + .byte 56 + .byte 58 + .byte 60 + .byte 62 + .byte 65 + .byte 67 + .byte 69 + .byte 71 + .byte 73 + .byte 75 + .byte 77 + .byte 79 + .byte 81 + .byte 83 + .byte 85 + .byte 87 + .byte 89 + .byte 91 + .byte 93 + .byte 95 + .byte 97 + .byte 99 + .byte 101 + .byte 103 + .byte 105 + .byte 107 + .byte 109 + .byte 111 + .byte 113 + .byte 115 + .byte 117 + .byte 119 + .byte 121 + .byte 123 + .byte 125 + .byte 127 + .byte 128 + .byte 130 + .byte 132 + .byte 134 + .byte 136 + .byte 138 + .byte 140 + .byte 142 + .byte 144 + .byte 146 + .byte 148 + .byte 150 + .byte 152 + .byte 154 + .byte 156 + .byte 158 + .byte 160 + .byte 162 + .byte 164 + .byte 166 + .byte 168 + .byte 170 + .byte 172 + .byte 174 + .byte 176 + .byte 178 + .byte 180 + .byte 182 + .byte 184 + .byte 186 + .byte 188 + .byte 190 + .byte 193 + .byte 195 + .byte 197 + .byte 199 + .byte 201 + .byte 203 + .byte 205 + .byte 207 + .byte 209 + .byte 211 + .byte 213 + .byte 215 + .byte 217 + .byte 219 + .byte 221 + .byte 223 + .byte 225 + .byte 227 + .byte 229 + .byte 231 + .byte 233 + .byte 235 + .byte 237 + .byte 239 + .byte 241 + .byte 243 + .byte 245 + .byte 247 + .byte 249 + .byte 251 + .byte 253 + .byte 255 + .byte 1 + .byte 3 + .byte 5 + .byte 7 + .byte 9 + .byte 11 + .byte 13 + .byte 15 + .byte 17 + .byte 19 + .byte 21 + .byte 23 + .byte 25 + .byte 27 + .byte 29 + .byte 31 + .byte 33 + .byte 35 + .byte 37 + .byte 39 + .byte 41 + .byte 43 + .byte 45 + .byte 47 + .byte 49 + .byte 51 + .byte 53 + .byte 55 + .byte 57 + .byte 59 + .byte 61 + .byte 63 + .byte 64 + .byte 66 + .byte 68 + .byte 70 + .byte 72 + .byte 74 + .byte 76 + .byte 78 + .byte 80 + .byte 82 + .byte 84 + .byte 86 + .byte 88 + .byte 90 + .byte 92 + .byte 94 + .byte 96 + .byte 98 + .byte 100 + .byte 102 + .byte 104 + .byte 106 + .byte 108 + .byte 110 + .byte 112 + .byte 114 + .byte 116 + .byte 118 + .byte 120 + .byte 122 + .byte 124 + .byte 126 + .byte 129 + .byte 131 + .byte 133 + .byte 135 + .byte 137 + .byte 139 + .byte 141 + .byte 143 + .byte 145 + .byte 147 + .byte 149 + .byte 151 + .byte 153 + .byte 155 + .byte 157 + .byte 159 + .byte 161 + .byte 163 + .byte 165 + .byte 167 + .byte 169 + .byte 171 + .byte 173 + .byte 175 + .byte 177 + .byte 179 + .byte 181 + .byte 183 + .byte 185 + .byte 187 + .byte 189 + .byte 191 + .byte 192 + .byte 194 + .byte 196 + .byte 198 + .byte 200 + .byte 202 + .byte 204 + .byte 206 + .byte 208 + .byte 210 + .byte 212 + .byte 214 + .byte 216 + .byte 218 + .byte 220 + .byte 222 + .byte 224 + .byte 226 + .byte 228 + .byte 230 + .byte 232 + .byte 234 + .byte 236 + .byte 238 + .byte 240 + .byte 242 + .byte 244 + .byte 246 + .byte 248 + .byte 250 + .byte 252 + .byte 254 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_3, @object + .size table_3, 256 +table_3: + .byte 0 + .byte 128 + .byte 1 + .byte 129 + .byte 2 + .byte 130 + .byte 3 + .byte 131 + .byte 4 + .byte 132 + .byte 5 + .byte 133 + .byte 6 + .byte 134 + .byte 7 + .byte 135 + .byte 8 + .byte 136 + .byte 9 + .byte 137 + .byte 10 + .byte 138 + .byte 11 + .byte 139 + .byte 12 + .byte 140 + .byte 13 + .byte 141 + .byte 14 + .byte 142 + .byte 15 + .byte 143 + .byte 16 + .byte 144 + .byte 17 + .byte 145 + .byte 18 + .byte 146 + .byte 19 + .byte 147 + .byte 20 + .byte 148 + .byte 21 + .byte 149 + .byte 22 + .byte 150 + .byte 23 + .byte 151 + .byte 24 + .byte 152 + .byte 25 + .byte 153 + .byte 26 + .byte 154 + .byte 27 + .byte 155 + .byte 28 + .byte 156 + .byte 29 + .byte 157 + .byte 30 + .byte 158 + .byte 31 + .byte 159 + .byte 160 + .byte 32 + .byte 161 + .byte 33 + .byte 162 + .byte 34 + .byte 163 + .byte 35 + .byte 164 + .byte 36 + .byte 165 + .byte 37 + .byte 166 + .byte 38 + .byte 167 + .byte 39 + .byte 168 + .byte 40 + .byte 169 + .byte 41 + .byte 170 + .byte 42 + .byte 171 + .byte 43 + .byte 172 + .byte 44 + .byte 173 + .byte 45 + .byte 174 + .byte 46 + .byte 175 + .byte 47 + .byte 176 + .byte 48 + .byte 177 + .byte 49 + .byte 178 + .byte 50 + .byte 179 + .byte 51 + .byte 180 + .byte 52 + .byte 181 + .byte 53 + .byte 182 + .byte 54 + .byte 183 + .byte 55 + .byte 184 + .byte 56 + .byte 185 + .byte 57 + .byte 186 + .byte 58 + .byte 187 + .byte 59 + .byte 188 + .byte 60 + .byte 189 + .byte 61 + .byte 190 + .byte 62 + .byte 191 + .byte 63 + .byte 64 + .byte 192 + .byte 65 + .byte 193 + .byte 66 + .byte 194 + .byte 67 + .byte 195 + .byte 68 + .byte 196 + .byte 69 + .byte 197 + .byte 70 + .byte 198 + .byte 71 + .byte 199 + .byte 72 + .byte 200 + .byte 73 + .byte 201 + .byte 74 + .byte 202 + .byte 75 + .byte 203 + .byte 76 + .byte 204 + .byte 77 + .byte 205 + .byte 78 + .byte 206 + .byte 79 + .byte 207 + .byte 80 + .byte 208 + .byte 81 + .byte 209 + .byte 82 + .byte 210 + .byte 83 + .byte 211 + .byte 84 + .byte 212 + .byte 85 + .byte 213 + .byte 86 + .byte 214 + .byte 87 + .byte 215 + .byte 88 + .byte 216 + .byte 89 + .byte 217 + .byte 90 + .byte 218 + .byte 91 + .byte 219 + .byte 92 + .byte 220 + .byte 93 + .byte 221 + .byte 94 + .byte 222 + .byte 95 + .byte 223 + .byte 224 + .byte 96 + .byte 225 + .byte 97 + .byte 226 + .byte 98 + .byte 227 + .byte 99 + .byte 228 + .byte 100 + .byte 229 + .byte 101 + .byte 230 + .byte 102 + .byte 231 + .byte 103 + .byte 232 + .byte 104 + .byte 233 + .byte 105 + .byte 234 + .byte 106 + .byte 235 + .byte 107 + .byte 236 + .byte 108 + .byte 237 + .byte 109 + .byte 238 + .byte 110 + .byte 239 + .byte 111 + .byte 240 + .byte 112 + .byte 241 + .byte 113 + .byte 242 + .byte 114 + .byte 243 + .byte 115 + .byte 244 + .byte 116 + .byte 245 + .byte 117 + .byte 246 + .byte 118 + .byte 247 + .byte 119 + .byte 248 + .byte 120 + .byte 249 + .byte 121 + .byte 250 + .byte 122 + .byte 251 + .byte 123 + .byte 252 + .byte 124 + .byte 253 + .byte 125 + .byte 254 + .byte 126 + .byte 255 + .byte 127 + + .section .progmem.data,"a",@progbits + .p2align 8 + .type table_4, @object + .size table_4, 112 +table_4: + .byte 1 + .byte 0 + .byte 3 + .byte 0 + .byte 7 + .byte 0 + .byte 15 + .byte 0 + .byte 15 + .byte 1 + .byte 14 + .byte 3 + .byte 13 + .byte 3 + .byte 11 + .byte 3 + .byte 7 + .byte 3 + .byte 15 + .byte 2 + .byte 14 + .byte 1 + .byte 12 + .byte 3 + .byte 9 + .byte 3 + .byte 3 + .byte 3 + .byte 7 + .byte 2 + .byte 14 + .byte 0 + .byte 13 + .byte 1 + .byte 10 + .byte 3 + .byte 5 + .byte 3 + .byte 11 + .byte 2 + .byte 6 + .byte 1 + .byte 12 + .byte 2 + .byte 8 + .byte 1 + .byte 0 + .byte 3 + .byte 1 + .byte 2 + .byte 2 + .byte 0 + .byte 5 + .byte 0 + .byte 11 + .byte 0 + .byte 7 + .byte 1 + .byte 14 + .byte 2 + .byte 12 + .byte 1 + .byte 8 + .byte 3 + .byte 1 + .byte 3 + .byte 3 + .byte 2 + .byte 6 + .byte 0 + .byte 13 + .byte 0 + .byte 11 + .byte 1 + .byte 6 + .byte 3 + .byte 13 + .byte 2 + .byte 10 + .byte 1 + .byte 4 + .byte 3 + .byte 9 + .byte 2 + .byte 2 + .byte 1 + .byte 4 + .byte 2 + .byte 8 + .byte 0 + .byte 1 + .byte 1 + .byte 2 + .byte 2 + .byte 4 + .byte 0 + .byte 9 + .byte 0 + .byte 3 + .byte 1 + .byte 6 + .byte 2 + .byte 12 + .byte 0 + .byte 9 + .byte 1 + .byte 2 + .byte 3 + .byte 5 + .byte 2 + .byte 10 + .byte 0 + + .text +.global skinny_128_384_init + .type skinny_128_384_init, @function +skinny_128_384_init: + movw r30,r24 + movw r26,r22 +.L__stack_usage = 2 + ldi r22,12 +1: + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + st Z+,r18 + st Z+,r19 + st Z+,r20 + st Z+,r21 + dec r22 + brne 1b + ret + .size skinny_128_384_init, .-skinny_128_384_init + + .text +.global skinny_128_384_encrypt + .type skinny_128_384_encrypt, @function +skinny_128_384_encrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,48 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 68 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + ldd r18,Z+4 + ldd r19,Z+5 + ldd r20,Z+6 + ldd r21,Z+7 + std Y+5,r18 + std Y+6,r19 + std Y+7,r20 + std Y+8,r21 + ldd r18,Z+8 + ldd r19,Z+9 + ldd r20,Z+10 + ldd r21,Z+11 + std Y+9,r18 + std Y+10,r19 + std Y+11,r20 + std Y+12,r21 + ldd r18,Z+12 + ldd r19,Z+13 + ldd r20,Z+14 + ldd r21,Z+15 + std Y+13,r18 + std Y+14,r19 + std Y+15,r20 + std Y+16,r21 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + ldd r18,Z+20 + ldd r19,Z+21 + ldd r20,Z+22 + ldd r21,Z+23 + std Y+21,r18 + std Y+22,r19 + std Y+23,r20 + std Y+24,r21 + ldd r18,Z+24 + ldd r19,Z+25 + ldd r20,Z+26 + ldd r21,Z+27 + std Y+25,r18 + std Y+26,r19 + std Y+27,r20 + std Y+28,r21 + ldd r18,Z+28 + ldd r19,Z+29 + ldd r20,Z+30 + ldd r21,Z+31 + std Y+29,r18 + std Y+30,r19 + std Y+31,r20 + std Y+32,r21 + ldd r18,Z+32 + ldd r19,Z+33 + ldd r20,Z+34 + ldd r21,Z+35 + std Y+33,r18 + std Y+34,r19 + std Y+35,r20 + std Y+36,r21 + ldd r18,Z+36 + ldd r19,Z+37 + ldd r20,Z+38 + ldd r21,Z+39 + std Y+37,r18 + std Y+38,r19 + std Y+39,r20 + std Y+40,r21 + ldd r18,Z+40 + ldd r19,Z+41 + ldd r20,Z+42 + ldd r21,Z+43 + std Y+41,r18 + std Y+42,r19 + std Y+43,r20 + std Y+44,r21 + ldd r18,Z+44 + ldd r19,Z+45 + ldd r20,Z+46 + ldd r21,Z+47 + std Y+45,r18 + std Y+46,r19 + std Y+47,r20 + std Y+48,r21 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r26,hh8(table_0) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + mov r26,r1 +114: + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + ldi r27,2 + eor r4,r27 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+33 + eor r18,r0 + ldd r0,Y+34 + eor r19,r0 + ldd r0,Y+35 + eor r20,r0 + ldd r0,Y+36 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldd r0,Y+37 + eor r22,r0 + ldd r0,Y+38 + eor r23,r0 + ldd r0,Y+39 + eor r2,r0 + ldd r0,Y+40 + eor r3,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + mov r0,r6 + mov r6,r4 + mov r4,r0 + mov r0,r7 + mov r7,r5 + mov r5,r0 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r13 + std Y+42,r17 + std Y+43,r12 + std Y+44,r25 + std Y+45,r14 + std Y+46,r16 + std Y+47,r24 + std Y+48,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + ldi r27,2 + eor r22,r27 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+41 + eor r8,r0 + ldd r0,Y+42 + eor r9,r0 + ldd r0,Y+43 + eor r10,r0 + ldd r0,Y+44 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldd r0,Y+45 + eor r18,r0 + ldd r0,Y+46 + eor r19,r0 + ldd r0,Y+47 + eor r20,r0 + ldd r0,Y+48 + eor r21,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + mov r0,r2 + mov r2,r22 + mov r22,r0 + mov r0,r3 + mov r3,r23 + mov r23,r0 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r13 + std Y+34,r17 + std Y+35,r12 + std Y+36,r25 + std Y+37,r14 + std Y+38,r16 + std Y+39,r24 + std Y+40,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + ldi r27,2 + eor r18,r27 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+33 + eor r4,r0 + ldd r0,Y+34 + eor r5,r0 + ldd r0,Y+35 + eor r6,r0 + ldd r0,Y+36 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldd r0,Y+37 + eor r8,r0 + ldd r0,Y+38 + eor r9,r0 + ldd r0,Y+39 + eor r10,r0 + ldd r0,Y+40 + eor r11,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + mov r0,r20 + mov r20,r18 + mov r18,r0 + mov r0,r21 + mov r21,r19 + mov r19,r0 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r13 + std Y+42,r17 + std Y+43,r12 + std Y+44,r25 + std Y+45,r14 + std Y+46,r16 + std Y+47,r24 + std Y+48,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + ldi r27,2 + eor r8,r27 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+41 + eor r22,r0 + ldd r0,Y+42 + eor r23,r0 + ldd r0,Y+43 + eor r2,r0 + ldd r0,Y+44 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldd r0,Y+45 + eor r4,r0 + ldd r0,Y+46 + eor r5,r0 + ldd r0,Y+47 + eor r6,r0 + ldd r0,Y+48 + eor r7,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + mov r0,r10 + mov r10,r8 + mov r8,r0 + mov r0,r11 + mov r11,r9 + mov r9,r0 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + cpi r26,80 + brne 5721f + rjmp 790f +5721: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r13 + std Y+34,r17 + std Y+35,r12 + std Y+36,r25 + std Y+37,r14 + std Y+38,r16 + std Y+39,r24 + std Y+40,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 114b +790: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+49 + ldd r27,Y+50 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,50 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_384_encrypt, .-skinny_128_384_encrypt + +.global skinny_128_384_encrypt_tk_full + .set skinny_128_384_encrypt_tk_full,skinny_128_384_encrypt + + .text +.global skinny_128_384_decrypt + .type skinny_128_384_decrypt, @function +skinny_128_384_decrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,48 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 68 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + ldd r22,Z+4 + ldd r23,Z+5 + ldd r2,Z+6 + ldd r3,Z+7 + ldd r4,Z+8 + ldd r5,Z+9 + ldd r6,Z+10 + ldd r7,Z+11 + ldd r8,Z+12 + ldd r9,Z+13 + ldd r10,Z+14 + ldd r11,Z+15 + std Y+1,r23 + std Y+2,r2 + std Y+3,r21 + std Y+4,r20 + std Y+5,r3 + std Y+6,r18 + std Y+7,r19 + std Y+8,r22 + std Y+9,r9 + std Y+10,r10 + std Y+11,r7 + std Y+12,r6 + std Y+13,r11 + std Y+14,r4 + std Y+15,r5 + std Y+16,r8 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + ldd r22,Z+20 + ldd r23,Z+21 + ldd r2,Z+22 + ldd r3,Z+23 + ldd r4,Z+24 + ldd r5,Z+25 + ldd r6,Z+26 + ldd r7,Z+27 + ldd r8,Z+28 + ldd r9,Z+29 + ldd r10,Z+30 + ldd r11,Z+31 + std Y+17,r23 + std Y+18,r2 + std Y+19,r21 + std Y+20,r20 + std Y+21,r3 + std Y+22,r18 + std Y+23,r19 + std Y+24,r22 + std Y+25,r9 + std Y+26,r10 + std Y+27,r7 + std Y+28,r6 + std Y+29,r11 + std Y+30,r4 + std Y+31,r5 + std Y+32,r8 + ldd r18,Z+32 + ldd r19,Z+33 + ldd r20,Z+34 + ldd r21,Z+35 + ldd r22,Z+36 + ldd r23,Z+37 + ldd r2,Z+38 + ldd r3,Z+39 + ldd r4,Z+40 + ldd r5,Z+41 + ldd r6,Z+42 + ldd r7,Z+43 + ldd r8,Z+44 + ldd r9,Z+45 + ldd r10,Z+46 + ldd r11,Z+47 + std Y+33,r23 + std Y+34,r2 + std Y+35,r21 + std Y+36,r20 + std Y+37,r3 + std Y+38,r18 + std Y+39,r19 + std Y+40,r22 + std Y+41,r9 + std Y+42,r10 + std Y+43,r7 + std Y+44,r6 + std Y+45,r11 + std Y+46,r4 + std Y+47,r5 + std Y+48,r8 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r26,hh8(table_2) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,20 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 +122: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 122b + std Y+17,r12 + std Y+18,r13 + std Y+19,r14 + std Y+20,r15 + std Y+21,r24 + std Y+22,r25 + std Y+23,r16 + std Y+24,r17 + ldi r26,20 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 +150: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 150b + std Y+25,r12 + std Y+26,r13 + std Y+27,r14 + std Y+28,r15 + std Y+29,r24 + std Y+30,r25 + std Y+31,r16 + std Y+32,r17 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r26,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,20 + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 +179: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 179b + std Y+33,r12 + std Y+34,r13 + std Y+35,r14 + std Y+36,r15 + std Y+37,r24 + std Y+38,r25 + std Y+39,r16 + std Y+40,r17 + ldi r26,20 + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 +207: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 207b + std Y+41,r12 + std Y+42,r13 + std Y+43,r14 + std Y+44,r15 + std Y+45,r24 + std Y+46,r25 + std Y+47,r16 + std Y+48,r17 + ldi r26,80 +227: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r14 + std Y+34,r12 + std Y+35,r24 + std Y+36,r17 + std Y+37,r16 + std Y+38,r15 + std Y+39,r25 + std Y+40,r13 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + mov r0,r8 + mov r8,r10 + mov r10,r0 + mov r0,r9 + mov r9,r11 + mov r11,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+41 + eor r22,r0 + ldd r0,Y+42 + eor r23,r0 + ldd r0,Y+43 + eor r2,r0 + ldd r0,Y+44 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldd r0,Y+45 + eor r4,r0 + ldd r0,Y+46 + eor r5,r0 + ldd r0,Y+47 + eor r6,r0 + ldd r0,Y+48 + eor r7,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + ldi r27,2 + eor r8,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r14 + std Y+42,r12 + std Y+43,r24 + std Y+44,r17 + std Y+45,r16 + std Y+46,r15 + std Y+47,r25 + std Y+48,r13 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + mov r0,r18 + mov r18,r20 + mov r20,r0 + mov r0,r19 + mov r19,r21 + mov r21,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+33 + eor r4,r0 + ldd r0,Y+34 + eor r5,r0 + ldd r0,Y+35 + eor r6,r0 + ldd r0,Y+36 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldd r0,Y+37 + eor r8,r0 + ldd r0,Y+38 + eor r9,r0 + ldd r0,Y+39 + eor r10,r0 + ldd r0,Y+40 + eor r11,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + ldi r27,2 + eor r18,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+33 + ldd r13,Y+34 + ldd r14,Y+35 + ldd r15,Y+36 + ldd r24,Y+37 + ldd r25,Y+38 + ldd r16,Y+39 + ldd r17,Y+40 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+33,r14 + std Y+34,r12 + std Y+35,r24 + std Y+36,r17 + std Y+37,r16 + std Y+38,r15 + std Y+39,r25 + std Y+40,r13 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + mov r0,r22 + mov r22,r2 + mov r2,r0 + mov r0,r23 + mov r23,r3 + mov r3,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+41 + eor r8,r0 + ldd r0,Y+42 + eor r9,r0 + ldd r0,Y+43 + eor r10,r0 + ldd r0,Y+44 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldd r0,Y+45 + eor r18,r0 + ldd r0,Y+46 + eor r19,r0 + ldd r0,Y+47 + eor r20,r0 + ldd r0,Y+48 + eor r21,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + ldi r27,2 + eor r22,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+41 + ldd r13,Y+42 + ldd r14,Y+43 + ldd r15,Y+44 + ldd r24,Y+45 + ldd r25,Y+46 + ldd r16,Y+47 + ldd r17,Y+48 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+41,r14 + std Y+42,r12 + std Y+43,r24 + std Y+44,r17 + std Y+45,r16 + std Y+46,r15 + std Y+47,r25 + std Y+48,r13 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + mov r0,r4 + mov r4,r6 + mov r6,r0 + mov r0,r5 + mov r5,r7 + mov r7,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+33 + eor r18,r0 + ldd r0,Y+34 + eor r19,r0 + ldd r0,Y+35 + eor r20,r0 + ldd r0,Y+36 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldd r0,Y+37 + eor r22,r0 + ldd r0,Y+38 + eor r23,r0 + ldd r0,Y+39 + eor r2,r0 + ldd r0,Y+40 + eor r3,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + ldi r27,2 + eor r4,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + cp r26,r1 + breq 903f + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 227b +903: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+49 + ldd r27,Y+50 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,50 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_384_decrypt, .-skinny_128_384_decrypt + + .text +.global skinny_128_256_init + .type skinny_128_256_init, @function +skinny_128_256_init: + movw r30,r24 + movw r26,r22 +.L__stack_usage = 2 + ldi r22,8 +1: + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + st Z+,r18 + st Z+,r19 + st Z+,r20 + st Z+,r21 + dec r22 + brne 1b + ret + .size skinny_128_256_init, .-skinny_128_256_init + + .text +.global skinny_128_256_encrypt + .type skinny_128_256_encrypt, @function +skinny_128_256_encrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,32 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 52 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + ldd r18,Z+4 + ldd r19,Z+5 + ldd r20,Z+6 + ldd r21,Z+7 + std Y+5,r18 + std Y+6,r19 + std Y+7,r20 + std Y+8,r21 + ldd r18,Z+8 + ldd r19,Z+9 + ldd r20,Z+10 + ldd r21,Z+11 + std Y+9,r18 + std Y+10,r19 + std Y+11,r20 + std Y+12,r21 + ldd r18,Z+12 + ldd r19,Z+13 + ldd r20,Z+14 + ldd r21,Z+15 + std Y+13,r18 + std Y+14,r19 + std Y+15,r20 + std Y+16,r21 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + ldd r18,Z+20 + ldd r19,Z+21 + ldd r20,Z+22 + ldd r21,Z+23 + std Y+21,r18 + std Y+22,r19 + std Y+23,r20 + std Y+24,r21 + ldd r18,Z+24 + ldd r19,Z+25 + ldd r20,Z+26 + ldd r21,Z+27 + std Y+25,r18 + std Y+26,r19 + std Y+27,r20 + std Y+28,r21 + ldd r18,Z+28 + ldd r19,Z+29 + ldd r20,Z+30 + ldd r21,Z+31 + std Y+29,r18 + std Y+30,r19 + std Y+31,r20 + std Y+32,r21 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r26,hh8(table_0) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + mov r26,r1 +82: + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + ldi r27,2 + eor r4,r27 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + mov r0,r6 + mov r6,r4 + mov r4,r0 + mov r0,r7 + mov r7,r5 + mov r5,r0 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + inc r26 + ldi r27,2 + eor r22,r27 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + mov r0,r2 + mov r2,r22 + mov r22,r0 + mov r0,r3 + mov r3,r23 + mov r23,r0 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + inc r26 + ldi r27,2 + eor r18,r27 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + mov r0,r20 + mov r20,r18 + mov r18,r0 + mov r0,r21 + mov r21,r19 + mov r19,r0 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r13 + std Y+10,r17 + std Y+11,r12 + std Y+12,r25 + std Y+13,r14 + std Y+14,r16 + std Y+15,r24 + std Y+16,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r13 + std Y+26,r17 + std Y+27,r12 + std Y+28,r25 + std Y+29,r14 + std Y+30,r16 + std Y+31,r24 + std Y+32,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + inc r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + inc r26 + ldi r27,2 + eor r8,r27 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + mov r0,r10 + mov r10,r8 + mov r8,r0 + mov r0,r11 + mov r11,r9 + mov r9,r0 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + cpi r26,96 + breq 594f + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r13 + std Y+2,r17 + std Y+3,r12 + std Y+4,r25 + std Y+5,r14 + std Y+6,r16 + std Y+7,r24 + std Y+8,r15 + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r27,hh8(table_2) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r13 + std Y+18,r17 + std Y+19,r12 + std Y+20,r25 + std Y+21,r14 + std Y+22,r16 + std Y+23,r24 + std Y+24,r15 + ldi r30,lo8(table_0) + ldi r31,hi8(table_0) +#if defined(RAMPZ) + ldi r27,hh8(table_0) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 82b +594: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+33 + ldd r27,Y+34 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,34 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_256_encrypt, .-skinny_128_256_encrypt + +.global skinny_128_256_encrypt_tk_full + .set skinny_128_256_encrypt_tk_full,skinny_128_256_encrypt + + .text +.global skinny_128_256_decrypt + .type skinny_128_256_decrypt, @function +skinny_128_256_decrypt: + push r28 + push r29 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + push r23 + push r22 + movw r30,r24 + movw r26,r20 + in r28,0x3d + in r29,0x3e + sbiw r28,32 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 +.L__stack_usage = 52 + ld r18,Z + ldd r19,Z+1 + ldd r20,Z+2 + ldd r21,Z+3 + ldd r22,Z+4 + ldd r23,Z+5 + ldd r2,Z+6 + ldd r3,Z+7 + ldd r4,Z+8 + ldd r5,Z+9 + ldd r6,Z+10 + ldd r7,Z+11 + ldd r8,Z+12 + ldd r9,Z+13 + ldd r10,Z+14 + ldd r11,Z+15 + std Y+1,r18 + std Y+2,r19 + std Y+3,r20 + std Y+4,r21 + std Y+5,r22 + std Y+6,r23 + std Y+7,r2 + std Y+8,r3 + std Y+9,r4 + std Y+10,r5 + std Y+11,r6 + std Y+12,r7 + std Y+13,r8 + std Y+14,r9 + std Y+15,r10 + std Y+16,r11 + ldd r18,Z+16 + ldd r19,Z+17 + ldd r20,Z+18 + ldd r21,Z+19 + ldd r22,Z+20 + ldd r23,Z+21 + ldd r2,Z+22 + ldd r3,Z+23 + ldd r4,Z+24 + ldd r5,Z+25 + ldd r6,Z+26 + ldd r7,Z+27 + ldd r8,Z+28 + ldd r9,Z+29 + ldd r10,Z+30 + ldd r11,Z+31 + std Y+17,r18 + std Y+18,r19 + std Y+19,r20 + std Y+20,r21 + std Y+21,r22 + std Y+22,r23 + std Y+23,r2 + std Y+24,r3 + std Y+25,r4 + std Y+26,r5 + std Y+27,r6 + std Y+28,r7 + std Y+29,r8 + std Y+30,r9 + std Y+31,r10 + std Y+32,r11 + ld r18,X+ + ld r19,X+ + ld r20,X+ + ld r21,X+ + ld r22,X+ + ld r23,X+ + ld r2,X+ + ld r3,X+ + ld r4,X+ + ld r5,X+ + ld r6,X+ + ld r7,X+ + ld r8,X+ + ld r9,X+ + ld r10,X+ + ld r11,X+ + ldi r30,lo8(table_2) + ldi r31,hi8(table_2) +#if defined(RAMPZ) + ldi r26,hh8(table_2) + in r0,_SFR_IO_ADDR(RAMPZ) + push r0 + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,24 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 +90: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 90b + std Y+17,r12 + std Y+18,r13 + std Y+19,r14 + std Y+20,r15 + std Y+21,r24 + std Y+22,r25 + std Y+23,r16 + std Y+24,r17 + ldi r26,24 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 +118: + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + dec r26 + brne 118b + std Y+25,r12 + std Y+26,r13 + std Y+27,r14 + std Y+28,r15 + std Y+29,r24 + std Y+30,r25 + std Y+31,r16 + std Y+32,r17 + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r26,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r26 +#endif + ldi r26,96 +139: + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + eor r18,r8 + eor r19,r9 + eor r20,r10 + eor r21,r11 + eor r8,r22 + eor r9,r23 + eor r10,r2 + eor r11,r3 + eor r4,r8 + eor r5,r9 + eor r6,r10 + eor r7,r11 + mov r0,r4 + mov r4,r5 + mov r5,r6 + mov r6,r7 + mov r7,r0 + mov r0,r8 + mov r8,r10 + mov r10,r0 + mov r0,r9 + mov r9,r11 + mov r11,r0 + mov r0,r21 + mov r21,r20 + mov r20,r19 + mov r19,r18 + mov r18,r0 + ldd r0,Y+9 + eor r22,r0 + ldd r0,Y+10 + eor r23,r0 + ldd r0,Y+11 + eor r2,r0 + ldd r0,Y+12 + eor r3,r0 + ldd r0,Y+25 + eor r22,r0 + ldd r0,Y+26 + eor r23,r0 + ldd r0,Y+27 + eor r2,r0 + ldd r0,Y+28 + eor r3,r0 + ldd r0,Y+13 + eor r4,r0 + ldd r0,Y+14 + eor r5,r0 + ldd r0,Y+15 + eor r6,r0 + ldd r0,Y+16 + eor r7,r0 + ldd r0,Y+29 + eor r4,r0 + ldd r0,Y+30 + eor r5,r0 + ldd r0,Y+31 + eor r6,r0 + ldd r0,Y+32 + eor r7,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + ldi r27,2 + eor r8,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + eor r22,r18 + eor r23,r19 + eor r2,r20 + eor r3,r21 + eor r18,r4 + eor r19,r5 + eor r20,r6 + eor r21,r7 + eor r8,r18 + eor r9,r19 + eor r10,r20 + eor r11,r21 + mov r0,r8 + mov r8,r9 + mov r9,r10 + mov r10,r11 + mov r11,r0 + mov r0,r18 + mov r18,r20 + mov r20,r0 + mov r0,r19 + mov r19,r21 + mov r21,r0 + mov r0,r3 + mov r3,r2 + mov r2,r23 + mov r23,r22 + mov r22,r0 + ldd r0,Y+1 + eor r4,r0 + ldd r0,Y+2 + eor r5,r0 + ldd r0,Y+3 + eor r6,r0 + ldd r0,Y+4 + eor r7,r0 + ldd r0,Y+17 + eor r4,r0 + ldd r0,Y+18 + eor r5,r0 + ldd r0,Y+19 + eor r6,r0 + ldd r0,Y+20 + eor r7,r0 + ldd r0,Y+5 + eor r8,r0 + ldd r0,Y+6 + eor r9,r0 + ldd r0,Y+7 + eor r10,r0 + ldd r0,Y+8 + eor r11,r0 + ldd r0,Y+21 + eor r8,r0 + ldd r0,Y+22 + eor r9,r0 + ldd r0,Y+23 + eor r10,r0 + ldd r0,Y+24 + eor r11,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r4,r27 + ldi r27,2 + eor r18,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+1 + ldd r13,Y+2 + ldd r14,Y+3 + ldd r15,Y+4 + ldd r24,Y+5 + ldd r25,Y+6 + ldd r16,Y+7 + ldd r17,Y+8 + std Y+1,r14 + std Y+2,r12 + std Y+3,r24 + std Y+4,r17 + std Y+5,r16 + std Y+6,r15 + std Y+7,r25 + std Y+8,r13 + ldd r12,Y+17 + ldd r13,Y+18 + ldd r14,Y+19 + ldd r15,Y+20 + ldd r24,Y+21 + ldd r25,Y+22 + ldd r16,Y+23 + ldd r17,Y+24 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+17,r14 + std Y+18,r12 + std Y+19,r24 + std Y+20,r17 + std Y+21,r16 + std Y+22,r15 + std Y+23,r25 + std Y+24,r13 + eor r4,r22 + eor r5,r23 + eor r6,r2 + eor r7,r3 + eor r22,r8 + eor r23,r9 + eor r2,r10 + eor r3,r11 + eor r18,r22 + eor r19,r23 + eor r20,r2 + eor r21,r3 + mov r0,r18 + mov r18,r19 + mov r19,r20 + mov r20,r21 + mov r21,r0 + mov r0,r22 + mov r22,r2 + mov r2,r0 + mov r0,r23 + mov r23,r3 + mov r3,r0 + mov r0,r7 + mov r7,r6 + mov r6,r5 + mov r5,r4 + mov r4,r0 + ldd r0,Y+9 + eor r8,r0 + ldd r0,Y+10 + eor r9,r0 + ldd r0,Y+11 + eor r10,r0 + ldd r0,Y+12 + eor r11,r0 + ldd r0,Y+25 + eor r8,r0 + ldd r0,Y+26 + eor r9,r0 + ldd r0,Y+27 + eor r10,r0 + ldd r0,Y+28 + eor r11,r0 + ldd r0,Y+13 + eor r18,r0 + ldd r0,Y+14 + eor r19,r0 + ldd r0,Y+15 + eor r20,r0 + ldd r0,Y+16 + eor r21,r0 + ldd r0,Y+29 + eor r18,r0 + ldd r0,Y+30 + eor r19,r0 + ldd r0,Y+31 + eor r20,r0 + ldd r0,Y+32 + eor r21,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r8,r27 + ldi r27,2 + eor r22,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + ldd r12,Y+9 + ldd r13,Y+10 + ldd r14,Y+11 + ldd r15,Y+12 + ldd r24,Y+13 + ldd r25,Y+14 + ldd r16,Y+15 + ldd r17,Y+16 + std Y+9,r14 + std Y+10,r12 + std Y+11,r24 + std Y+12,r17 + std Y+13,r16 + std Y+14,r15 + std Y+15,r25 + std Y+16,r13 + ldd r12,Y+25 + ldd r13,Y+26 + ldd r14,Y+27 + ldd r15,Y+28 + ldd r24,Y+29 + ldd r25,Y+30 + ldd r16,Y+31 + ldd r17,Y+32 + mov r30,r12 +#if defined(RAMPZ) + elpm r12,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r12,Z +#elif defined(__AVR_TINY__) + ld r12,Z +#else + lpm + mov r12,r0 +#endif + mov r30,r13 +#if defined(RAMPZ) + elpm r13,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r13,Z +#elif defined(__AVR_TINY__) + ld r13,Z +#else + lpm + mov r13,r0 +#endif + mov r30,r14 +#if defined(RAMPZ) + elpm r14,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r14,Z +#elif defined(__AVR_TINY__) + ld r14,Z +#else + lpm + mov r14,r0 +#endif + mov r30,r15 +#if defined(RAMPZ) + elpm r15,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r15,Z +#elif defined(__AVR_TINY__) + ld r15,Z +#else + lpm + mov r15,r0 +#endif + mov r30,r24 +#if defined(RAMPZ) + elpm r24,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r24,Z +#elif defined(__AVR_TINY__) + ld r24,Z +#else + lpm + mov r24,r0 +#endif + mov r30,r25 +#if defined(RAMPZ) + elpm r25,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r25,Z +#elif defined(__AVR_TINY__) + ld r25,Z +#else + lpm + mov r25,r0 +#endif + mov r30,r16 +#if defined(RAMPZ) + elpm r16,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r16,Z +#elif defined(__AVR_TINY__) + ld r16,Z +#else + lpm + mov r16,r0 +#endif + mov r30,r17 +#if defined(RAMPZ) + elpm r17,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r17,Z +#elif defined(__AVR_TINY__) + ld r17,Z +#else + lpm + mov r17,r0 +#endif + std Y+25,r14 + std Y+26,r12 + std Y+27,r24 + std Y+28,r17 + std Y+29,r16 + std Y+30,r15 + std Y+31,r25 + std Y+32,r13 + eor r8,r4 + eor r9,r5 + eor r10,r6 + eor r11,r7 + eor r4,r18 + eor r5,r19 + eor r6,r20 + eor r7,r21 + eor r22,r4 + eor r23,r5 + eor r2,r6 + eor r3,r7 + mov r0,r22 + mov r22,r23 + mov r23,r2 + mov r2,r3 + mov r3,r0 + mov r0,r4 + mov r4,r6 + mov r6,r0 + mov r0,r5 + mov r5,r7 + mov r7,r0 + mov r0,r11 + mov r11,r10 + mov r10,r9 + mov r9,r8 + mov r8,r0 + ldd r0,Y+1 + eor r18,r0 + ldd r0,Y+2 + eor r19,r0 + ldd r0,Y+3 + eor r20,r0 + ldd r0,Y+4 + eor r21,r0 + ldd r0,Y+17 + eor r18,r0 + ldd r0,Y+18 + eor r19,r0 + ldd r0,Y+19 + eor r20,r0 + ldd r0,Y+20 + eor r21,r0 + ldd r0,Y+5 + eor r22,r0 + ldd r0,Y+6 + eor r23,r0 + ldd r0,Y+7 + eor r2,r0 + ldd r0,Y+8 + eor r3,r0 + ldd r0,Y+21 + eor r22,r0 + ldd r0,Y+22 + eor r23,r0 + ldd r0,Y+23 + eor r2,r0 + ldd r0,Y+24 + eor r3,r0 + ldi r30,lo8(table_4) + ldi r31,hi8(table_4) +#if defined(RAMPZ) + ldi r24,hh8(table_4) + out _SFR_IO_ADDR(RAMPZ),r24 +#endif + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r22,r27 + dec r26 + mov r30,r26 +#if defined(RAMPZ) + elpm r27,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r27,Z +#elif defined(__AVR_TINY__) + ld r27,Z +#else + lpm + mov r27,r0 +#endif + eor r18,r27 + ldi r27,2 + eor r4,r27 + ldi r30,lo8(table_1) + ldi r31,hi8(table_1) +#if defined(RAMPZ) + ldi r27,hh8(table_1) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + mov r30,r18 +#if defined(RAMPZ) + elpm r18,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r18,Z +#elif defined(__AVR_TINY__) + ld r18,Z +#else + lpm + mov r18,r0 +#endif + mov r30,r19 +#if defined(RAMPZ) + elpm r19,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r19,Z +#elif defined(__AVR_TINY__) + ld r19,Z +#else + lpm + mov r19,r0 +#endif + mov r30,r20 +#if defined(RAMPZ) + elpm r20,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r20,Z +#elif defined(__AVR_TINY__) + ld r20,Z +#else + lpm + mov r20,r0 +#endif + mov r30,r21 +#if defined(RAMPZ) + elpm r21,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r21,Z +#elif defined(__AVR_TINY__) + ld r21,Z +#else + lpm + mov r21,r0 +#endif + mov r30,r22 +#if defined(RAMPZ) + elpm r22,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r22,Z +#elif defined(__AVR_TINY__) + ld r22,Z +#else + lpm + mov r22,r0 +#endif + mov r30,r23 +#if defined(RAMPZ) + elpm r23,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r23,Z +#elif defined(__AVR_TINY__) + ld r23,Z +#else + lpm + mov r23,r0 +#endif + mov r30,r2 +#if defined(RAMPZ) + elpm r2,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r2,Z +#elif defined(__AVR_TINY__) + ld r2,Z +#else + lpm + mov r2,r0 +#endif + mov r30,r3 +#if defined(RAMPZ) + elpm r3,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r3,Z +#elif defined(__AVR_TINY__) + ld r3,Z +#else + lpm + mov r3,r0 +#endif + mov r30,r4 +#if defined(RAMPZ) + elpm r4,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r4,Z +#elif defined(__AVR_TINY__) + ld r4,Z +#else + lpm + mov r4,r0 +#endif + mov r30,r5 +#if defined(RAMPZ) + elpm r5,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r5,Z +#elif defined(__AVR_TINY__) + ld r5,Z +#else + lpm + mov r5,r0 +#endif + mov r30,r6 +#if defined(RAMPZ) + elpm r6,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r6,Z +#elif defined(__AVR_TINY__) + ld r6,Z +#else + lpm + mov r6,r0 +#endif + mov r30,r7 +#if defined(RAMPZ) + elpm r7,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r7,Z +#elif defined(__AVR_TINY__) + ld r7,Z +#else + lpm + mov r7,r0 +#endif + mov r30,r8 +#if defined(RAMPZ) + elpm r8,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r8,Z +#elif defined(__AVR_TINY__) + ld r8,Z +#else + lpm + mov r8,r0 +#endif + mov r30,r9 +#if defined(RAMPZ) + elpm r9,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r9,Z +#elif defined(__AVR_TINY__) + ld r9,Z +#else + lpm + mov r9,r0 +#endif + mov r30,r10 +#if defined(RAMPZ) + elpm r10,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r10,Z +#elif defined(__AVR_TINY__) + ld r10,Z +#else + lpm + mov r10,r0 +#endif + mov r30,r11 +#if defined(RAMPZ) + elpm r11,Z +#elif defined(__AVR_HAVE_LPMX__) + lpm r11,Z +#elif defined(__AVR_TINY__) + ld r11,Z +#else + lpm + mov r11,r0 +#endif + cp r26,r1 + breq 651f + ldi r30,lo8(table_3) + ldi r31,hi8(table_3) +#if defined(RAMPZ) + ldi r27,hh8(table_3) + out _SFR_IO_ADDR(RAMPZ),r27 +#endif + rjmp 139b +651: +#if defined(RAMPZ) + pop r0 + out _SFR_IO_ADDR(RAMPZ),r0 +#endif + ldd r26,Y+33 + ldd r27,Y+34 + st X+,r18 + st X+,r19 + st X+,r20 + st X+,r21 + st X+,r22 + st X+,r23 + st X+,r2 + st X+,r3 + st X+,r4 + st X+,r5 + st X+,r6 + st X+,r7 + st X+,r8 + st X+,r9 + st X+,r10 + st X+,r11 + adiw r28,34 + in r0,0x3f + cli + out 0x3e,r29 + out 0x3f,r0 + out 0x3d,r28 + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r29 + pop r28 + ret + .size skinny_128_256_decrypt, .-skinny_128_256_decrypt + +#endif diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128.c b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128.c new file mode 100644 index 0000000..cb1fbda --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128.c @@ -0,0 +1,801 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "internal-skinny128.h" +#include "internal-skinnyutil.h" +#include "internal-util.h" +#include + +#if !defined(__AVR__) + +STATIC_INLINE void skinny128_fast_forward_tk(uint32_t *tk) +{ + /* This function is used to fast-forward the TK1 tweak value + * to the value at the end of the key schedule for decryption. + * + * The tweak permutation repeats every 16 rounds, so SKINNY-128-256 + * with 48 rounds does not need any fast forwarding applied. + * SKINNY-128-128 with 40 rounds and SKINNY-128-384 with 56 rounds + * are equivalent to applying the permutation 8 times: + * + * PT*8 = [5, 6, 3, 2, 7, 0, 1, 4, 13, 14, 11, 10, 15, 8, 9, 12] + */ + uint32_t row0 = tk[0]; + uint32_t row1 = tk[1]; + uint32_t row2 = tk[2]; + uint32_t row3 = tk[3]; + tk[0] = ((row1 >> 8) & 0x0000FFFFU) | + ((row0 >> 8) & 0x00FF0000U) | + ((row0 << 8) & 0xFF000000U); + tk[1] = ((row1 >> 24) & 0x000000FFU) | + ((row0 << 8) & 0x00FFFF00U) | + ((row1 << 24) & 0xFF000000U); + tk[2] = ((row3 >> 8) & 0x0000FFFFU) | + ((row2 >> 8) & 0x00FF0000U) | + ((row2 << 8) & 0xFF000000U); + tk[3] = ((row3 >> 24) & 0x000000FFU) | + ((row2 << 8) & 0x00FFFF00U) | + ((row3 << 24) & 0xFF000000U); +} + +void skinny_128_384_init + (skinny_128_384_key_schedule_t *ks, const unsigned char key[48]) +{ +#if !SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint32_t *schedule; + unsigned round; + uint8_t rc; +#endif + +#if SKINNY_128_SMALL_SCHEDULE + /* Copy the input key as-is when using the small key schedule version */ + memcpy(ks->TK1, key, sizeof(ks->TK1)); + memcpy(ks->TK2, key + 16, sizeof(ks->TK2)); + memcpy(ks->TK3, key + 32, sizeof(ks->TK3)); +#else + /* Set the initial states of TK1, TK2, and TK3 */ + memcpy(ks->TK1, key, 16); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + TK3[0] = le_load_word32(key + 32); + TK3[1] = le_load_word32(key + 36); + TK3[2] = le_load_word32(key + 40); + TK3[3] = le_load_word32(key + 44); + + /* Set up the key schedule using TK2 and TK3. TK1 is not added + * to the key schedule because we will derive that part of the + * schedule during encryption operations */ + schedule = ks->k; + rc = 0; + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round, schedule += 2) { + /* XOR the round constants with the current schedule words. + * The round constants for the 3rd and 4th rows are + * fixed and will be applied during encryption. */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + schedule[0] = TK2[0] ^ TK3[0] ^ (rc & 0x0F); + schedule[1] = TK2[1] ^ TK3[1] ^ (rc >> 4); + + /* Permute TK2 and TK3 for the next round */ + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + + /* Apply the LFSR's to TK2 and TK3 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + } +#endif +} + +void skinny_128_384_encrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 for the next round */ + skinny128_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_decrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t TK3[4]; + uint8_t rc = 0x15; +#else + const uint32_t *schedule = &(ks->k[SKINNY_128_384_ROUNDS * 2 - 2]); +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1 */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Permute TK1 to fast-forward it to the end of the key schedule */ + skinny128_fast_forward_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_fast_forward_tk(TK2); + skinny128_fast_forward_tk(TK3); + for (round = 0; round < SKINNY_128_384_ROUNDS; round += 2) { + /* Also fast-forward the LFSR's on every byte of TK2 and TK3 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR2(TK2[2]); + skinny128_LFSR2(TK2[3]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + skinny128_LFSR3(TK3[2]); + skinny128_LFSR3(TK3[3]); + } +#endif + + /* Perform all decryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Inverse permutation on TK1 for this round */ + skinny128_inv_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_inv_permute_tk(TK2); + skinny128_inv_permute_tk(TK3); + skinny128_LFSR3(TK2[2]); + skinny128_LFSR3(TK2[3]); + skinny128_LFSR2(TK3[2]); + skinny128_LFSR2(TK3[3]); +#endif + + /* Inverse mix of the columns */ + temp = s3; + s3 = s0; + s0 = s1; + s1 = s2; + s3 ^= temp; + s2 = temp ^ s0; + s1 ^= s2; + + /* Inverse shift of the rows */ + s1 = leftRotate24(s1); + s2 = leftRotate16(s2); + s3 = leftRotate8(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc >> 1) ^ (((rc << 5) ^ rc ^ 0x20) & 0x20); + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; + schedule -= 2; +#endif + s2 ^= 0x02; + + /* Apply the inverse of the S-box to all bytes in the state */ + skinny128_inv_sbox(s0); + skinny128_inv_sbox(s1); + skinny128_inv_sbox(s2); + skinny128_inv_sbox(s3); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK3[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); + TK2[0] = le_load_word32(tk2); + TK2[1] = le_load_word32(tk2 + 4); + TK2[2] = le_load_word32(tk2 + 8); + TK2[3] = le_load_word32(tk2 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK3[0] = le_load_word32(ks->TK3); + TK3[1] = le_load_word32(ks->TK3 + 4); + TK3[2] = le_load_word32(ks->TK3 + 8); + TK3[3] = le_load_word32(ks->TK3 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0] ^ TK2[0]; + s1 ^= schedule[1] ^ TK1[1] ^ TK2[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK3); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_384_encrypt_tk_full + (const unsigned char key[48], unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; + uint32_t TK3[4]; + uint32_t temp; + unsigned round; + uint8_t rc = 0; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakey */ + TK1[0] = le_load_word32(key); + TK1[1] = le_load_word32(key + 4); + TK1[2] = le_load_word32(key + 8); + TK1[3] = le_load_word32(key + 12); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + TK3[0] = le_load_word32(key + 32); + TK3[1] = le_load_word32(key + 36); + TK3[2] = le_load_word32(key + 40); + TK3[3] = le_load_word32(key + 44); + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_384_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ TK3[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ TK3[1] ^ (rc >> 4); + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1, TK2, and TK3 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_permute_tk(TK3); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR3(TK3[0]); + skinny128_LFSR3(TK3[1]); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_init + (skinny_128_256_key_schedule_t *ks, const unsigned char key[32]) +{ +#if !SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint32_t *schedule; + unsigned round; + uint8_t rc; +#endif + +#if SKINNY_128_SMALL_SCHEDULE + /* Copy the input key as-is when using the small key schedule version */ + memcpy(ks->TK1, key, sizeof(ks->TK1)); + memcpy(ks->TK2, key + 16, sizeof(ks->TK2)); +#else + /* Set the initial states of TK1 and TK2 */ + memcpy(ks->TK1, key, 16); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + + /* Set up the key schedule using TK2. TK1 is not added + * to the key schedule because we will derive that part of the + * schedule during encryption operations */ + schedule = ks->k; + rc = 0; + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round, schedule += 2) { + /* XOR the round constants with the current schedule words. + * The round constants for the 3rd and 4th rows are + * fixed and will be applied during encryption. */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + schedule[0] = TK2[0] ^ (rc & 0x0F); + schedule[1] = TK2[1] ^ (rc >> 4); + + /* Permute TK2 for the next round */ + skinny128_permute_tk(TK2); + + /* Apply the LFSR to TK2 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + } +#endif +} + +void skinny_128_256_encrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint8_t rc = 0; +#else + const uint32_t *schedule = ks->k; +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1 */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); +#endif + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; +#endif + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); +#else + schedule += 2; +#endif + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_decrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; +#if SKINNY_128_SMALL_SCHEDULE + uint32_t TK2[4]; + uint8_t rc = 0x09; +#else + const uint32_t *schedule = &(ks->k[SKINNY_128_256_ROUNDS * 2 - 2]); +#endif + uint32_t temp; + unsigned round; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakable part of the state, TK1. + * There is no need to fast-forward TK1 because the value at + * the end of the key schedule is the same as at the start */ + TK1[0] = le_load_word32(ks->TK1); + TK1[1] = le_load_word32(ks->TK1 + 4); + TK1[2] = le_load_word32(ks->TK1 + 8); + TK1[3] = le_load_word32(ks->TK1 + 12); +#if SKINNY_128_SMALL_SCHEDULE + TK2[0] = le_load_word32(ks->TK2); + TK2[1] = le_load_word32(ks->TK2 + 4); + TK2[2] = le_load_word32(ks->TK2 + 8); + TK2[3] = le_load_word32(ks->TK2 + 12); + for (round = 0; round < SKINNY_128_256_ROUNDS; round += 2) { + /* Also fast-forward the LFSR's on every byte of TK2 */ + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + skinny128_LFSR2(TK2[2]); + skinny128_LFSR2(TK2[3]); + } +#endif + + /* Perform all decryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Inverse permutation on TK1 for this round */ + skinny128_inv_permute_tk(TK1); +#if SKINNY_128_SMALL_SCHEDULE + skinny128_inv_permute_tk(TK2); + skinny128_LFSR3(TK2[2]); + skinny128_LFSR3(TK2[3]); +#endif + + /* Inverse mix of the columns */ + temp = s3; + s3 = s0; + s0 = s1; + s1 = s2; + s3 ^= temp; + s2 = temp ^ s0; + s1 ^= s2; + + /* Inverse shift of the rows */ + s1 = leftRotate24(s1); + s2 = leftRotate16(s2); + s3 = leftRotate8(s3); + + /* Apply the subkey for this round */ +#if SKINNY_128_SMALL_SCHEDULE + rc = (rc >> 1) ^ (((rc << 5) ^ rc ^ 0x20) & 0x20); + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); +#else + s0 ^= schedule[0] ^ TK1[0]; + s1 ^= schedule[1] ^ TK1[1]; + schedule -= 2; +#endif + s2 ^= 0x02; + + /* Apply the inverse of the S-box to all bytes in the state */ + skinny128_inv_sbox(s0); + skinny128_inv_sbox(s1); + skinny128_inv_sbox(s2); + skinny128_inv_sbox(s3); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +void skinny_128_256_encrypt_tk_full + (const unsigned char key[32], unsigned char *output, + const unsigned char *input) +{ + uint32_t s0, s1, s2, s3; + uint32_t TK1[4]; + uint32_t TK2[4]; + uint32_t temp; + unsigned round; + uint8_t rc = 0; + + /* Unpack the input block into the state array */ + s0 = le_load_word32(input); + s1 = le_load_word32(input + 4); + s2 = le_load_word32(input + 8); + s3 = le_load_word32(input + 12); + + /* Make a local copy of the tweakey */ + TK1[0] = le_load_word32(key); + TK1[1] = le_load_word32(key + 4); + TK1[2] = le_load_word32(key + 8); + TK1[3] = le_load_word32(key + 12); + TK2[0] = le_load_word32(key + 16); + TK2[1] = le_load_word32(key + 20); + TK2[2] = le_load_word32(key + 24); + TK2[3] = le_load_word32(key + 28); + + /* Perform all encryption rounds */ + for (round = 0; round < SKINNY_128_256_ROUNDS; ++round) { + /* Apply the S-box to all bytes in the state */ + skinny128_sbox(s0); + skinny128_sbox(s1); + skinny128_sbox(s2); + skinny128_sbox(s3); + + /* XOR the round constant and the subkey for this round */ + rc = (rc << 1) ^ ((rc >> 5) & 0x01) ^ ((rc >> 4) & 0x01) ^ 0x01; + rc &= 0x3F; + s0 ^= TK1[0] ^ TK2[0] ^ (rc & 0x0F); + s1 ^= TK1[1] ^ TK2[1] ^ (rc >> 4); + s2 ^= 0x02; + + /* Shift the cells in the rows right, which moves the cell + * values up closer to the MSB. That is, we do a left rotate + * on the word to rotate the cells in the word right */ + s1 = leftRotate8(s1); + s2 = leftRotate16(s2); + s3 = leftRotate24(s3); + + /* Mix the columns */ + s1 ^= s2; + s2 ^= s0; + temp = s3 ^ s2; + s3 = s2; + s2 = s1; + s1 = s0; + s0 = temp; + + /* Permute TK1 and TK2 for the next round */ + skinny128_permute_tk(TK1); + skinny128_permute_tk(TK2); + skinny128_LFSR2(TK2[0]); + skinny128_LFSR2(TK2[1]); + } + + /* Pack the result into the output buffer */ + le_store_word32(output, s0); + le_store_word32(output + 4, s1); + le_store_word32(output + 8, s2); + le_store_word32(output + 12, s3); +} + +#else /* __AVR__ */ + +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2) +{ + memcpy(ks->TK2, tk2, 16); + skinny_128_384_encrypt(ks, output, input); +} + +#endif /* __AVR__ */ diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128.h b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128.h new file mode 100644 index 0000000..2bfda3c --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinny128.h @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_SKINNY128_H +#define LW_INTERNAL_SKINNY128_H + +/** + * \file internal-skinny128.h + * \brief SKINNY-128 block cipher family. + * + * References: https://eprint.iacr.org/2016/660.pdf, + * https://sites.google.com/site/skinnycipher/ + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \def SKINNY_128_SMALL_SCHEDULE + * \brief Defined to 1 to use the small key schedule version of SKINNY-128. + */ +#if defined(__AVR__) +#define SKINNY_128_SMALL_SCHEDULE 1 +#else +#define SKINNY_128_SMALL_SCHEDULE 0 +#endif + +/** + * \brief Size of a block for SKINNY-128 block ciphers. + */ +#define SKINNY_128_BLOCK_SIZE 16 + +/** + * \brief Number of rounds for SKINNY-128-384. + */ +#define SKINNY_128_384_ROUNDS 56 + +/** + * \brief Structure of the key schedule for SKINNY-128-384. + */ +typedef struct +{ + /** TK1 for the tweakable part of the key schedule */ + uint8_t TK1[16]; + +#if SKINNY_128_SMALL_SCHEDULE + /** TK2 for the small key schedule */ + uint8_t TK2[16]; + + /** TK3 for the small key schedule */ + uint8_t TK3[16]; +#else + /** Words of the full key schedule */ + uint32_t k[SKINNY_128_384_ROUNDS * 2]; +#endif + +} skinny_128_384_key_schedule_t; + +/** + * \brief Initializes the key schedule for SKINNY-128-384. + * + * \param ks Points to the key schedule to initialize. + * \param key Points to the key data. + */ +void skinny_128_384_init + (skinny_128_384_key_schedule_t *ks, const unsigned char key[48]); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_384_encrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Decrypts a 128-bit block with SKINNY-128-384. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_384_decrypt + (const skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384 and an explicitly + * provided TK2 value. + * + * \param ks Points to the SKINNY-128-384 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * \param tk2 TK2 value that should be updated on the fly. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when both TK1 and TK2 change from block to block. + * When the key is initialized with skinny_128_384_init(), the TK2 part of + * the key value should be set to zero. + * + * \note Some versions of this function may modify the key schedule to + * copy tk2 into place. + */ +void skinny_128_384_encrypt_tk2 + (skinny_128_384_key_schedule_t *ks, unsigned char *output, + const unsigned char *input, const unsigned char *tk2); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-384 and a + * fully specified tweakey value. + * + * \param key Points to the 384-bit tweakey value. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when the entire tweakey changes from block to + * block. It is slower than the other versions of SKINNY-128-384 but + * more memory-efficient. + */ +void skinny_128_384_encrypt_tk_full + (const unsigned char key[48], unsigned char *output, + const unsigned char *input); + +/** + * \brief Number of rounds for SKINNY-128-256. + */ +#define SKINNY_128_256_ROUNDS 48 + +/** + * \brief Structure of the key schedule for SKINNY-128-256. + */ +typedef struct +{ + /** TK1 for the tweakable part of the key schedule */ + uint8_t TK1[16]; + +#if SKINNY_128_SMALL_SCHEDULE + /** TK2 for the small key schedule */ + uint8_t TK2[16]; +#else + /** Words of the full key schedule */ + uint32_t k[SKINNY_128_256_ROUNDS * 2]; +#endif + +} skinny_128_256_key_schedule_t; + +/** + * \brief Initializes the key schedule for SKINNY-128-256. + * + * \param ks Points to the key schedule to initialize. + * \param key Points to the key data. + */ +void skinny_128_256_init + (skinny_128_256_key_schedule_t *ks, const unsigned char key[32]); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-256. + * + * \param ks Points to the SKINNY-128-256 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_256_encrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Decrypts a 128-bit block with SKINNY-128-256. + * + * \param ks Points to the SKINNY-128-256 key schedule. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + */ +void skinny_128_256_decrypt + (const skinny_128_256_key_schedule_t *ks, unsigned char *output, + const unsigned char *input); + +/** + * \brief Encrypts a 128-bit block with SKINNY-128-256 and a + * fully specified tweakey value. + * + * \param key Points to the 256-bit tweakey value. + * \param output Output buffer which must be at least 16 bytes in length. + * \param input Input buffer which must be at least 16 bytes in length. + * + * The \a input and \a output buffers can be the same buffer for + * in-place encryption. + * + * This version is useful when the entire tweakey changes from block to + * block. It is slower than the other versions of SKINNY-128-256 but + * more memory-efficient. + */ +void skinny_128_256_encrypt_tk_full + (const unsigned char key[32], unsigned char *output, + const unsigned char *input); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinnyutil.h b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinnyutil.h new file mode 100644 index 0000000..83136cb --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-skinnyutil.h @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_SKINNYUTIL_H +#define LW_INTERNAL_SKINNYUTIL_H + +/** + * \file internal-skinnyutil.h + * \brief Utilities to help implement SKINNY and its variants. + */ + +#include "internal-util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond skinnyutil */ + +/* Utilities for implementing SKINNY-128 */ + +#define skinny128_LFSR2(x) \ + do { \ + uint32_t _x = (x); \ + (x) = ((_x << 1) & 0xFEFEFEFEU) ^ \ + (((_x >> 7) ^ (_x >> 5)) & 0x01010101U); \ + } while (0) + + +#define skinny128_LFSR3(x) \ + do { \ + uint32_t _x = (x); \ + (x) = ((_x >> 1) & 0x7F7F7F7FU) ^ \ + (((_x << 7) ^ (_x << 1)) & 0x80808080U); \ + } while (0) + +/* LFSR2 and LFSR3 are inverses of each other */ +#define skinny128_inv_LFSR2(x) skinny128_LFSR3(x) +#define skinny128_inv_LFSR3(x) skinny128_LFSR2(x) + +#define skinny128_permute_tk(tk) \ + do { \ + /* PT = [9, 15, 8, 13, 10, 14, 12, 11, 0, 1, 2, 3, 4, 5, 6, 7] */ \ + uint32_t row2 = tk[2]; \ + uint32_t row3 = tk[3]; \ + tk[2] = tk[0]; \ + tk[3] = tk[1]; \ + row3 = (row3 << 16) | (row3 >> 16); \ + tk[0] = ((row2 >> 8) & 0x000000FFU) | \ + ((row2 << 16) & 0x00FF0000U) | \ + ( row3 & 0xFF00FF00U); \ + tk[1] = ((row2 >> 16) & 0x000000FFU) | \ + (row2 & 0xFF000000U) | \ + ((row3 << 8) & 0x0000FF00U) | \ + ( row3 & 0x00FF0000U); \ + } while (0) + +#define skinny128_inv_permute_tk(tk) \ + do { \ + /* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \ + uint32_t row0 = tk[0]; \ + uint32_t row1 = tk[1]; \ + tk[0] = tk[2]; \ + tk[1] = tk[3]; \ + tk[2] = ((row0 >> 16) & 0x000000FFU) | \ + ((row0 << 8) & 0x0000FF00U) | \ + ((row1 << 16) & 0x00FF0000U) | \ + ( row1 & 0xFF000000U); \ + tk[3] = ((row0 >> 16) & 0x0000FF00U) | \ + ((row0 << 16) & 0xFF000000U) | \ + ((row1 >> 16) & 0x000000FFU) | \ + ((row1 << 8) & 0x00FF0000U); \ + } while (0) + +/* + * Apply the SKINNY sbox. The original version from the specification is + * equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x11111111U) ^ (x)) + * #define SBOX_SWAP(x) + * (((x) & 0xF9F9F9F9U) | + * (((x) >> 1) & 0x02020202U) | + * (((x) << 1) & 0x04040404U)) + * #define SBOX_PERMUTE(x) + * ((((x) & 0x01010101U) << 2) | + * (((x) & 0x06060606U) << 5) | + * (((x) & 0x20202020U) >> 5) | + * (((x) & 0xC8C8C8C8U) >> 2) | + * (((x) & 0x10101010U) >> 1)) + * + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE(x); + * x = SBOX_MIX(x); + * return SBOX_SWAP(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_PERMUTE and SBOX_SWAP steps to be performed with one + * final permuatation. This reduces the number of shift operations. + */ +#define skinny128_sbox(x) \ +do { \ + uint32_t y; \ + \ + /* Mix the bits */ \ + x = ~x; \ + x ^= (((x >> 2) & (x >> 3)) & 0x11111111U); \ + y = (((x << 5) & (x << 1)) & 0x20202020U); \ + x ^= (((x << 5) & (x << 4)) & 0x40404040U) ^ y; \ + y = (((x << 2) & (x << 1)) & 0x80808080U); \ + x ^= (((x >> 2) & (x << 1)) & 0x02020202U) ^ y; \ + y = (((x >> 5) & (x << 1)) & 0x04040404U); \ + x ^= (((x >> 1) & (x >> 2)) & 0x08080808U) ^ y; \ + x = ~x; \ + \ + /* Permutation generated by http://programming.sirrida.de/calcperm.php */ \ + /* The final permutation for each byte is [2 7 6 1 3 0 4 5] */ \ + x = ((x & 0x08080808U) << 1) | \ + ((x & 0x32323232U) << 2) | \ + ((x & 0x01010101U) << 5) | \ + ((x & 0x80808080U) >> 6) | \ + ((x & 0x40404040U) >> 4) | \ + ((x & 0x04040404U) >> 2); \ +} while (0) + +/* + * Apply the inverse of the SKINNY sbox. The original version from the + * specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x11111111U) ^ (x)) + * #define SBOX_SWAP(x) + * (((x) & 0xF9F9F9F9U) | + * (((x) >> 1) & 0x02020202U) | + * (((x) << 1) & 0x04040404U)) + * #define SBOX_PERMUTE_INV(x) + * ((((x) & 0x08080808U) << 1) | + * (((x) & 0x32323232U) << 2) | + * (((x) & 0x01010101U) << 5) | + * (((x) & 0xC0C0C0C0U) >> 5) | + * (((x) & 0x04040404U) >> 2)) + * + * x = SBOX_SWAP(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_PERMUTE_INV(x); + * return SBOX_MIX(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_PERMUTE_INV and SBOX_SWAP steps to be performed with one + * final permuatation. This reduces the number of shift operations. + */ +#define skinny128_inv_sbox(x) \ +do { \ + uint32_t y; \ + \ + /* Mix the bits */ \ + x = ~x; \ + y = (((x >> 1) & (x >> 3)) & 0x01010101U); \ + x ^= (((x >> 2) & (x >> 3)) & 0x10101010U) ^ y; \ + y = (((x >> 6) & (x >> 1)) & 0x02020202U); \ + x ^= (((x >> 1) & (x >> 2)) & 0x08080808U) ^ y; \ + y = (((x << 2) & (x << 1)) & 0x80808080U); \ + x ^= (((x >> 1) & (x << 2)) & 0x04040404U) ^ y; \ + y = (((x << 5) & (x << 1)) & 0x20202020U); \ + x ^= (((x << 4) & (x << 5)) & 0x40404040U) ^ y; \ + x = ~x; \ + \ + /* Permutation generated by http://programming.sirrida.de/calcperm.php */ \ + /* The final permutation for each byte is [5 3 0 4 6 7 2 1] */ \ + x = ((x & 0x01010101U) << 2) | \ + ((x & 0x04040404U) << 4) | \ + ((x & 0x02020202U) << 6) | \ + ((x & 0x20202020U) >> 5) | \ + ((x & 0xC8C8C8C8U) >> 2) | \ + ((x & 0x10101010U) >> 1); \ +} while (0) + +/* Utilities for implementing SKINNY-64 */ + +#define skinny64_LFSR2(x) \ + do { \ + uint16_t _x = (x); \ + (x) = ((_x << 1) & 0xEEEEU) ^ (((_x >> 3) ^ (_x >> 2)) & 0x1111U); \ + } while (0) + +#define skinny64_LFSR3(x) \ + do { \ + uint16_t _x = (x); \ + (x) = ((_x >> 1) & 0x7777U) ^ ((_x ^ (_x << 3)) & 0x8888U); \ + } while (0) + +/* LFSR2 and LFSR3 are inverses of each other */ +#define skinny64_inv_LFSR2(x) skinny64_LFSR3(x) +#define skinny64_inv_LFSR3(x) skinny64_LFSR2(x) + +#define skinny64_permute_tk(tk) \ + do { \ + /* PT = [9, 15, 8, 13, 10, 14, 12, 11, 0, 1, 2, 3, 4, 5, 6, 7] */ \ + uint16_t row2 = tk[2]; \ + uint16_t row3 = tk[3]; \ + tk[2] = tk[0]; \ + tk[3] = tk[1]; \ + row3 = (row3 << 8) | (row3 >> 8); \ + tk[0] = ((row2 << 4) & 0xF000U) | \ + ((row2 >> 8) & 0x00F0U) | \ + ( row3 & 0x0F0FU); \ + tk[1] = ((row2 << 8) & 0xF000U) | \ + ((row3 >> 4) & 0x0F00U) | \ + ( row3 & 0x00F0U) | \ + ( row2 & 0x000FU); \ + } while (0) + +#define skinny64_inv_permute_tk(tk) \ + do { \ + /* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \ + uint16_t row0 = tk[0]; \ + uint16_t row1 = tk[1]; \ + tk[0] = tk[2]; \ + tk[1] = tk[3]; \ + tk[2] = ((row0 << 8) & 0xF000U) | \ + ((row0 >> 4) & 0x0F00U) | \ + ((row1 >> 8) & 0x00F0U) | \ + ( row1 & 0x000FU); \ + tk[3] = ((row1 << 8) & 0xF000U) | \ + ((row0 << 8) & 0x0F00U) | \ + ((row1 >> 4) & 0x00F0U) | \ + ((row0 >> 8) & 0x000FU); \ + } while (0) + +/* + * Apply the SKINNY-64 sbox. The original version from the + * specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x1111U) ^ (x)) + * #define SBOX_SHIFT(x) + * ((((x) << 1) & 0xEEEEU) | (((x) >> 3) & 0x1111U)) + * + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT(x); + * return SBOX_MIX(x); + * + * However, we can mix the bits in their original positions and then + * delay the SBOX_SHIFT steps to be performed with one final rotation. + * This reduces the number of required shift operations from 14 to 10. + * + * We can further reduce the number of NOT operations from 4 to 2 + * using the technique from https://github.com/kste/skinny_avx to + * convert NOR-XOR operations into AND-XOR operations by converting + * the S-box into its NOT-inverse. + */ +#define skinny64_sbox(x) \ +do { \ + x = ~x; \ + x = (((x >> 3) & (x >> 2)) & 0x1111U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x8888U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x4444U) ^ x; \ + x = (((x >> 2) & (x << 1)) & 0x2222U) ^ x; \ + x = ~x; \ + x = ((x >> 1) & 0x7777U) | ((x << 3) & 0x8888U); \ +} while (0) + +/* + * Apply the inverse of the SKINNY-64 sbox. The original version + * from the specification is equivalent to: + * + * #define SBOX_MIX(x) + * (((~((((x) >> 1) | (x)) >> 2)) & 0x1111U) ^ (x)) + * #define SBOX_SHIFT_INV(x) + * ((((x) >> 1) & 0x7777U) | (((x) << 3) & 0x8888U)) + * + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * x = SBOX_MIX(x); + * x = SBOX_SHIFT_INV(x); + * return SBOX_MIX(x); + */ +#define skinny64_inv_sbox(x) \ +do { \ + x = ~x; \ + x = (((x >> 3) & (x >> 2)) & 0x1111U) ^ x; \ + x = (((x << 1) & (x >> 2)) & 0x2222U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x4444U) ^ x; \ + x = (((x << 1) & (x << 2)) & 0x8888U) ^ x; \ + x = ~x; \ + x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \ +} while (0) + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-util.h b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-util.h new file mode 100644 index 0000000..e30166d --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/internal-util.h @@ -0,0 +1,702 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LW_INTERNAL_UTIL_H +#define LW_INTERNAL_UTIL_H + +#include + +/* Figure out how to inline functions using this C compiler */ +#if defined(__STDC__) && __STDC_VERSION__ >= 199901L +#define STATIC_INLINE static inline +#elif defined(__GNUC__) || defined(__clang__) +#define STATIC_INLINE static __inline__ +#else +#define STATIC_INLINE static +#endif + +/* Try to figure out whether the CPU is little-endian or big-endian. + * May need to modify this to include new compiler-specific defines. + * Alternatively, define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ in your + * compiler flags when you compile this library */ +#if defined(__x86_64) || defined(__x86_64__) || \ + defined(__i386) || defined(__i386__) || \ + defined(__AVR__) || defined(__arm) || defined(__arm__) || \ + defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86) || \ + defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM_FP) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 1234) || \ + defined(__LITTLE_ENDIAN__) +#define LW_UTIL_LITTLE_ENDIAN 1 +#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 4321) || \ + defined(__BIG_ENDIAN__) +/* Big endian */ +#else +#error "Cannot determine the endianess of this platform" +#endif + +/* Helper macros to load and store values while converting endian-ness */ + +/* Load a big-endian 32-bit word from a byte buffer */ +#define be_load_word32(ptr) \ + ((((uint32_t)((ptr)[0])) << 24) | \ + (((uint32_t)((ptr)[1])) << 16) | \ + (((uint32_t)((ptr)[2])) << 8) | \ + ((uint32_t)((ptr)[3]))) + +/* Store a big-endian 32-bit word into a byte buffer */ +#define be_store_word32(ptr, x) \ + do { \ + uint32_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 24); \ + (ptr)[1] = (uint8_t)(_x >> 16); \ + (ptr)[2] = (uint8_t)(_x >> 8); \ + (ptr)[3] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 32-bit word from a byte buffer */ +#define le_load_word32(ptr) \ + ((((uint32_t)((ptr)[3])) << 24) | \ + (((uint32_t)((ptr)[2])) << 16) | \ + (((uint32_t)((ptr)[1])) << 8) | \ + ((uint32_t)((ptr)[0]))) + +/* Store a little-endian 32-bit word into a byte buffer */ +#define le_store_word32(ptr, x) \ + do { \ + uint32_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + (ptr)[2] = (uint8_t)(_x >> 16); \ + (ptr)[3] = (uint8_t)(_x >> 24); \ + } while (0) + +/* Load a big-endian 64-bit word from a byte buffer */ +#define be_load_word64(ptr) \ + ((((uint64_t)((ptr)[0])) << 56) | \ + (((uint64_t)((ptr)[1])) << 48) | \ + (((uint64_t)((ptr)[2])) << 40) | \ + (((uint64_t)((ptr)[3])) << 32) | \ + (((uint64_t)((ptr)[4])) << 24) | \ + (((uint64_t)((ptr)[5])) << 16) | \ + (((uint64_t)((ptr)[6])) << 8) | \ + ((uint64_t)((ptr)[7]))) + +/* Store a big-endian 64-bit word into a byte buffer */ +#define be_store_word64(ptr, x) \ + do { \ + uint64_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 56); \ + (ptr)[1] = (uint8_t)(_x >> 48); \ + (ptr)[2] = (uint8_t)(_x >> 40); \ + (ptr)[3] = (uint8_t)(_x >> 32); \ + (ptr)[4] = (uint8_t)(_x >> 24); \ + (ptr)[5] = (uint8_t)(_x >> 16); \ + (ptr)[6] = (uint8_t)(_x >> 8); \ + (ptr)[7] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 64-bit word from a byte buffer */ +#define le_load_word64(ptr) \ + ((((uint64_t)((ptr)[7])) << 56) | \ + (((uint64_t)((ptr)[6])) << 48) | \ + (((uint64_t)((ptr)[5])) << 40) | \ + (((uint64_t)((ptr)[4])) << 32) | \ + (((uint64_t)((ptr)[3])) << 24) | \ + (((uint64_t)((ptr)[2])) << 16) | \ + (((uint64_t)((ptr)[1])) << 8) | \ + ((uint64_t)((ptr)[0]))) + +/* Store a little-endian 64-bit word into a byte buffer */ +#define le_store_word64(ptr, x) \ + do { \ + uint64_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + (ptr)[2] = (uint8_t)(_x >> 16); \ + (ptr)[3] = (uint8_t)(_x >> 24); \ + (ptr)[4] = (uint8_t)(_x >> 32); \ + (ptr)[5] = (uint8_t)(_x >> 40); \ + (ptr)[6] = (uint8_t)(_x >> 48); \ + (ptr)[7] = (uint8_t)(_x >> 56); \ + } while (0) + +/* Load a big-endian 16-bit word from a byte buffer */ +#define be_load_word16(ptr) \ + ((((uint16_t)((ptr)[0])) << 8) | \ + ((uint16_t)((ptr)[1]))) + +/* Store a big-endian 16-bit word into a byte buffer */ +#define be_store_word16(ptr, x) \ + do { \ + uint16_t _x = (x); \ + (ptr)[0] = (uint8_t)(_x >> 8); \ + (ptr)[1] = (uint8_t)_x; \ + } while (0) + +/* Load a little-endian 16-bit word from a byte buffer */ +#define le_load_word16(ptr) \ + ((((uint16_t)((ptr)[1])) << 8) | \ + ((uint16_t)((ptr)[0]))) + +/* Store a little-endian 16-bit word into a byte buffer */ +#define le_store_word16(ptr, x) \ + do { \ + uint16_t _x = (x); \ + (ptr)[0] = (uint8_t)_x; \ + (ptr)[1] = (uint8_t)(_x >> 8); \ + } while (0) + +/* XOR a source byte buffer against a destination */ +#define lw_xor_block(dest, src, len) \ + do { \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest++ ^= *_src++; \ + --_len; \ + } \ + } while (0) + +/* XOR two source byte buffers and put the result in a destination buffer */ +#define lw_xor_block_2_src(dest, src1, src2, len) \ + do { \ + unsigned char *_dest = (dest); \ + const unsigned char *_src1 = (src1); \ + const unsigned char *_src2 = (src2); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest++ = *_src1++ ^ *_src2++; \ + --_len; \ + } \ + } while (0) + +/* XOR a source byte buffer against a destination and write to another + * destination at the same time */ +#define lw_xor_block_2_dest(dest2, dest, src, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + *_dest2++ = (*_dest++ ^= *_src++); \ + --_len; \ + } \ + } while (0) + +/* XOR two byte buffers and write to a destination which at the same + * time copying the contents of src2 to dest2 */ +#define lw_xor_block_copy_src(dest2, dest, src1, src2, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src1 = (src1); \ + const unsigned char *_src2 = (src2); \ + unsigned _len = (len); \ + while (_len > 0) { \ + unsigned char _temp = *_src2++; \ + *_dest2++ = _temp; \ + *_dest++ = *_src1++ ^ _temp; \ + --_len; \ + } \ + } while (0) + +/* XOR a source byte buffer against a destination and write to another + * destination at the same time. This version swaps the source value + * into the "dest" buffer */ +#define lw_xor_block_swap(dest2, dest, src, len) \ + do { \ + unsigned char *_dest2 = (dest2); \ + unsigned char *_dest = (dest); \ + const unsigned char *_src = (src); \ + unsigned _len = (len); \ + while (_len > 0) { \ + unsigned char _temp = *_src++; \ + *_dest2++ = *_dest ^ _temp; \ + *_dest++ = _temp; \ + --_len; \ + } \ + } while (0) + +/* Rotation functions need to be optimised for best performance on AVR. + * The most efficient rotations are where the number of bits is 1 or a + * multiple of 8, so we compose the efficient rotations to produce all + * other rotation counts of interest. */ + +#if defined(__AVR__) +#define LW_CRYPTO_ROTATE32_COMPOSED 1 +#else +#define LW_CRYPTO_ROTATE32_COMPOSED 0 +#endif + +/* Rotation macros for 32-bit arguments */ + +/* Generic left rotate */ +#define leftRotate(a, bits) \ + (__extension__ ({ \ + uint32_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (32 - (bits))); \ + })) + +/* Generic right rotate */ +#define rightRotate(a, bits) \ + (__extension__ ({ \ + uint32_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (32 - (bits))); \ + })) + +#if !LW_CRYPTO_ROTATE32_COMPOSED + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1(a) (leftRotate((a), 1)) +#define leftRotate2(a) (leftRotate((a), 2)) +#define leftRotate3(a) (leftRotate((a), 3)) +#define leftRotate4(a) (leftRotate((a), 4)) +#define leftRotate5(a) (leftRotate((a), 5)) +#define leftRotate6(a) (leftRotate((a), 6)) +#define leftRotate7(a) (leftRotate((a), 7)) +#define leftRotate8(a) (leftRotate((a), 8)) +#define leftRotate9(a) (leftRotate((a), 9)) +#define leftRotate10(a) (leftRotate((a), 10)) +#define leftRotate11(a) (leftRotate((a), 11)) +#define leftRotate12(a) (leftRotate((a), 12)) +#define leftRotate13(a) (leftRotate((a), 13)) +#define leftRotate14(a) (leftRotate((a), 14)) +#define leftRotate15(a) (leftRotate((a), 15)) +#define leftRotate16(a) (leftRotate((a), 16)) +#define leftRotate17(a) (leftRotate((a), 17)) +#define leftRotate18(a) (leftRotate((a), 18)) +#define leftRotate19(a) (leftRotate((a), 19)) +#define leftRotate20(a) (leftRotate((a), 20)) +#define leftRotate21(a) (leftRotate((a), 21)) +#define leftRotate22(a) (leftRotate((a), 22)) +#define leftRotate23(a) (leftRotate((a), 23)) +#define leftRotate24(a) (leftRotate((a), 24)) +#define leftRotate25(a) (leftRotate((a), 25)) +#define leftRotate26(a) (leftRotate((a), 26)) +#define leftRotate27(a) (leftRotate((a), 27)) +#define leftRotate28(a) (leftRotate((a), 28)) +#define leftRotate29(a) (leftRotate((a), 29)) +#define leftRotate30(a) (leftRotate((a), 30)) +#define leftRotate31(a) (leftRotate((a), 31)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1(a) (rightRotate((a), 1)) +#define rightRotate2(a) (rightRotate((a), 2)) +#define rightRotate3(a) (rightRotate((a), 3)) +#define rightRotate4(a) (rightRotate((a), 4)) +#define rightRotate5(a) (rightRotate((a), 5)) +#define rightRotate6(a) (rightRotate((a), 6)) +#define rightRotate7(a) (rightRotate((a), 7)) +#define rightRotate8(a) (rightRotate((a), 8)) +#define rightRotate9(a) (rightRotate((a), 9)) +#define rightRotate10(a) (rightRotate((a), 10)) +#define rightRotate11(a) (rightRotate((a), 11)) +#define rightRotate12(a) (rightRotate((a), 12)) +#define rightRotate13(a) (rightRotate((a), 13)) +#define rightRotate14(a) (rightRotate((a), 14)) +#define rightRotate15(a) (rightRotate((a), 15)) +#define rightRotate16(a) (rightRotate((a), 16)) +#define rightRotate17(a) (rightRotate((a), 17)) +#define rightRotate18(a) (rightRotate((a), 18)) +#define rightRotate19(a) (rightRotate((a), 19)) +#define rightRotate20(a) (rightRotate((a), 20)) +#define rightRotate21(a) (rightRotate((a), 21)) +#define rightRotate22(a) (rightRotate((a), 22)) +#define rightRotate23(a) (rightRotate((a), 23)) +#define rightRotate24(a) (rightRotate((a), 24)) +#define rightRotate25(a) (rightRotate((a), 25)) +#define rightRotate26(a) (rightRotate((a), 26)) +#define rightRotate27(a) (rightRotate((a), 27)) +#define rightRotate28(a) (rightRotate((a), 28)) +#define rightRotate29(a) (rightRotate((a), 29)) +#define rightRotate30(a) (rightRotate((a), 30)) +#define rightRotate31(a) (rightRotate((a), 31)) + +#else /* LW_CRYPTO_ROTATE32_COMPOSED */ + +/* Composed rotation macros where 1 and 8 are fast, but others are slow */ + +/* Left rotate by 1 */ +#define leftRotate1(a) (leftRotate((a), 1)) + +/* Left rotate by 2 */ +#define leftRotate2(a) (leftRotate(leftRotate((a), 1), 1)) + +/* Left rotate by 3 */ +#define leftRotate3(a) (leftRotate(leftRotate(leftRotate((a), 1), 1), 1)) + +/* Left rotate by 4 */ +#define leftRotate4(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 1), 1), 1), 1)) + +/* Left rotate by 5: Rotate left by 8, then right by 3 */ +#define leftRotate5(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 8), 1), 1), 1)) + +/* Left rotate by 6: Rotate left by 8, then right by 2 */ +#define leftRotate6(a) (rightRotate(rightRotate(leftRotate((a), 8), 1), 1)) + +/* Left rotate by 7: Rotate left by 8, then right by 1 */ +#define leftRotate7(a) (rightRotate(leftRotate((a), 8), 1)) + +/* Left rotate by 8 */ +#define leftRotate8(a) (leftRotate((a), 8)) + +/* Left rotate by 9: Rotate left by 8, then left by 1 */ +#define leftRotate9(a) (leftRotate(leftRotate((a), 8), 1)) + +/* Left rotate by 10: Rotate left by 8, then left by 2 */ +#define leftRotate10(a) (leftRotate(leftRotate(leftRotate((a), 8), 1), 1)) + +/* Left rotate by 11: Rotate left by 8, then left by 3 */ +#define leftRotate11(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 8), 1), 1), 1)) + +/* Left rotate by 12: Rotate left by 16, then right by 4 */ +#define leftRotate12(a) (rightRotate(rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1), 1)) + +/* Left rotate by 13: Rotate left by 16, then right by 3 */ +#define leftRotate13(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1)) + +/* Left rotate by 14: Rotate left by 16, then right by 2 */ +#define leftRotate14(a) (rightRotate(rightRotate(leftRotate((a), 16), 1), 1)) + +/* Left rotate by 15: Rotate left by 16, then right by 1 */ +#define leftRotate15(a) (rightRotate(leftRotate((a), 16), 1)) + +/* Left rotate by 16 */ +#define leftRotate16(a) (leftRotate((a), 16)) + +/* Left rotate by 17: Rotate left by 16, then left by 1 */ +#define leftRotate17(a) (leftRotate(leftRotate((a), 16), 1)) + +/* Left rotate by 18: Rotate left by 16, then left by 2 */ +#define leftRotate18(a) (leftRotate(leftRotate(leftRotate((a), 16), 1), 1)) + +/* Left rotate by 19: Rotate left by 16, then left by 3 */ +#define leftRotate19(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1)) + +/* Left rotate by 20: Rotate left by 16, then left by 4 */ +#define leftRotate20(a) (leftRotate(leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1), 1)) + +/* Left rotate by 21: Rotate left by 24, then right by 3 */ +#define leftRotate21(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 24), 1), 1), 1)) + +/* Left rotate by 22: Rotate left by 24, then right by 2 */ +#define leftRotate22(a) (rightRotate(rightRotate(leftRotate((a), 24), 1), 1)) + +/* Left rotate by 23: Rotate left by 24, then right by 1 */ +#define leftRotate23(a) (rightRotate(leftRotate((a), 24), 1)) + +/* Left rotate by 24 */ +#define leftRotate24(a) (leftRotate((a), 24)) + +/* Left rotate by 25: Rotate left by 24, then left by 1 */ +#define leftRotate25(a) (leftRotate(leftRotate((a), 24), 1)) + +/* Left rotate by 26: Rotate left by 24, then left by 2 */ +#define leftRotate26(a) (leftRotate(leftRotate(leftRotate((a), 24), 1), 1)) + +/* Left rotate by 27: Rotate left by 24, then left by 3 */ +#define leftRotate27(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 24), 1), 1), 1)) + +/* Left rotate by 28: Rotate right by 4 */ +#define leftRotate28(a) (rightRotate(rightRotate(rightRotate(rightRotate((a), 1), 1), 1), 1)) + +/* Left rotate by 29: Rotate right by 3 */ +#define leftRotate29(a) (rightRotate(rightRotate(rightRotate((a), 1), 1), 1)) + +/* Left rotate by 30: Rotate right by 2 */ +#define leftRotate30(a) (rightRotate(rightRotate((a), 1), 1)) + +/* Left rotate by 31: Rotate right by 1 */ +#define leftRotate31(a) (rightRotate((a), 1)) + +/* Define the 32-bit right rotations in terms of left rotations */ +#define rightRotate1(a) (leftRotate31((a))) +#define rightRotate2(a) (leftRotate30((a))) +#define rightRotate3(a) (leftRotate29((a))) +#define rightRotate4(a) (leftRotate28((a))) +#define rightRotate5(a) (leftRotate27((a))) +#define rightRotate6(a) (leftRotate26((a))) +#define rightRotate7(a) (leftRotate25((a))) +#define rightRotate8(a) (leftRotate24((a))) +#define rightRotate9(a) (leftRotate23((a))) +#define rightRotate10(a) (leftRotate22((a))) +#define rightRotate11(a) (leftRotate21((a))) +#define rightRotate12(a) (leftRotate20((a))) +#define rightRotate13(a) (leftRotate19((a))) +#define rightRotate14(a) (leftRotate18((a))) +#define rightRotate15(a) (leftRotate17((a))) +#define rightRotate16(a) (leftRotate16((a))) +#define rightRotate17(a) (leftRotate15((a))) +#define rightRotate18(a) (leftRotate14((a))) +#define rightRotate19(a) (leftRotate13((a))) +#define rightRotate20(a) (leftRotate12((a))) +#define rightRotate21(a) (leftRotate11((a))) +#define rightRotate22(a) (leftRotate10((a))) +#define rightRotate23(a) (leftRotate9((a))) +#define rightRotate24(a) (leftRotate8((a))) +#define rightRotate25(a) (leftRotate7((a))) +#define rightRotate26(a) (leftRotate6((a))) +#define rightRotate27(a) (leftRotate5((a))) +#define rightRotate28(a) (leftRotate4((a))) +#define rightRotate29(a) (leftRotate3((a))) +#define rightRotate30(a) (leftRotate2((a))) +#define rightRotate31(a) (leftRotate1((a))) + +#endif /* LW_CRYPTO_ROTATE32_COMPOSED */ + +/* Rotation macros for 64-bit arguments */ + +/* Generic left rotate */ +#define leftRotate_64(a, bits) \ + (__extension__ ({ \ + uint64_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (64 - (bits))); \ + })) + +/* Generic right rotate */ +#define rightRotate_64(a, bits) \ + (__extension__ ({ \ + uint64_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (64 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_64(a) (leftRotate_64((a), 1)) +#define leftRotate2_64(a) (leftRotate_64((a), 2)) +#define leftRotate3_64(a) (leftRotate_64((a), 3)) +#define leftRotate4_64(a) (leftRotate_64((a), 4)) +#define leftRotate5_64(a) (leftRotate_64((a), 5)) +#define leftRotate6_64(a) (leftRotate_64((a), 6)) +#define leftRotate7_64(a) (leftRotate_64((a), 7)) +#define leftRotate8_64(a) (leftRotate_64((a), 8)) +#define leftRotate9_64(a) (leftRotate_64((a), 9)) +#define leftRotate10_64(a) (leftRotate_64((a), 10)) +#define leftRotate11_64(a) (leftRotate_64((a), 11)) +#define leftRotate12_64(a) (leftRotate_64((a), 12)) +#define leftRotate13_64(a) (leftRotate_64((a), 13)) +#define leftRotate14_64(a) (leftRotate_64((a), 14)) +#define leftRotate15_64(a) (leftRotate_64((a), 15)) +#define leftRotate16_64(a) (leftRotate_64((a), 16)) +#define leftRotate17_64(a) (leftRotate_64((a), 17)) +#define leftRotate18_64(a) (leftRotate_64((a), 18)) +#define leftRotate19_64(a) (leftRotate_64((a), 19)) +#define leftRotate20_64(a) (leftRotate_64((a), 20)) +#define leftRotate21_64(a) (leftRotate_64((a), 21)) +#define leftRotate22_64(a) (leftRotate_64((a), 22)) +#define leftRotate23_64(a) (leftRotate_64((a), 23)) +#define leftRotate24_64(a) (leftRotate_64((a), 24)) +#define leftRotate25_64(a) (leftRotate_64((a), 25)) +#define leftRotate26_64(a) (leftRotate_64((a), 26)) +#define leftRotate27_64(a) (leftRotate_64((a), 27)) +#define leftRotate28_64(a) (leftRotate_64((a), 28)) +#define leftRotate29_64(a) (leftRotate_64((a), 29)) +#define leftRotate30_64(a) (leftRotate_64((a), 30)) +#define leftRotate31_64(a) (leftRotate_64((a), 31)) +#define leftRotate32_64(a) (leftRotate_64((a), 32)) +#define leftRotate33_64(a) (leftRotate_64((a), 33)) +#define leftRotate34_64(a) (leftRotate_64((a), 34)) +#define leftRotate35_64(a) (leftRotate_64((a), 35)) +#define leftRotate36_64(a) (leftRotate_64((a), 36)) +#define leftRotate37_64(a) (leftRotate_64((a), 37)) +#define leftRotate38_64(a) (leftRotate_64((a), 38)) +#define leftRotate39_64(a) (leftRotate_64((a), 39)) +#define leftRotate40_64(a) (leftRotate_64((a), 40)) +#define leftRotate41_64(a) (leftRotate_64((a), 41)) +#define leftRotate42_64(a) (leftRotate_64((a), 42)) +#define leftRotate43_64(a) (leftRotate_64((a), 43)) +#define leftRotate44_64(a) (leftRotate_64((a), 44)) +#define leftRotate45_64(a) (leftRotate_64((a), 45)) +#define leftRotate46_64(a) (leftRotate_64((a), 46)) +#define leftRotate47_64(a) (leftRotate_64((a), 47)) +#define leftRotate48_64(a) (leftRotate_64((a), 48)) +#define leftRotate49_64(a) (leftRotate_64((a), 49)) +#define leftRotate50_64(a) (leftRotate_64((a), 50)) +#define leftRotate51_64(a) (leftRotate_64((a), 51)) +#define leftRotate52_64(a) (leftRotate_64((a), 52)) +#define leftRotate53_64(a) (leftRotate_64((a), 53)) +#define leftRotate54_64(a) (leftRotate_64((a), 54)) +#define leftRotate55_64(a) (leftRotate_64((a), 55)) +#define leftRotate56_64(a) (leftRotate_64((a), 56)) +#define leftRotate57_64(a) (leftRotate_64((a), 57)) +#define leftRotate58_64(a) (leftRotate_64((a), 58)) +#define leftRotate59_64(a) (leftRotate_64((a), 59)) +#define leftRotate60_64(a) (leftRotate_64((a), 60)) +#define leftRotate61_64(a) (leftRotate_64((a), 61)) +#define leftRotate62_64(a) (leftRotate_64((a), 62)) +#define leftRotate63_64(a) (leftRotate_64((a), 63)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_64(a) (rightRotate_64((a), 1)) +#define rightRotate2_64(a) (rightRotate_64((a), 2)) +#define rightRotate3_64(a) (rightRotate_64((a), 3)) +#define rightRotate4_64(a) (rightRotate_64((a), 4)) +#define rightRotate5_64(a) (rightRotate_64((a), 5)) +#define rightRotate6_64(a) (rightRotate_64((a), 6)) +#define rightRotate7_64(a) (rightRotate_64((a), 7)) +#define rightRotate8_64(a) (rightRotate_64((a), 8)) +#define rightRotate9_64(a) (rightRotate_64((a), 9)) +#define rightRotate10_64(a) (rightRotate_64((a), 10)) +#define rightRotate11_64(a) (rightRotate_64((a), 11)) +#define rightRotate12_64(a) (rightRotate_64((a), 12)) +#define rightRotate13_64(a) (rightRotate_64((a), 13)) +#define rightRotate14_64(a) (rightRotate_64((a), 14)) +#define rightRotate15_64(a) (rightRotate_64((a), 15)) +#define rightRotate16_64(a) (rightRotate_64((a), 16)) +#define rightRotate17_64(a) (rightRotate_64((a), 17)) +#define rightRotate18_64(a) (rightRotate_64((a), 18)) +#define rightRotate19_64(a) (rightRotate_64((a), 19)) +#define rightRotate20_64(a) (rightRotate_64((a), 20)) +#define rightRotate21_64(a) (rightRotate_64((a), 21)) +#define rightRotate22_64(a) (rightRotate_64((a), 22)) +#define rightRotate23_64(a) (rightRotate_64((a), 23)) +#define rightRotate24_64(a) (rightRotate_64((a), 24)) +#define rightRotate25_64(a) (rightRotate_64((a), 25)) +#define rightRotate26_64(a) (rightRotate_64((a), 26)) +#define rightRotate27_64(a) (rightRotate_64((a), 27)) +#define rightRotate28_64(a) (rightRotate_64((a), 28)) +#define rightRotate29_64(a) (rightRotate_64((a), 29)) +#define rightRotate30_64(a) (rightRotate_64((a), 30)) +#define rightRotate31_64(a) (rightRotate_64((a), 31)) +#define rightRotate32_64(a) (rightRotate_64((a), 32)) +#define rightRotate33_64(a) (rightRotate_64((a), 33)) +#define rightRotate34_64(a) (rightRotate_64((a), 34)) +#define rightRotate35_64(a) (rightRotate_64((a), 35)) +#define rightRotate36_64(a) (rightRotate_64((a), 36)) +#define rightRotate37_64(a) (rightRotate_64((a), 37)) +#define rightRotate38_64(a) (rightRotate_64((a), 38)) +#define rightRotate39_64(a) (rightRotate_64((a), 39)) +#define rightRotate40_64(a) (rightRotate_64((a), 40)) +#define rightRotate41_64(a) (rightRotate_64((a), 41)) +#define rightRotate42_64(a) (rightRotate_64((a), 42)) +#define rightRotate43_64(a) (rightRotate_64((a), 43)) +#define rightRotate44_64(a) (rightRotate_64((a), 44)) +#define rightRotate45_64(a) (rightRotate_64((a), 45)) +#define rightRotate46_64(a) (rightRotate_64((a), 46)) +#define rightRotate47_64(a) (rightRotate_64((a), 47)) +#define rightRotate48_64(a) (rightRotate_64((a), 48)) +#define rightRotate49_64(a) (rightRotate_64((a), 49)) +#define rightRotate50_64(a) (rightRotate_64((a), 50)) +#define rightRotate51_64(a) (rightRotate_64((a), 51)) +#define rightRotate52_64(a) (rightRotate_64((a), 52)) +#define rightRotate53_64(a) (rightRotate_64((a), 53)) +#define rightRotate54_64(a) (rightRotate_64((a), 54)) +#define rightRotate55_64(a) (rightRotate_64((a), 55)) +#define rightRotate56_64(a) (rightRotate_64((a), 56)) +#define rightRotate57_64(a) (rightRotate_64((a), 57)) +#define rightRotate58_64(a) (rightRotate_64((a), 58)) +#define rightRotate59_64(a) (rightRotate_64((a), 59)) +#define rightRotate60_64(a) (rightRotate_64((a), 60)) +#define rightRotate61_64(a) (rightRotate_64((a), 61)) +#define rightRotate62_64(a) (rightRotate_64((a), 62)) +#define rightRotate63_64(a) (rightRotate_64((a), 63)) + +/* Rotate a 16-bit value left by a number of bits */ +#define leftRotate_16(a, bits) \ + (__extension__ ({ \ + uint16_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (16 - (bits))); \ + })) + +/* Rotate a 16-bit value right by a number of bits */ +#define rightRotate_16(a, bits) \ + (__extension__ ({ \ + uint16_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (16 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_16(a) (leftRotate_16((a), 1)) +#define leftRotate2_16(a) (leftRotate_16((a), 2)) +#define leftRotate3_16(a) (leftRotate_16((a), 3)) +#define leftRotate4_16(a) (leftRotate_16((a), 4)) +#define leftRotate5_16(a) (leftRotate_16((a), 5)) +#define leftRotate6_16(a) (leftRotate_16((a), 6)) +#define leftRotate7_16(a) (leftRotate_16((a), 7)) +#define leftRotate8_16(a) (leftRotate_16((a), 8)) +#define leftRotate9_16(a) (leftRotate_16((a), 9)) +#define leftRotate10_16(a) (leftRotate_16((a), 10)) +#define leftRotate11_16(a) (leftRotate_16((a), 11)) +#define leftRotate12_16(a) (leftRotate_16((a), 12)) +#define leftRotate13_16(a) (leftRotate_16((a), 13)) +#define leftRotate14_16(a) (leftRotate_16((a), 14)) +#define leftRotate15_16(a) (leftRotate_16((a), 15)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_16(a) (rightRotate_16((a), 1)) +#define rightRotate2_16(a) (rightRotate_16((a), 2)) +#define rightRotate3_16(a) (rightRotate_16((a), 3)) +#define rightRotate4_16(a) (rightRotate_16((a), 4)) +#define rightRotate5_16(a) (rightRotate_16((a), 5)) +#define rightRotate6_16(a) (rightRotate_16((a), 6)) +#define rightRotate7_16(a) (rightRotate_16((a), 7)) +#define rightRotate8_16(a) (rightRotate_16((a), 8)) +#define rightRotate9_16(a) (rightRotate_16((a), 9)) +#define rightRotate10_16(a) (rightRotate_16((a), 10)) +#define rightRotate11_16(a) (rightRotate_16((a), 11)) +#define rightRotate12_16(a) (rightRotate_16((a), 12)) +#define rightRotate13_16(a) (rightRotate_16((a), 13)) +#define rightRotate14_16(a) (rightRotate_16((a), 14)) +#define rightRotate15_16(a) (rightRotate_16((a), 15)) + +/* Rotate an 8-bit value left by a number of bits */ +#define leftRotate_8(a, bits) \ + (__extension__ ({ \ + uint8_t _temp = (a); \ + (_temp << (bits)) | (_temp >> (8 - (bits))); \ + })) + +/* Rotate an 8-bit value right by a number of bits */ +#define rightRotate_8(a, bits) \ + (__extension__ ({ \ + uint8_t _temp = (a); \ + (_temp >> (bits)) | (_temp << (8 - (bits))); \ + })) + +/* Left rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define leftRotate1_8(a) (leftRotate_8((a), 1)) +#define leftRotate2_8(a) (leftRotate_8((a), 2)) +#define leftRotate3_8(a) (leftRotate_8((a), 3)) +#define leftRotate4_8(a) (leftRotate_8((a), 4)) +#define leftRotate5_8(a) (leftRotate_8((a), 5)) +#define leftRotate6_8(a) (leftRotate_8((a), 6)) +#define leftRotate7_8(a) (leftRotate_8((a), 7)) + +/* Right rotate by a specific number of bits. These macros may be replaced + * with more efficient ones on platforms that lack a barrel shifter */ +#define rightRotate1_8(a) (rightRotate_8((a), 1)) +#define rightRotate2_8(a) (rightRotate_8((a), 2)) +#define rightRotate3_8(a) (rightRotate_8((a), 3)) +#define rightRotate4_8(a) (rightRotate_8((a), 4)) +#define rightRotate5_8(a) (rightRotate_8((a), 5)) +#define rightRotate6_8(a) (rightRotate_8((a), 6)) +#define rightRotate7_8(a) (rightRotate_8((a), 7)) + +#endif diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-aead.c b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-aead.c new file mode 100644 index 0000000..7558527 --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-aead.c @@ -0,0 +1,804 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "skinny-aead.h" +#include "internal-skinny128.h" +#include "internal-util.h" +#include + +aead_cipher_t const skinny_aead_m1_cipher = { + "SKINNY-AEAD-M1", + SKINNY_AEAD_KEY_SIZE, + SKINNY_AEAD_M1_NONCE_SIZE, + SKINNY_AEAD_M1_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + skinny_aead_m1_encrypt, + skinny_aead_m1_decrypt +}; + +aead_cipher_t const skinny_aead_m2_cipher = { + "SKINNY-AEAD-M2", + SKINNY_AEAD_KEY_SIZE, + SKINNY_AEAD_M2_NONCE_SIZE, + SKINNY_AEAD_M2_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + skinny_aead_m2_encrypt, + skinny_aead_m2_decrypt +}; + +aead_cipher_t const skinny_aead_m3_cipher = { + "SKINNY-AEAD-M3", + SKINNY_AEAD_KEY_SIZE, + SKINNY_AEAD_M3_NONCE_SIZE, + SKINNY_AEAD_M3_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + skinny_aead_m3_encrypt, + skinny_aead_m3_decrypt +}; + +aead_cipher_t const skinny_aead_m4_cipher = { + "SKINNY-AEAD-M4", + SKINNY_AEAD_KEY_SIZE, + SKINNY_AEAD_M4_NONCE_SIZE, + SKINNY_AEAD_M4_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + skinny_aead_m4_encrypt, + skinny_aead_m4_decrypt +}; + +aead_cipher_t const skinny_aead_m5_cipher = { + "SKINNY-AEAD-M5", + SKINNY_AEAD_KEY_SIZE, + SKINNY_AEAD_M5_NONCE_SIZE, + SKINNY_AEAD_M5_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + skinny_aead_m5_encrypt, + skinny_aead_m5_decrypt +}; + +aead_cipher_t const skinny_aead_m6_cipher = { + "SKINNY-AEAD-M6", + SKINNY_AEAD_KEY_SIZE, + SKINNY_AEAD_M6_NONCE_SIZE, + SKINNY_AEAD_M6_TAG_SIZE, + AEAD_FLAG_LITTLE_ENDIAN, + skinny_aead_m6_encrypt, + skinny_aead_m6_decrypt +}; + +/* Domain separator prefixes for all of the SKINNY-AEAD family members */ +#define DOMAIN_SEP_M1 0x00 +#define DOMAIN_SEP_M2 0x10 +#define DOMAIN_SEP_M3 0x08 +#define DOMAIN_SEP_M4 0x18 +#define DOMAIN_SEP_M5 0x10 +#define DOMAIN_SEP_M6 0x18 + +/** + * \brief Initialize the key and nonce for SKINNY-128-384 based AEAD schemes. + * + * \param ks The key schedule to initialize. + * \param key Points to the 16 bytes of the key. + * \param nonce Points to the nonce. + * \param nonce_len Length of the nonce in bytes. + */ +static void skinny_aead_128_384_init + (skinny_128_384_key_schedule_t *ks, const unsigned char *key, + const unsigned char *nonce, unsigned nonce_len) +{ + unsigned char k[48]; + memset(k, 0, 16); + memcpy(k + 16, nonce, nonce_len); + memset(k + 16 + nonce_len, 0, 16 - nonce_len); + memcpy(k + 32, key, 16); + skinny_128_384_init(ks, k); +} + +/** + * \brief Set the domain separation value in the tweak for SKINNY-128-384. + * + * \param ks Key schedule for the block cipher. + * \param d Domain separation value to write into the tweak. + */ +#define skinny_aead_128_384_set_domain(ks,d) ((ks)->TK1[15] = (d)) + +/** + * \brief Sets the LFSR field in the tweak for SKINNY-128-384. + * + * \param ks Key schedule for the block cipher. + * \param lfsr 64-bit LFSR value. + */ +#define skinny_aead_128_384_set_lfsr(ks,lfsr) le_store_word64((ks)->TK1, (lfsr)) + +/** + * \brief Updates the LFSR value for SKINNY-128-384. + * + * \param lfsr 64-bit LFSR value to be updated. + */ +#define skinny_aead_128_384_update_lfsr(lfsr) \ + do { \ + uint8_t feedback = ((lfsr) & (1ULL << 63)) ? 0x1B : 0x00; \ + (lfsr) = ((lfsr) << 1) ^ feedback; \ + } while (0) + +/** + * \brief Authenticates the associated data for a SKINNY-128-384 based AEAD. + * + * \param ks The key schedule to use. + * \param prefix Domain separation prefix for the family member. + * \param tag Final tag to XOR the authentication checksum into. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void skinny_aead_128_384_authenticate + (skinny_128_384_key_schedule_t *ks, unsigned char prefix, + unsigned char tag[SKINNY_128_BLOCK_SIZE], + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char block[SKINNY_128_BLOCK_SIZE]; + uint64_t lfsr = 1; + skinny_aead_128_384_set_domain(ks, prefix | 2); + while (adlen >= SKINNY_128_BLOCK_SIZE) { + skinny_aead_128_384_set_lfsr(ks, lfsr); + skinny_128_384_encrypt(ks, block, ad); + lw_xor_block(tag, block, SKINNY_128_BLOCK_SIZE); + ad += SKINNY_128_BLOCK_SIZE; + adlen -= SKINNY_128_BLOCK_SIZE; + skinny_aead_128_384_update_lfsr(lfsr); + } + if (adlen > 0) { + unsigned temp = (unsigned)adlen; + skinny_aead_128_384_set_lfsr(ks, lfsr); + skinny_aead_128_384_set_domain(ks, prefix | 3); + memcpy(block, ad, temp); + block[temp] = 0x80; + memset(block + temp + 1, 0, SKINNY_128_BLOCK_SIZE - temp - 1); + skinny_128_384_encrypt(ks, block, block); + lw_xor_block(tag, block, SKINNY_128_BLOCK_SIZE); + } +} + +/** + * \brief Encrypts the plaintext for a SKINNY-128-384 based AEAD. + * + * \param ks The key schedule to use. + * \param prefix Domain separation prefix for the family member. + * \param sum Authenticated checksum over the plaintext. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the plaintext buffer. + * \param mlen Number of bytes of plaintext to be encrypted. + */ +static void skinny_aead_128_384_encrypt + (skinny_128_384_key_schedule_t *ks, unsigned char prefix, + unsigned char sum[SKINNY_128_BLOCK_SIZE], unsigned char *c, + const unsigned char *m, unsigned long long mlen) +{ + unsigned char block[SKINNY_128_BLOCK_SIZE]; + uint64_t lfsr = 1; + memset(sum, 0, SKINNY_128_BLOCK_SIZE); + skinny_aead_128_384_set_domain(ks, prefix | 0); + while (mlen >= SKINNY_128_BLOCK_SIZE) { + skinny_aead_128_384_set_lfsr(ks, lfsr); + lw_xor_block(sum, m, SKINNY_128_BLOCK_SIZE); + skinny_128_384_encrypt(ks, c, m); + c += SKINNY_128_BLOCK_SIZE; + m += SKINNY_128_BLOCK_SIZE; + mlen -= SKINNY_128_BLOCK_SIZE; + skinny_aead_128_384_update_lfsr(lfsr); + } + skinny_aead_128_384_set_lfsr(ks, lfsr); + if (mlen > 0) { + unsigned temp = (unsigned)mlen; + skinny_aead_128_384_set_domain(ks, prefix | 1); + lw_xor_block(sum, m, temp); + sum[temp] ^= 0x80; + memset(block, 0, SKINNY_128_BLOCK_SIZE); + skinny_128_384_encrypt(ks, block, block); + lw_xor_block_2_src(c, block, m, temp); + skinny_aead_128_384_update_lfsr(lfsr); + skinny_aead_128_384_set_lfsr(ks, lfsr); + skinny_aead_128_384_set_domain(ks, prefix | 5); + } else { + skinny_aead_128_384_set_domain(ks, prefix | 4); + } + skinny_128_384_encrypt(ks, sum, sum); +} + +/** + * \brief Decrypts the ciphertext for a SKINNY-128-384 based AEAD. + * + * \param ks The key schedule to use. + * \param prefix Domain separation prefix for the family member. + * \param sum Authenticated checksum over the plaintext. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the ciphertext buffer. + * \param mlen Number of bytes of ciphertext to be decrypted. + */ +static void skinny_aead_128_384_decrypt + (skinny_128_384_key_schedule_t *ks, unsigned char prefix, + unsigned char sum[SKINNY_128_BLOCK_SIZE], unsigned char *m, + const unsigned char *c, unsigned long long mlen) +{ + unsigned char block[SKINNY_128_BLOCK_SIZE]; + uint64_t lfsr = 1; + memset(sum, 0, SKINNY_128_BLOCK_SIZE); + skinny_aead_128_384_set_domain(ks, prefix | 0); + while (mlen >= SKINNY_128_BLOCK_SIZE) { + skinny_aead_128_384_set_lfsr(ks, lfsr); + skinny_128_384_decrypt(ks, m, c); + lw_xor_block(sum, m, SKINNY_128_BLOCK_SIZE); + c += SKINNY_128_BLOCK_SIZE; + m += SKINNY_128_BLOCK_SIZE; + mlen -= SKINNY_128_BLOCK_SIZE; + skinny_aead_128_384_update_lfsr(lfsr); + } + skinny_aead_128_384_set_lfsr(ks, lfsr); + if (mlen > 0) { + unsigned temp = (unsigned)mlen; + skinny_aead_128_384_set_domain(ks, prefix | 1); + memset(block, 0, SKINNY_128_BLOCK_SIZE); + skinny_128_384_encrypt(ks, block, block); + lw_xor_block_2_src(m, block, c, temp); + lw_xor_block(sum, m, temp); + sum[temp] ^= 0x80; + skinny_aead_128_384_update_lfsr(lfsr); + skinny_aead_128_384_set_lfsr(ks, lfsr); + skinny_aead_128_384_set_domain(ks, prefix | 5); + } else { + skinny_aead_128_384_set_domain(ks, prefix | 4); + } + skinny_128_384_encrypt(ks, sum, sum); +} + +int skinny_aead_m1_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + SKINNY_AEAD_M1_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M1_NONCE_SIZE); + + /* Encrypt to plaintext to produce the ciphertext */ + skinny_aead_128_384_encrypt(&ks, DOMAIN_SEP_M1, sum, c, m, mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M1, sum, ad, adlen); + + /* Generate the authentication tag */ + memcpy(c + mlen, sum, SKINNY_AEAD_M1_TAG_SIZE); + return 0; +} + +int skinny_aead_m1_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < SKINNY_AEAD_M1_TAG_SIZE) + return -1; + *mlen = clen - SKINNY_AEAD_M1_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M1_NONCE_SIZE); + + /* Decrypt to ciphertext to produce the plaintext */ + skinny_aead_128_384_decrypt(&ks, DOMAIN_SEP_M1, sum, m, c, *mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M1, sum, ad, adlen); + + /* Check the authentication tag */ + return aead_check_tag(m, *mlen, sum, c + *mlen, SKINNY_AEAD_M1_TAG_SIZE); +} + +int skinny_aead_m2_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + SKINNY_AEAD_M2_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M2_NONCE_SIZE); + + /* Encrypt to plaintext to produce the ciphertext */ + skinny_aead_128_384_encrypt(&ks, DOMAIN_SEP_M2, sum, c, m, mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M2, sum, ad, adlen); + + /* Generate the authentication tag */ + memcpy(c + mlen, sum, SKINNY_AEAD_M2_TAG_SIZE); + return 0; +} + +int skinny_aead_m2_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < SKINNY_AEAD_M2_TAG_SIZE) + return -1; + *mlen = clen - SKINNY_AEAD_M2_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M2_NONCE_SIZE); + + /* Decrypt to ciphertext to produce the plaintext */ + skinny_aead_128_384_decrypt(&ks, DOMAIN_SEP_M2, sum, m, c, *mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M2, sum, ad, adlen); + + /* Check the authentication tag */ + return aead_check_tag(m, *mlen, sum, c + *mlen, SKINNY_AEAD_M2_TAG_SIZE); +} + +int skinny_aead_m3_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + SKINNY_AEAD_M3_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M3_NONCE_SIZE); + + /* Encrypt to plaintext to produce the ciphertext */ + skinny_aead_128_384_encrypt(&ks, DOMAIN_SEP_M3, sum, c, m, mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M3, sum, ad, adlen); + + /* Generate the authentication tag */ + memcpy(c + mlen, sum, SKINNY_AEAD_M3_TAG_SIZE); + return 0; +} + +int skinny_aead_m3_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < SKINNY_AEAD_M3_TAG_SIZE) + return -1; + *mlen = clen - SKINNY_AEAD_M3_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M3_NONCE_SIZE); + + /* Decrypt to ciphertext to produce the plaintext */ + skinny_aead_128_384_decrypt(&ks, DOMAIN_SEP_M3, sum, m, c, *mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M3, sum, ad, adlen); + + /* Check the authentication tag */ + return aead_check_tag(m, *mlen, sum, c + *mlen, SKINNY_AEAD_M3_TAG_SIZE); +} + +int skinny_aead_m4_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + SKINNY_AEAD_M4_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M4_NONCE_SIZE); + + /* Encrypt to plaintext to produce the ciphertext */ + skinny_aead_128_384_encrypt(&ks, DOMAIN_SEP_M4, sum, c, m, mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M4, sum, ad, adlen); + + /* Generate the authentication tag */ + memcpy(c + mlen, sum, SKINNY_AEAD_M4_TAG_SIZE); + return 0; +} + +int skinny_aead_m4_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_384_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < SKINNY_AEAD_M4_TAG_SIZE) + return -1; + *mlen = clen - SKINNY_AEAD_M4_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_384_init(&ks, k, npub, SKINNY_AEAD_M4_NONCE_SIZE); + + /* Decrypt to ciphertext to produce the plaintext */ + skinny_aead_128_384_decrypt(&ks, DOMAIN_SEP_M4, sum, m, c, *mlen); + + /* Process the associated data */ + skinny_aead_128_384_authenticate(&ks, DOMAIN_SEP_M4, sum, ad, adlen); + + /* Check the authentication tag */ + return aead_check_tag(m, *mlen, sum, c + *mlen, SKINNY_AEAD_M4_TAG_SIZE); +} + +/** + * \brief Initialize the key and nonce for SKINNY-128-256 based AEAD schemes. + * + * \param ks The key schedule to initialize. + * \param key Points to the 16 bytes of the key. + * \param nonce Points to the nonce. + * \param nonce_len Length of the nonce in bytes. + */ +static void skinny_aead_128_256_init + (skinny_128_256_key_schedule_t *ks, const unsigned char *key, + const unsigned char *nonce, unsigned nonce_len) +{ + unsigned char k[32]; + memset(k, 0, 16 - nonce_len); + memcpy(k + 16 - nonce_len, nonce, nonce_len); + memcpy(k + 16, key, 16); + skinny_128_256_init(ks, k); +} + +/** + * \brief Set the domain separation value in the tweak for SKINNY-128-256. + * + * \param ks Key schedule for the block cipher. + * \param d Domain separation value to write into the tweak. + */ +#define skinny_aead_128_256_set_domain(ks,d) ((ks)->TK1[3] = (d)) + +/** + * \brief Sets the LFSR field in the tweak for SKINNY-128-256. + * + * \param ks Key schedule for the block cipher. + * \param lfsr 24-bit LFSR value. + */ +#define skinny_aead_128_256_set_lfsr(ks,lfsr) \ + do { \ + (ks)->TK1[0] = (uint8_t)(lfsr); \ + (ks)->TK1[1] = (uint8_t)((lfsr) >> 8); \ + (ks)->TK1[2] = (uint8_t)((lfsr) >> 16); \ + } while (0) + +/** + * \brief Updates the LFSR value for SKINNY-128-256. + * + * \param lfsr 24-bit LFSR value to be updated. + */ +#define skinny_aead_128_256_update_lfsr(lfsr) \ + do { \ + uint32_t feedback = ((lfsr) & (((uint32_t)1) << 23)) ? 0x1B : 0x00; \ + (lfsr) = ((lfsr) << 1) ^ (feedback); \ + } while (0) + +/** + * \brief Authenticates the associated data for a SKINNY-128-256 based AEAD. + * + * \param ks The key schedule to use. + * \param prefix Domain separation prefix for the family member. + * \param tag Final tag to XOR the authentication checksum into. + * \param ad Points to the associated data. + * \param adlen Length of the associated data in bytes. + */ +static void skinny_aead_128_256_authenticate + (skinny_128_256_key_schedule_t *ks, unsigned char prefix, + unsigned char tag[SKINNY_128_BLOCK_SIZE], + const unsigned char *ad, unsigned long long adlen) +{ + unsigned char block[SKINNY_128_BLOCK_SIZE]; + uint32_t lfsr = 1; + skinny_aead_128_256_set_domain(ks, prefix | 2); + while (adlen >= SKINNY_128_BLOCK_SIZE) { + skinny_aead_128_256_set_lfsr(ks, lfsr); + skinny_128_256_encrypt(ks, block, ad); + lw_xor_block(tag, block, SKINNY_128_BLOCK_SIZE); + ad += SKINNY_128_BLOCK_SIZE; + adlen -= SKINNY_128_BLOCK_SIZE; + skinny_aead_128_256_update_lfsr(lfsr); + } + if (adlen > 0) { + unsigned temp = (unsigned)adlen; + skinny_aead_128_256_set_lfsr(ks, lfsr); + skinny_aead_128_256_set_domain(ks, prefix | 3); + memcpy(block, ad, temp); + block[temp] = 0x80; + memset(block + temp + 1, 0, SKINNY_128_BLOCK_SIZE - temp - 1); + skinny_128_256_encrypt(ks, block, block); + lw_xor_block(tag, block, SKINNY_128_BLOCK_SIZE); + } +} + +/** + * \brief Encrypts the plaintext for a SKINNY-128-256 based AEAD. + * + * \param ks The key schedule to use. + * \param prefix Domain separation prefix for the family member. + * \param sum Authenticated checksum over the plaintext. + * \param c Points to the buffer to receive the ciphertext. + * \param m Points to the plaintext buffer. + * \param mlen Number of bytes of plaintext to be encrypted. + */ +static void skinny_aead_128_256_encrypt + (skinny_128_256_key_schedule_t *ks, unsigned char prefix, + unsigned char sum[SKINNY_128_BLOCK_SIZE], unsigned char *c, + const unsigned char *m, unsigned long long mlen) +{ + unsigned char block[SKINNY_128_BLOCK_SIZE]; + uint32_t lfsr = 1; + memset(sum, 0, SKINNY_128_BLOCK_SIZE); + skinny_aead_128_256_set_domain(ks, prefix | 0); + while (mlen >= SKINNY_128_BLOCK_SIZE) { + skinny_aead_128_256_set_lfsr(ks, lfsr); + lw_xor_block(sum, m, SKINNY_128_BLOCK_SIZE); + skinny_128_256_encrypt(ks, c, m); + c += SKINNY_128_BLOCK_SIZE; + m += SKINNY_128_BLOCK_SIZE; + mlen -= SKINNY_128_BLOCK_SIZE; + skinny_aead_128_256_update_lfsr(lfsr); + } + skinny_aead_128_256_set_lfsr(ks, lfsr); + if (mlen > 0) { + unsigned temp = (unsigned)mlen; + skinny_aead_128_256_set_domain(ks, prefix | 1); + lw_xor_block(sum, m, temp); + sum[temp] ^= 0x80; + memset(block, 0, SKINNY_128_BLOCK_SIZE); + skinny_128_256_encrypt(ks, block, block); + lw_xor_block_2_src(c, block, m, temp); + skinny_aead_128_256_update_lfsr(lfsr); + skinny_aead_128_256_set_lfsr(ks, lfsr); + skinny_aead_128_256_set_domain(ks, prefix | 5); + } else { + skinny_aead_128_256_set_domain(ks, prefix | 4); + } + skinny_128_256_encrypt(ks, sum, sum); +} + +/** + * \brief Decrypts the ciphertext for a SKINNY-128-256 based AEAD. + * + * \param ks The key schedule to use. + * \param prefix Domain separation prefix for the family member. + * \param sum Authenticated checksum over the plaintext. + * \param m Points to the buffer to receive the plaintext. + * \param c Points to the ciphertext buffer. + * \param mlen Number of bytes of ciphertext to be decrypted. + */ +static void skinny_aead_128_256_decrypt + (skinny_128_256_key_schedule_t *ks, unsigned char prefix, + unsigned char sum[SKINNY_128_BLOCK_SIZE], unsigned char *m, + const unsigned char *c, unsigned long long mlen) +{ + unsigned char block[SKINNY_128_BLOCK_SIZE]; + uint32_t lfsr = 1; + memset(sum, 0, SKINNY_128_BLOCK_SIZE); + skinny_aead_128_256_set_domain(ks, prefix | 0); + while (mlen >= SKINNY_128_BLOCK_SIZE) { + skinny_aead_128_256_set_lfsr(ks, lfsr); + skinny_128_256_decrypt(ks, m, c); + lw_xor_block(sum, m, SKINNY_128_BLOCK_SIZE); + c += SKINNY_128_BLOCK_SIZE; + m += SKINNY_128_BLOCK_SIZE; + mlen -= SKINNY_128_BLOCK_SIZE; + skinny_aead_128_256_update_lfsr(lfsr); + } + skinny_aead_128_256_set_lfsr(ks, lfsr); + if (mlen > 0) { + unsigned temp = (unsigned)mlen; + skinny_aead_128_256_set_domain(ks, prefix | 1); + memset(block, 0, SKINNY_128_BLOCK_SIZE); + skinny_128_256_encrypt(ks, block, block); + lw_xor_block_2_src(m, block, c, temp); + lw_xor_block(sum, m, temp); + sum[temp] ^= 0x80; + skinny_aead_128_256_update_lfsr(lfsr); + skinny_aead_128_256_set_lfsr(ks, lfsr); + skinny_aead_128_256_set_domain(ks, prefix | 5); + } else { + skinny_aead_128_256_set_domain(ks, prefix | 4); + } + skinny_128_256_encrypt(ks, sum, sum); +} + +int skinny_aead_m5_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + SKINNY_AEAD_M5_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_256_init(&ks, k, npub, SKINNY_AEAD_M5_NONCE_SIZE); + + /* Encrypt to plaintext to produce the ciphertext */ + skinny_aead_128_256_encrypt(&ks, DOMAIN_SEP_M5, sum, c, m, mlen); + + /* Process the associated data */ + skinny_aead_128_256_authenticate(&ks, DOMAIN_SEP_M5, sum, ad, adlen); + + /* Generate the authentication tag */ + memcpy(c + mlen, sum, SKINNY_AEAD_M5_TAG_SIZE); + return 0; +} + +int skinny_aead_m5_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < SKINNY_AEAD_M5_TAG_SIZE) + return -1; + *mlen = clen - SKINNY_AEAD_M5_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_256_init(&ks, k, npub, SKINNY_AEAD_M5_NONCE_SIZE); + + /* Decrypt to ciphertext to produce the plaintext */ + skinny_aead_128_256_decrypt(&ks, DOMAIN_SEP_M5, sum, m, c, *mlen); + + /* Process the associated data */ + skinny_aead_128_256_authenticate(&ks, DOMAIN_SEP_M5, sum, ad, adlen); + + /* Check the authentication tag */ + return aead_check_tag(m, *mlen, sum, c + *mlen, SKINNY_AEAD_M5_TAG_SIZE); +} + +int skinny_aead_m6_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Set the length of the returned ciphertext */ + *clen = mlen + SKINNY_AEAD_M6_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_256_init(&ks, k, npub, SKINNY_AEAD_M6_NONCE_SIZE); + + /* Encrypt to plaintext to produce the ciphertext */ + skinny_aead_128_256_encrypt(&ks, DOMAIN_SEP_M6, sum, c, m, mlen); + + /* Process the associated data */ + skinny_aead_128_256_authenticate(&ks, DOMAIN_SEP_M6, sum, ad, adlen); + + /* Generate the authentication tag */ + memcpy(c + mlen, sum, SKINNY_AEAD_M6_TAG_SIZE); + return 0; +} + +int skinny_aead_m6_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + skinny_128_256_key_schedule_t ks; + unsigned char sum[SKINNY_128_BLOCK_SIZE]; + (void)nsec; + + /* Validate the ciphertext length and set the return "mlen" value */ + if (clen < SKINNY_AEAD_M6_TAG_SIZE) + return -1; + *mlen = clen - SKINNY_AEAD_M6_TAG_SIZE; + + /* Set up the key schedule with the key and the nonce */ + skinny_aead_128_256_init(&ks, k, npub, SKINNY_AEAD_M6_NONCE_SIZE); + + /* Decrypt to ciphertext to produce the plaintext */ + skinny_aead_128_256_decrypt(&ks, DOMAIN_SEP_M6, sum, m, c, *mlen); + + /* Process the associated data */ + skinny_aead_128_256_authenticate(&ks, DOMAIN_SEP_M6, sum, ad, adlen); + + /* Check the authentication tag */ + return aead_check_tag(m, *mlen, sum, c + *mlen, SKINNY_AEAD_M6_TAG_SIZE); +} diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-aead.h b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-aead.h new file mode 100644 index 0000000..c6b54fb --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-aead.h @@ -0,0 +1,518 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LWCRYPTO_SKINNY_AEAD_H +#define LWCRYPTO_SKINNY_AEAD_H + +#include "aead-common.h" + +/** + * \file skinny-aead.h + * \brief Authenticated encryption based on the SKINNY block cipher. + * + * SKINNY-AEAD is a family of authenticated encryption algorithms + * that are built around the SKINNY tweakable block cipher. There + * are six members in the family: + * + * \li SKINNY-AEAD-M1 has a 128-bit key, a 128-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. This is the + * primary member of the family. + * \li SKINNY-AEAD-M2 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li SKINNY-AEAD-M3 has a 128-bit key, a 128-bit nonce, and a 64-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li SKINNY-AEAD-M4 has a 128-bit key, a 96-bit nonce, and a 64-bit tag, + * based around the SKINNY-128-384 tweakable block cipher. + * \li SKINNY-AEAD-M5 has a 128-bit key, a 96-bit nonce, and a 128-bit tag, + * based around the SKINNY-128-256 tweakable block cipher. + * \li SKINNY-AEAD-M6 has a 128-bit key, a 96-bit nonce, and a 64-bit tag, + * based around the SKINNY-128-256 tweakable block cipher. + * + * The SKINNY-AEAD family also includes two hash algorithms: + * + * \li SKINNY-tk3-HASH with a 256-bit hash output, based around the + * SKINNY-128-384 tweakable block cipher. This is the primary hashing + * member of the family. + * \li SKINNY-tk2-HASH with a 256-bit hash output, based around the + * SKINNY-128-256 tweakable block cipher. + * + * References: https://sites.google.com/site/skinnycipher/home + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Size of the key for all SKINNY-AEAD family members. + */ +#define SKINNY_AEAD_KEY_SIZE 16 + +/** + * \brief Size of the authentication tag for SKINNY-AEAD-M1. + */ +#define SKINNY_AEAD_M1_TAG_SIZE 16 + +/** + * \brief Size of the nonce for SKINNY-AEAD-M1. + */ +#define SKINNY_AEAD_M1_NONCE_SIZE 16 + +/** + * \brief Size of the authentication tag for SKINNY-AEAD-M2. + */ +#define SKINNY_AEAD_M2_TAG_SIZE 16 + +/** + * \brief Size of the nonce for SKINNY-AEAD-M2. + */ +#define SKINNY_AEAD_M2_NONCE_SIZE 12 + +/** + * \brief Size of the authentication tag for SKINNY-AEAD-M3. + */ +#define SKINNY_AEAD_M3_TAG_SIZE 8 + +/** + * \brief Size of the nonce for SKINNY-AEAD-M3. + */ +#define SKINNY_AEAD_M3_NONCE_SIZE 16 + +/** + * \brief Size of the authentication tag for SKINNY-AEAD-M4. + */ +#define SKINNY_AEAD_M4_TAG_SIZE 8 + +/** + * \brief Size of the nonce for SKINNY-AEAD-M4. + */ +#define SKINNY_AEAD_M4_NONCE_SIZE 12 + +/** + * \brief Size of the authentication tag for SKINNY-AEAD-M5. + */ +#define SKINNY_AEAD_M5_TAG_SIZE 16 + +/** + * \brief Size of the nonce for SKINNY-AEAD-M5. + */ +#define SKINNY_AEAD_M5_NONCE_SIZE 12 + +/** + * \brief Size of the authentication tag for SKINNY-AEAD-M6. + */ +#define SKINNY_AEAD_M6_TAG_SIZE 8 + +/** + * \brief Size of the nonce for SKINNY-AEAD-M6. + */ +#define SKINNY_AEAD_M6_NONCE_SIZE 12 + +/** + * \brief Meta-information block for the SKINNY-AEAD-M1 cipher. + */ +extern aead_cipher_t const skinny_aead_m1_cipher; + +/** + * \brief Meta-information block for the SKINNY-AEAD-M2 cipher. + */ +extern aead_cipher_t const skinny_aead_m2_cipher; + +/** + * \brief Meta-information block for the SKINNY-AEAD-M3 cipher. + */ +extern aead_cipher_t const skinny_aead_m3_cipher; + +/** + * \brief Meta-information block for the SKINNY-AEAD-M4 cipher. + */ +extern aead_cipher_t const skinny_aead_m4_cipher; + +/** + * \brief Meta-information block for the SKINNY-AEAD-M5 cipher. + */ +extern aead_cipher_t const skinny_aead_m5_cipher; + +/** + * \brief Meta-information block for the SKINNY-AEAD-M6 cipher. + */ +extern aead_cipher_t const skinny_aead_m6_cipher; + +/** + * \brief Encrypts and authenticates a packet with SKINNY-AEAD-M1. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa skinny_aead_m1_decrypt() + */ +int skinny_aead_m1_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with SKINNY-AEAD-M1. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa skinny_aead_m1_encrypt() + */ +int skinny_aead_m1_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with SKINNY-AEAD-M2. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa skinny_aead_m2_decrypt() + */ +int skinny_aead_m2_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with SKINNY-AEAD-M2. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa skinny_aead_m2_encrypt() + */ +int skinny_aead_m2_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with SKINNY-AEAD-M3. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 8 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa skinny_aead_m3_decrypt() + */ +int skinny_aead_m3_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with SKINNY-AEAD-M3. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 8 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 16 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa skinny_aead_m3_encrypt() + */ +int skinny_aead_m3_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with SKINNY-AEAD-M4. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 8 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa skinny_aead_m4_decrypt() + */ +int skinny_aead_m4_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with SKINNY-AEAD-M4. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 8 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa skinny_aead_m4_encrypt() + */ +int skinny_aead_m4_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with SKINNY-AEAD-M5. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 16 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa skinny_aead_m5_decrypt() + */ +int skinny_aead_m5_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with SKINNY-AEAD-M5. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 16 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa skinny_aead_m5_encrypt() + */ +int skinny_aead_m5_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Encrypts and authenticates a packet with SKINNY-AEAD-M6. + * + * \param c Buffer to receive the output. + * \param clen On exit, set to the length of the output which includes + * the ciphertext and the 8 byte authentication tag. + * \param m Buffer that contains the plaintext message to encrypt. + * \param mlen Length of the plaintext message in bytes. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param nsec Secret nonce - not used by this algorithm. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to encrypt the packet. + * + * \return 0 on success, or a negative value if there was an error in + * the parameters. + * + * \sa skinny_aead_m6_decrypt() + */ +int skinny_aead_m6_encrypt + (unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +/** + * \brief Decrypts and authenticates a packet with SKINNY-AEAD-M6. + * + * \param m Buffer to receive the plaintext message on output. + * \param mlen Receives the length of the plaintext message on output. + * \param nsec Secret nonce - not used by this algorithm. + * \param c Buffer that contains the ciphertext and authentication + * tag to decrypt. + * \param clen Length of the input data in bytes, which includes the + * ciphertext and the 8 byte authentication tag. + * \param ad Buffer that contains associated data to authenticate + * along with the packet but which does not need to be encrypted. + * \param adlen Length of the associated data in bytes. + * \param npub Points to the public nonce for the packet which must + * be 12 bytes in length. + * \param k Points to the 16 bytes of the key to use to decrypt the packet. + * + * \return 0 on success, -1 if the authentication tag was incorrect, + * or some other negative number if there was an error in the parameters. + * + * \sa skinny_aead_m6_encrypt() + */ +int skinny_aead_m6_decrypt + (unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-hash.c b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-hash.c new file mode 100644 index 0000000..0abdeff --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-hash.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "skinny-hash.h" +#include "internal-skinny128.h" +#include "internal-util.h" +#include + +aead_hash_algorithm_t const skinny_tk3_hash_algorithm = { + "SKINNY-tk3-HASH", + sizeof(int), + SKINNY_HASH_SIZE, + AEAD_FLAG_NONE, + skinny_tk3_hash, + (aead_hash_init_t)0, + (aead_hash_update_t)0, + (aead_hash_finalize_t)0, + (aead_xof_absorb_t)0, + (aead_xof_squeeze_t)0 +}; + +aead_hash_algorithm_t const skinny_tk2_hash_algorithm = { + "SKINNY-tk2-HASH", + sizeof(int), + SKINNY_HASH_SIZE, + AEAD_FLAG_NONE, + skinny_tk2_hash, + (aead_hash_init_t)0, + (aead_hash_update_t)0, + (aead_hash_finalize_t)0, + (aead_xof_absorb_t)0, + (aead_xof_squeeze_t)0 +}; + +/** + * \brief Size of the permutation state for SKINNY-tk3-HASH. + */ +#define SKINNY_TK3_STATE_SIZE 48 + +/** + * \brief Size of the permutation state for SKINNY-tk2-HASH. + */ +#define SKINNY_TK2_STATE_SIZE 32 + +/** + * \brief Rate of absorbing data for SKINNY-tk3-HASH. + */ +#define SKINNY_TK3_HASH_RATE 16 + +/** + * \brief Rate of absorbing data for SKINNY-tk2-HASH. + */ +#define SKINNY_TK2_HASH_RATE 4 + +/** + * \brief Input block that is encrypted with the state for each + * block permutation of SKINNY-tk3-HASH or SKINNY-tk2-HASH. + */ +static unsigned char const skinny_hash_block[48] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/** + * \brief Permutes the internal state for SKINNY-tk3-HASH. + * + * \param state The state to be permuted. + */ +static void skinny_tk3_permute(unsigned char state[SKINNY_TK3_STATE_SIZE]) +{ + unsigned char temp[SKINNY_TK3_STATE_SIZE]; + skinny_128_384_encrypt_tk_full(state, temp, skinny_hash_block); + skinny_128_384_encrypt_tk_full(state, temp + 16, skinny_hash_block + 16); + skinny_128_384_encrypt_tk_full(state, temp + 32, skinny_hash_block + 32); + memcpy(state, temp, SKINNY_TK3_STATE_SIZE); +} + +/** + * \brief Permutes the internal state for SKINNY-tk2-HASH. + * + * \param state The state to be permuted. + */ +static void skinny_tk2_permute(unsigned char state[SKINNY_TK2_STATE_SIZE]) +{ + unsigned char temp[SKINNY_TK2_STATE_SIZE]; + skinny_128_256_encrypt_tk_full(state, temp, skinny_hash_block); + skinny_128_256_encrypt_tk_full(state, temp + 16, skinny_hash_block + 16); + memcpy(state, temp, SKINNY_TK2_STATE_SIZE); +} + +int skinny_tk3_hash + (unsigned char *out, const unsigned char *in, unsigned long long inlen) +{ + unsigned char state[SKINNY_TK3_STATE_SIZE]; + unsigned temp; + + /* Initialize the hash state */ + memset(state, 0, sizeof(state)); + state[SKINNY_TK3_HASH_RATE] = 0x80; + + /* Process as many full blocks as possible */ + while (inlen >= SKINNY_TK3_HASH_RATE) { + lw_xor_block(state, in, SKINNY_TK3_HASH_RATE); + skinny_tk3_permute(state); + in += SKINNY_TK3_HASH_RATE; + inlen -= SKINNY_TK3_HASH_RATE; + } + + /* Pad and process the last block */ + temp = (unsigned)inlen; + lw_xor_block(state, in, temp); + state[temp] ^= 0x80; /* padding */ + skinny_tk3_permute(state); + + /* Generate the hash output */ + memcpy(out, state, 16); + skinny_tk3_permute(state); + memcpy(out + 16, state, 16); + return 0; +} + +int skinny_tk2_hash + (unsigned char *out, const unsigned char *in, unsigned long long inlen) +{ + unsigned char state[SKINNY_TK2_STATE_SIZE]; + unsigned temp; + + /* Initialize the hash state */ + memset(state, 0, sizeof(state)); + state[SKINNY_TK2_HASH_RATE] = 0x80; + + /* Process as many full blocks as possible */ + while (inlen >= SKINNY_TK2_HASH_RATE) { + lw_xor_block(state, in, SKINNY_TK2_HASH_RATE); + skinny_tk2_permute(state); + in += SKINNY_TK2_HASH_RATE; + inlen -= SKINNY_TK2_HASH_RATE; + } + + /* Pad and process the last block */ + temp = (unsigned)inlen; + lw_xor_block(state, in, temp); + state[temp] ^= 0x80; /* padding */ + skinny_tk2_permute(state); + + /* Generate the hash output */ + memcpy(out, state, 16); + skinny_tk2_permute(state); + memcpy(out + 16, state, 16); + return 0; +} diff --git a/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-hash.h b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-hash.h new file mode 100644 index 0000000..f75ce9f --- /dev/null +++ b/skinny/Implementations/crypto_aead/skinnyaeadtk3128128+v1/rhys/skinny-hash.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef LWCRYPTO_SKINNY_HASH_H +#define LWCRYPTO_SKINNY_HASH_H + +#include "aead-common.h" + +/** + * \file skinny-hash.h + * \brief Hash algorithms based on the SKINNY block cipher. + * + * The SKINNY-AEAD family includes two hash algorithms: + * + * \li SKINNY-tk3-HASH with a 256-bit hash output, based around the + * SKINNY-128-384 tweakable block cipher. This is the primary hashing + * member of the family. + * \li SKINNY-tk2-HASH with a 256-bit hash output, based around the + * SKINNY-128-256 tweakable block cipher. + * + * References: https://sites.google.com/site/skinnycipher/home + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Size of the hash output for SKINNY-tk3-HASH and SKINNY-tk2-HASH. + */ +#define SKINNY_HASH_SIZE 32 + +/** + * \brief Meta-information block for the SKINNY-tk3-HASH algorithm. + */ +extern aead_hash_algorithm_t const skinny_tk3_hash_algorithm; + +/** + * \brief Meta-information block for the SKINNY-tk2-HASH algorithm. + */ +extern aead_hash_algorithm_t const skinny_tk2_hash_algorithm; + +/** + * \brief Hashes a block of input data with SKINNY-tk3-HASH to + * generate a hash value. + * + * \param out Buffer to receive the hash output which must be at least + * SKINNY_HASH_SIZE bytes in length. + * \param in Points to the input data to be hashed. + * \param inlen Length of the input data in bytes. + * + * \return Returns zero on success or -1 if there was an error in the + * parameters. + */ +int skinny_tk3_hash + (unsigned char *out, const unsigned char *in, unsigned long long inlen); + +/** + * \brief Hashes a block of input data with SKINNY-tk2-HASH to + * generate a hash value. + * + * \param out Buffer to receive the hash output which must be at least + * SKINNY_HASH_SIZE bytes in length. + * \param in Points to the input data to be hashed. + * \param inlen Length of the input data in bytes. + * + * \return Returns zero on success or -1 if there was an error in the + * parameters. + */ +int skinny_tk2_hash + (unsigned char *out, const unsigned char *in, unsigned long long inlen); + +#ifdef __cplusplus +} +#endif + +#endif