- 论坛徽章:
- 0
|
sm3 加密算法,在Linux环境可以正常执行,但是在AIX环境,执行CF(压缩函数)时,执行到第33次计算,计算结果不对。
代码如下:
#include <string.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#include "sm3.h"
#define SHFR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define UNPACK32(x, str) \
{ \
*((str) + 3) = (uint8_t) ((x)); \
*((str) + 2) = (uint8_t) ((x) >> ; \
*((str) + 1) = (uint8_t) ((x) >> 16); \
*((str) + 0) = (uint8_t) ((x) >> 24);\
}
#define PACK32(str, x) \
{ \
*(x) =((uint32_t) * ((str) + 3)) \
|((uint32_t) * ((str) + 2) << \
|((uint32_t) *((str) +1) << 16) \
|((uint32_t) * ((str) +0) << 24);\
}
/*
* 置换函数P0
*/
#define P0(x) ((x)^(ROTL((x),9))^(ROTL((x),17)))
/*
* 置换函数SM3P1
*/
/*
* 问题:用下面的宏会导致Debug版和Release版不一致,且Release版不正确!
*/
#define SM3P1(x) ((x)^(ROTL((x),15))^(ROTL((x),23)))
/*static uint32_t sm3p1 (uint32_t x)
{
return (x) ^ ROTL ((x), 15) ^ (ROTL ((x), 23));
}*/
static uint32_t FF (uint32_t j, uint32_t A, uint32_t B, uint32_t C)
{
if (j < 16)
return ((A) ^ (B) ^ (C));
return (((A) & (B)) | ((A) & (C)) | ((B) & (C)));
}
static uint32_t GG (uint32_t j, uint32_t E, uint32_t F, uint32_t G)
{
if (j < 16)
return ((E) ^ (F) ^ (G));
return (((E) & (F)) | ((~(E)) & (G)));
}
static uint32_t sm3_h0[8] = {
0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e
};
static uint32_t sm3_t[64] = {
0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519,
0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x79cc4519, 0x7a879d8a, 0x7a879d8a,
0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a,
0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a,
0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a,
0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a,
0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a, 0x7a879d8a,
0x7a879d8a
};
/* SM3 functions */
/*
* 压缩函数
*/
static void CF (uint32_t * vj, uint32_t * vj1, uint32_t * w, uint32_t * wd)
{
uint32_t ss1, ss2, tt1, tt2;
// A->v[7] B->v[6] C->v[5] D->v[4] E->v[3] F->v[2] G->v[1] H->v[0]
uint32_t v[8];
int i, j;
for (i = 0; i < 8; i++)
v[i] = vj[7 - i];
for (j = 0; j < 64; j++)
{
#ifdef DEBUG
printf ("i=%02d ", j);
for (i = 7; i >= 0; i--)
{
printf ("%08X ", v[i]);
}
#endif // end of debug
ss1 = ROTL ((ROTL (v[7], 12) + v[3] + ROTL (sm3_t[j], j)), 7); // [(A<<12)+E+(Tj<<<j)]<<<7
ss2 = ss1 ^ ROTL (v[7], 12); // SS1 xor (A<<<12)
tt1 = (FF (j, v[7], v[6], v[5]) + v[4] + ss2) + wd[j]; // [FF(A,B,C) +D +SS2] +wdj
tt2 = GG (j, v[3], v[2], v[1]) + v[0] + ss1 + w[j];// tt2=[GG(E,F,G)+H+SS1]+wj
v[4] = v[5]; // D=C
v[5] = ROTL (v[6], 9); // C=B<<<9
v[6] = v[7]; // B=A
v[7] = tt1; // A=TT1
v[0] = v[1]; // H=G
v[1] = ROTL (v[2], 19); // G=F<<<19
v[2] = v[3]; // F=E
v[3] = P0 (tt2); // E=P0(TT2)
#ifdef DEBUG
printf ("\n" ;
#endif // end of debug
}
for (i = 0; i < 8; i++)
vj1[i] = v[i] ^ vj[7 - i];
#ifdef DEBUG
printf ("i=%02d ", j);
for (i = 7; i >= 0; i--)
{
printf ("%08X ", vj1[i]);
}
#endif // end of debug
}
static void sm3_transf (sm3_ctx * ctx, const uint8_t * message, uint32_t block_nb)
{
uint32_t w[68], wd[64];
uint32_t wv[8], wvr[8];
const uint8_t *sub_block;
int i;
int j;
for (i = 0; i < 8; i++)
{
wv[i] = 0;
wvr[i] = 0;
}
for (i = 0; i < (int) block_nb; i++)
{
sub_block = message + (i << 6);
//process a block message
//initializing
for (j = 0; j < 16; j++)
{
PACK32 (&sub_block[j << 2], &w[j]);
}
//expanding message
for (j = 16; j < 68; j++)
{
w[j] = (SM3P1 ((w[j - 16] ^ w[j - 9] ^ (ROTL (w[j - 3], 15))))) ^ (ROTL (w[j - 13], 7)) ^ w[j - 6];
}
for (j = 0; j < 64; j++)
wd[j] = w[j] ^ w[j + 4];
for (j = 0; j < 8; j++)
{
wv[j] = ctx->h[j];
}
CF (ctx->h, wvr, w, wd);
for (j = 0; j < 8; j++)
{
ctx->h[j] = wvr[7 - j];
}
}
}
void sm3 (const uint8_t * message, uint32_t len, uint8_t * const digest)
{
sm3_ctx ctx;
sm3_init (&ctx);
sm3_update (&ctx, message, len);
sm3_final (&ctx, digest);
}
void sm3_init (sm3_ctx * ctx)
{
int i;
for (i = 0; i < 8; i++)
{
ctx->h[i] = sm3_h0[i];
}
ctx->len = 0;
ctx->tot_len = 0;
}
void sm3_update (sm3_ctx * ctx, const uint8_t * message, uint32_t len)
{
uint32_t block_nb; //block numbers
uint32_t new_len, rem_len, tmp_len;
const uint8_t *shifted_message;
tmp_len = SM3_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy (&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SM3_BLOCK_SIZE)
{
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SM3_BLOCK_SIZE;
shifted_message = message + rem_len;
sm3_transf (ctx, ctx->block, 1);
sm3_transf (ctx, shifted_message, block_nb);
rem_len = new_len % SM3_BLOCK_SIZE;
memcpy (ctx->block, &shifted_message[block_nb << 6], rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 6;
}
void sm3_final (sm3_ctx * ctx, uint8_t * const digest)
{
uint32_t block_nb;
uint32_t pm_len;
uint32_t len_b;
int i;
block_nb = (1 + ((SM3_BLOCK_SIZE - 9) < (ctx->len % SM3_BLOCK_SIZE)));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 6;
memset (ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32 (len_b, ctx->block + pm_len - 4);
sm3_transf (ctx, ctx->block, block_nb);
for (i = 0; i < 8; i++)
{
UNPACK32 (ctx->h[i], &digest[i << 2]);
}
}
#ifdef TEST_VECTORS
/* FIPS 180-2 Validation tests */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void test (const char *vector, unsigned char *digest, unsigned int digest_size)
{
char output[2 * SM3_DIGEST_SIZE + 1];
int i;
output[2 * digest_size] = '\0';
for (i = 0; i < (int) digest_size; i++)
{
sprintf (output + 2 * i, "%02x", digest[i]);
} printf ("\nH: %s\n", output);
if (strcmp (vector, output))
{
fprintf (stderr, "Test failed.\n" ;
exit (EXIT_FAILURE);
}
}
#ifdef __cplusplus
#include <cstdint>
#else
#include <stdint.h>
#endif
__inline__ uint64_t rdtsc(void) {
uint32_t lo, hi;
__asm__ __volatile__ (
" xorl %%eax,%%eax \n"
" cpuid" // serialize
::: "%rax", "%rbx", "%rcx", "%rdx" ;
/* We cannot use "=A", since this would use %rax on x86_64 and return only the lower 32bits of the TSC */
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (uint64_t)hi << 32 | lo;
}
int main (void)
{
static const char *vectors[1][2] = {
/* SM3 Testing Vectors */
{"66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0",
"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732",
},
};
static const char message1[] = "abc";
static const char message2[] = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";
unsigned char digest[SM3_DIGEST_SIZE];
printf ("SM3 Validation tests\n\n" ;
printf ("SM3 Test vectors\n" ;
sm3 ((const unsigned char *) message1, strlen (message1), digest);
test (vectors[0][0], digest, SM3_DIGEST_SIZE);
sm3 ((const unsigned char *) message2, strlen (message2), digest);
test (vectors[0][1], digest, SM3_DIGEST_SIZE);
printf ("\nPerformance Testing......\n" ;
uint64_t t0,t1;
clock_t start,end;
start=clock();
t0 =rdtsc();
sm3 ((const unsigned char *) message2, strlen (message2), digest);
t1=rdtsc();
printf("sm3 %d bytes elapsed %d cycles\n", strlen(message2), t1-t0);
int i,max=1000000,m2_len=strlen(message2);
t0=rdtsc();
sm3_ctx ctx;
sm3_init(&ctx);
for(i=0;i<max;i++)
sm3_update(&ctx,message2,m2_len);
sm3_final(&ctx,digest);
t1=rdtsc();
end=clock();
printf("sm3 processed %d bytes( or %8.2f MB) elapsed %d cycles or %8.2f second(s)\nThroughput = %8.2f MB/sec\n", max*m2_len,max*m2_len*1.0/1024/1024, t1-t0, (t1-t0)/1.2/100000000, (max*m2_len*1.0/1024/1024)/((end-start)/CLOCKS_PER_SEC));
printf ("All tests passed.\n" ;
return 0;
}
#endif /* TEST_VECTORS */
/*
* indent -gnu -i4 -bl4 -bl -bli0 -pcs -nut -bls -cli0 -bad -bap -npsl -nprs -l120 sm3.c
*/
|
|