104 lines
2.6 KiB
C
104 lines
2.6 KiB
C
//#include <intrin.h> // or x86intrin.h | x64intrin.h ?
|
|
#include <stdio.h>
|
|
#include <inttypes.h>
|
|
#include <string.h>
|
|
|
|
uint64_t _lrotl(uint64_t val, int shift) {
|
|
uint64_t hibit; /* non-zero means hi bit set */
|
|
uint64_t num = val; /* number to rotate */
|
|
shift &= 0x3f; /* modulo 64 -- this will also make
|
|
negative shifts work */
|
|
while (shift--) {
|
|
hibit = num & 0x8000000000000000; /* get high bit */
|
|
num <<= 1; /* shift left one bit */
|
|
if (hibit)
|
|
num |= 0x1; /* set lo bit if hi bit was set */
|
|
}
|
|
return num;
|
|
}
|
|
|
|
uint64_t _lrotr(uint64_t val, int shift) {
|
|
uint64_t lobit;
|
|
uint64_t num = val;
|
|
shift &= 0x3f;
|
|
while (shift--) {
|
|
lobit = num & 0x1;
|
|
num >>= 1;
|
|
if (lobit)
|
|
num |= 0x8000000000000000;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
#define LCS _lrotl // left circular shift
|
|
#define RCS _lrotr // right circular shift
|
|
#define u64 unsigned long long
|
|
#define R(x,y,k) (x=RCS(x,8) , x+=y, x^=k, y=LCS(y,3) , y^=x)
|
|
#define INV_R(x,y,k) (y^=x, y=RCS(y,3) , x^=k, x =y, x=LCS(x,8))
|
|
|
|
void Speck128ExpandKeyAndEncrypt(u64 pt [] , u64 ct [] , u64 K[]) {
|
|
u64 i,B=K[1],A=K[0];
|
|
ct[0]=pt[0]; ct[1]=pt[1];
|
|
for(i=0; i<32; i++) {
|
|
R(ct[1], ct[0], A); R(B, A, i);
|
|
}
|
|
}
|
|
|
|
void Speck128Encrypt(u64 pt[], u64 ct[], u64 k[]) {
|
|
u64 i;
|
|
ct[0]=pt[0]; ct[1]=pt[1];
|
|
for(i=0; i<32; i++) R(ct[1], ct[0], k[i]);
|
|
}
|
|
|
|
void Speck128Decrypt(u64 pt[], u64 ct[], u64 K[]) {
|
|
long long i;
|
|
for(i=31; i>=0; i--) {
|
|
INV_R(ct[1], ct[0], K[i]);
|
|
}
|
|
}
|
|
|
|
static void speck_keyexpand(u64 K[]) // OK
|
|
{
|
|
u64 tmp[32], *p;
|
|
memcpy(tmp,K, sizeof tmp);
|
|
// K[0] stays the same
|
|
u64 i;
|
|
for (i=0; i<(31);) {
|
|
p = tmp + (1+( i %(2 - 1)));
|
|
R(*p,tmp[0] , i );
|
|
++i ;
|
|
K[i] = tmp[0];
|
|
}
|
|
}
|
|
|
|
int main(void) {
|
|
u64 k[32];
|
|
k[1] = 0x0f0e0d0c0b0a0908;
|
|
k[0] = 0x0706050403020100;
|
|
|
|
u64 pt[2];
|
|
pt [1] = 0x6c61766975716520;
|
|
pt [0] = 0x7469206564616d20;
|
|
u64 ctverify [2];
|
|
|
|
ctverify [1] = 0xa65d985179783265;
|
|
ctverify [0] = 0x7860fedf5c570d18;
|
|
u64 ct[] = {0x0, 0x0};
|
|
|
|
// Speck128ExpandKeyAndEncrypt ( pt , ct, k);
|
|
speck_keyexpand (k);
|
|
Speck128Encrypt (pt, ct, k);
|
|
|
|
printf("ct[] = %llx %llx\n", ct[0], ct[1]);
|
|
|
|
if (( ct [1] == ctverify [1]) && ( ct [0] == ctverify [0]))
|
|
printf("Encryption Test Vector OK\n");
|
|
|
|
Speck128Decrypt ( pt, ct, k ) ;
|
|
printf("ct[] = %llx %llx\n", ct[0], ct[1]);
|
|
|
|
if ((ct[1] == pt[1]) && (ct[0] == pt[0]))
|
|
printf("Decryption Test Vector OK\n");
|
|
|
|
return 0;
|
|
}
|