3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * a implementation of the PRESENT block-cipher
23 * email: daniel.otte@rub.de
32 static uint8_t sbox(uint8_t b){
33 uint8_t sb[]={0xC, 0x5, 0x6, 0xB,
37 return (((sb[b>>4])<<4)|(sb[b&0xf]));
40 static uint8_t sbox_inv(uint8_t b){
41 uint8_t sb[]={0x5, 0xE, 0xF, 0x8,
45 return (((sb[b>>4])<<4)|(sb[b&0xf]));
48 #define SHR_O(a) c=(a)&1; (a)>>=1;
49 #define SHR_I(a) (a)=(c?0x8000:0x0000) | ((a)>>1);
51 static void p(uint16_t* o, uint8_t* i){
68 static void p_inv(uint8_t* o, uint8_t* i){
74 void present_init(const uint8_t* key, uint8_t keysize_b, present_ctx_t* ctx){
76 union __attribute__((packed)) {
80 struct __attribute__((packed)) {
89 memcpy(b.v8, key, 10);
90 memcpy(&(ctx->k[0]), b.v8+2, 8);
92 /* rotate buffer 19 right */
94 memmove(b.v8, b.v8+2, 8);
95 memcpy(b.v8+8, tmp, 2);
96 /* three shifts to do*/
100 b.v8[9] |= tmp[1]<<5;
101 b.v8[7] |= tmp[0]<<5;
102 /* rotating done now substitution */
103 b.v8[9] = (sbox(b.v8[9])&0xF0) | ((b.v8[9])&0x0F);
104 /* xor with round counter */
105 b.x.y.v16[0] ^= (uint16_t)i<<7;
106 memcpy(&(ctx->k[i]), b.v8+2, 8);
110 void present_enc(void* buffer, present_ctx_t* ctx){
113 *((uint64_t*)buffer) ^= ctx->k[i];
115 tmp[j] = sbox(((uint8_t*)buffer)[j]);
117 p((uint16_t*)buffer, tmp);
119 *((uint64_t*)buffer) ^= ctx->k[31];
123 void present_dec(void* buffer, present_ctx_t* ctx){
126 *((uint64_t*)buffer) ^= ctx->k[31];
128 for(i=30; i>=0; --i){
129 p_inv(tmp, (uint8_t*)buffer);
131 ((uint8_t*)buffer)[j] = sbox_inv(tmp[j]);
133 *((uint64_t*)buffer) ^= ctx->k[i];