📄 testphelix.c
字号:
{ /* count how many values are allowed */
#if PHELIX_MACSIZE(0) == PHELIX_MAXMACSIZE
i = 1;
#else
for (i=0;PHELIX_MACSIZE(i) <= PHELIX_MAXMACSIZE;i++) ;
assert(i > 0);
#endif
macSizeCnt = i;
}
for (i = Rand32() % macSizeCnt;PHELIX_MACSIZE(i) % mod;)
i=(i+1) % macSizeCnt;
return PHELIX_MACSIZE(i);
}
u32b RandKeySize(u32b mod)
{
static u32b keySizeCnt = 0;
u32b i;
if (keySizeCnt == 0)
{ /* count how many values are allowed */
#if PHELIX_KEYSIZE(0) == PHELIX_MAXKEYSIZE
i = 1;
#else
for (i=0;PHELIX_KEYSIZE(i) <= PHELIX_MAXKEYSIZE;i++) ;
assert(i > 0);
#endif
keySizeCnt = i;
}
for (i = Rand32() % keySizeCnt;PHELIX_KEYSIZE(i) % mod;)
i=(i+1) % keySizeCnt;
return PHELIX_KEYSIZE(i);
}
u32b RandNonceSize(u32b mod)
{
static u32b nonceSizeCnt = 0;
u32b i;
if (nonceSizeCnt == 0)
{ /* count how many values are allowed */
#if PHELIX_NONCESIZE(0) == PHELIX_MAXNONCESIZE
i = 1;
#else
for (i=0;PHELIX_NONCESIZE(i) <= PHELIX_MAXNONCESIZE;i++) ;
assert(i > 0);
#endif
nonceSizeCnt = i;
}
for (i = Rand32() % nonceSizeCnt;PHELIX_NONCESIZE(i) % mod;)
i=(i+1) % nonceSizeCnt;
return PHELIX_NONCESIZE(i);
}
u32b GetKeySize(u32b index)
{
static u32b keySizeCnt = 0;
u32b i;
if (keySizeCnt == 0)
{ /* count how many values are allowed */
for (i=0;PHELIX_KEYSIZE(i) <= PHELIX_MAXKEYSIZE;i++) ;
keySizeCnt = i;
assert(i > 0);
}
return PHELIX_KEYSIZE(index % keySizeCnt);
}
/*
****************************************************************
* Generate formatted KAT vectors for inclusion in "PhelixKAT.h"
****************************************************************
*/
void GenerateKAT(refStr fmtStr)
{
enum { ARRAY_CNT = 6 };
u32b j,k,n,r,xLen,vCnt;
u08b w[PHELIX_KEY_SIZE/8]; /* working key */
u08b * xPtr;
refStr xName;
TestVector v;
PhelixContext ctx;
const TestVector texVec[] = /* vectors for TeX paper */
{
{ 0,10,0,128,128, /* keySize, msgLen, aadLen, macSize */
/* key */ {0},
/* nonce */ {0},
/* aad */ {0},
/* pText */ {0}
},
{256,32,0,128,128, /* keySize, msgLen, aadLen, macSize */
/* key */ {0,0,0,0, 1,0,0,0, 2,0,0,0, 3,0,0,0,
4,0,0,0, 5,0,0,0, 6,0,0,0, 7,0,0,0},
/* nonce */ {0,0,0,1, 1,0,0,1, 2,0,0,1, 3,0,0,1},
/* aad */ {0},
/* pText */ {0,1,2,3, 1,2,3,4, 2,3,4,5, 3,4,5,6,
4,5,6,7, 5,6,7,8, 6,7,8,9, 7,8,9,10}
},
{128,0,0, 64,128, /* keySize, msgLen, aadLen, macSize */
/* key */ {1,2,3,4, 5,6,7,8, 8,7,6,5, 4,3,2,1},
/* nonce */ {4,0,0,0, 5,0,0,0, 6,0,0,0, 7,0,0,0},
/* aad */ {0},
/* pText */ {0}
},
{ 40,13,9, 96,128, /* keySize, msgLen, aadLen, macSize */
/* key */ {9,7,5,3, 1},
/* nonce */ {8,7,6,5, 4,3,2,1, 0,1,2,3, 4,5,6,7},
/* aad */ {0,2,4,6, 1,3,5,7, 8},
/* pText */ {0,1,2,3, 1,2,3,4, 2,3,4,5, 0xFF}
}
};
if (toupper(fmtStr[0]) == 'T')
{ /* generate KAT vectors for TeX document */
for (n=0;n<sizeof(texVec)/sizeof(texVec[0]);n++)
{
v = texVec[n];
PhelixSetupKey (&ctx,v.key,v.keySize,v.nonceSize,v.macSize);
PhelixEncryptPacket(PPv,v.pText,v.cText,v.msgLen,v.mac);
printf(" MAC tag: %-3d bits\n",v.macSize);
for (k=0;k<32;k++) /* set up w[] to show processed key (little-endian) */
w[k] = (u08b) ((ctx.ks.X_0[k/4] >> (8*(k%4))) & 0xFF);
for (k=0;k<=6;k++)
{
switch (k)
{
case 0: xPtr = v.key; xLen = v.keySize/8; xName = "Initial Key:"; break;
case 1: xPtr = w; xLen = 32; xName = "Working Key:"; break;
case 2: xPtr = v.nonce; xLen = sizeof(v.nonce); xName = "Nonce:"; break;
case 3: xPtr = v.aad; xLen = v.aadLen; xName = "AAD:"; break;
case 4: xPtr = v.pText; xLen = v.msgLen; xName = "Plaintext:"; break;
case 5: xPtr = v.cText; xLen = v.msgLen; xName = "Ciphertext:"; break;
case 6: xPtr = v.mac; xLen =(v.macSize+7)/8; xName = "MAC:"; break;
default:xPtr = NULL; xLen = 0; xName = NULL; break;
}
printf(" %-12s",xName);
if (xLen == 0)
printf(" <empty string>");
else for (j=0;j<xLen;j++)
{
if ((j % 4) == 0) printf(" ");
printf("%02X",xPtr[j]);
if (j == xLen-1) printf(" ");
else if ((j%16)==15) printf("\n%13s","");
else printf(" ");
}
printf("\n");
}
printf("\n");
}
return;
}
for (r=vCnt=0;r<4;r++)
for (n=0;n<=sizeof(v.pText);n++)
{
memset(&v,0,sizeof(v));
v.msgLen = sizeof(v.pText) - n;
v.nonceSize= PHELIX_NONCE_SIZE;
switch (r)
{
case 0: v.keySize = PHELIX_KEY_SIZE;
v.macSize = PHELIX_MAC_SIZE;
v.aadLen = 0; break;
case 1: v.keySize = GetKeySize(n);
v.macSize = RandMacSize(32);
v.aadLen = n % (sizeof(v.aad)+1); break;
case 2: v.keySize = RandKeySize(8);
v.macSize = RandMacSize(8);
v.aadLen = Rand32() % (sizeof(v.aad)+1); break;
default: v.keySize = RandKeySize(8);
v.macSize = RandMacSize(1);
v.nonceSize = RandNonceSize(1);
v.aadLen = Rand32() % (sizeof(v.aad)+1); break;
}
/* generate the (random) input data */
for (j=0;j<v.keySize/8; j++) v.key [j] = (u08b) ((r)? Rand08() : j );
for (j=0;j<sizeof(v.nonce);j++) v.nonce[j] = (u08b) ((r)? Rand08() : j+0x20);
for (j=0;j<v.aadLen; j++) v.aad [j] = (u08b) ((r)? Rand08() : j+0x40);
for (j=0;j<v.msgLen; j++) v.pText[j] = (u08b) ((r)? Rand08() : j+0x60);
/* perform the encryption */
PhelixSetupKey ( &ctx,v.key,v.keySize,v.nonceSize,v.macSize);
PhelixEncryptPacket(PPv,v.pText,v.cText,v.msgLen,v.mac);
/* now output the vector in C structure format */
printf("\n/* ---------- KAT vector #%3d ------------- */\n",++vCnt);
printf("{%4d,%4d,%4d,%4d,%4d, /* keySize, msgLen, aadLen, macSize, nonceSize */\n",
v.keySize,v.msgLen,v.aadLen,v.macSize,v.nonceSize);
for (k=0;k<ARRAY_CNT;k++)
{
switch (k)
{
case 0: xPtr = v.key; xLen = v.keySize/8; xName = "key"; break;
case 1: xPtr = v.nonce; xLen = sizeof(v.nonce); xName = "nonce"; break;
case 2: xPtr = v.aad; xLen = v.aadLen; xName = "aad"; break;
case 3: xPtr = v.pText; xLen = v.msgLen; xName = "pText"; break;
case 4: xPtr = v.cText; xLen = v.msgLen; xName = "cText"; break;
case 5: xPtr = v.mac; xLen =(v.macSize+7)/8; xName = "mac"; break;
/* default case here just to avoid uninitialized variable warning */
default:xPtr = NULL; xLen = 0; xName = NULL; break;
}
printf(" {");
for (j=0;j<xLen;j++)
{
printf("0x%02X",xPtr[j]);
if (j == xLen-1) printf("}");
else if ((j%16)==15) printf(",\n ");
else printf(",");
}
if (xLen == 0) printf("0x00}");
printf("%c /* %s */\n",(k==ARRAY_CNT-1)?' ':',',xName);
}
printf("},\n");
#ifdef ALLOW_DEBUG_IO
if (n == 16+r || vCnt == 1)
{ /* show internal details (as a C comment) for some KAT vectors */
_debugPhelix_ = 1;
printf("/**************************************************************\n"
" **** Phelix internal state (for debugging)\n"
" **************************************************************\n");
PhelixSetupKey(&ctx,v.key,v.keySize,v.nonceSize,v.macSize);
PhelixEncryptPacket(PPv,v.pText,v.cText,v.msgLen,v.mac);
printf("***************************************************************/\n\n");
_debugPhelix_ = 0;
}
#endif
}
}
/*
****************************************************************
* Process one packet (speed doesn't matter -- just function)
****************************************************************
*/
refStr MethodName(int method) /* name of the method (e.g., incremental vs all-in-one */
{
switch (method)
{
case 0: return "(all-in-one)";
case 1: return "(incremental)";
default: return NULL;
}
}
/* test the code of interest, map from ECRYPT to Phelix if necessary */
u32b ProcessPacket(int method,int action,PhelixPacketParms)
{
int doEncrypt = (action == 0);
u08b b,m[PHELIX_MAC_SIZE/8];
u32b k,n;
PhelixContext pc = *ctx;
/* generate small random steps toward the "full" length */
#define RandLen(k,n,len) \
k = (Rand08() & 1) ? 4 : (Rand32() % (len-n)) & ~3; \
if (k == 0) \
k = 4; /* minimum step size */ \
if (k > (len-n)) /* maximum step size */ \
k = len-n;
switch (method)
{
case 0: /* all-in-one */
if (doEncrypt)
{
PhelixEncryptPacket(&pc,nonce,aad,aadLen,src,dst,msgLen,mac);
return 0;
}
PhelixDecryptPacket(&pc,nonce,aad,aadLen,src,dst,msgLen,m);
break;
#ifndef MIX_ASM
case 1: /* incremental */
PhelixSetupNonce(&pc,nonce);
for (n=0;n<aadLen;n+=k) /* process AAD in variable-sized chunks */
{
RandLen(k,n,aadLen);
PhelixProcessAAD(&pc,aad+n,k);
}
for (n=0;n<msgLen;n+=k) /* process AAD in variable-sized chunks */
{
RandLen(k,n,msgLen);
if (doEncrypt)
PhelixEncryptBytes(&pc,src+n,dst+n,k);
else
PhelixDecryptBytes(&pc,src+n,dst+n,k);
}
if (doEncrypt)
{
PhelixFinalize(&pc,mac);
return 0;
}
else
{
PhelixFinalize(&pc,m);
break; /* go do the final compare */
}
#else
case 1: /* randomly intermix C and assembler calls to guarantee interoperability */
if (Rand32() & 1)
PhelixSetupNonce_ASM(&pc,nonce);
else
PhelixSetupNonce (&pc,nonce);
for (n=0;n<aadLen;n+=k) /* process AAD in variable-sized chunks */
{
RandLen(k,n,aadLen);
if (Rand32() & 1)
PhelixProcessAAD_ASM(&pc,aad+n,k);
else
PhelixProcessAAD (&pc,aad+n,k);
}
if (doEncrypt)
{
for (n=0;n<msgLen;n+=k) /* process AAD in variable-sized chunks */
{
RandLen(k,n,msgLen);
if (Rand32() & 1)
PhelixEncryptBytes_ASM(&pc,src+n,dst+n,k);
else
PhelixEncryptBytes (&pc,src+n,dst+n,k);
}
if (Rand32() & 1)
PhelixFinalize_ASM(&pc,mac);
else
PhelixFinalize (&pc,mac);
return 0;
}
else
{
for (n=0;n<msgLen;n+=k) /* process AAD in variable-sized chunks */
{
RandLen(k,n,msgLen);
if (Rand32() & 1)
PhelixDecryptBytes_ASM(&pc,src+n,dst+n,k);
else
PhelixDecryptBytes (&pc,src+n,dst+n,k);
}
if (Rand32() & 1)
PhelixFinalize_ASM(&pc,m);
else
PhelixFinalize (&pc,m);
break; /* go do the final compare */
}
#endif
default:
assert(method == 0);
return 1;
}
/* here only to do a decrypt MAC compare */
if (memcmp(mac,m,pc.ks.macSize/8)) /* do all the "full" bytes compare? */
return 1;
if (pc.ks.macSize % 8) /* any partial bytes? */
{
b = (u08b) (m[pc.ks.macSize/8] ^ mac[pc.ks.macSize/8]);
if (b & ((1 << (pc.ks.macSize % 8)) - 1))
return 1;
}
memcpy(mac,m,(pc.ks.macSize+7)/8);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -