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){
75 uint8_t buffer[10], tmp[2];
77 memcpy(buffer, key, 10);
78 memcpy(&(ctx->k[0]), buffer+2, 8);
80 /* rotate buffer 19 right */
81 memcpy(tmp, buffer, 2);
82 memmove(buffer, buffer+2, 8);
83 memcpy(buffer+8, tmp, 2);
84 /* three shifts to do*/
86 *((uint64_t*)buffer)>>=3;
87 *((uint16_t*)(buffer+8))>>=3;
88 buffer[9] |= tmp[1]<<5;
89 buffer[7] |= tmp[0]<<5;
90 /* rotating done now substitution */
91 buffer[9] = (sbox(buffer[9])&0xF0) | ((buffer[9])&0x0F);
92 /* xor with round counter */
93 *((uint16_t*)(buffer+1)) ^= (uint16_t)i<<7;
94 memcpy(&(ctx->k[i]), buffer+2, 8);
98 void present_enc(void* buffer, present_ctx_t* ctx){
101 *((uint64_t*)buffer) ^= ctx->k[i];
103 tmp[j] = sbox(((uint8_t*)buffer)[j]);
105 p((uint16_t*)buffer, tmp);
107 *((uint64_t*)buffer) ^= ctx->k[31];
111 void present_dec(void* buffer, present_ctx_t* ctx){
114 *((uint64_t*)buffer) ^= ctx->k[31];
116 for(i=30; i>=0; --i){
117 p_inv(tmp, (uint8_t*)buffer);
119 ((uint8_t*)buffer)[j] = sbox_inv(tmp[j]);
121 *((uint64_t*)buffer) ^= ctx->k[i];