📄 pgpsha384_512.c
字号:
and( &T2, &r.g );
xor( &T1, &T2 ); /* T1 = Ch(e,f,g) */
add( &T1, &r.h );
add( &T1, &T3 );
add( &T1, K+t );
add( &T1, W+t );
/* calculate T2 = ( S(r.a,28) ^ S(r.a,34) ^ S(r.a,39) ) + (= Sum0(a))
( (r.a & r.b) ^ (r.a & r.c) ^ (r.b & r.c) ); (= Maj(a,b,c)) */
S_l( &T2, &r.a, 28 );
S_h( &T3, &r.a, 34 & (32-1) );
xor( &T2, &T3 );
S_h( &T3, &r.a, 39 & (32-1) );
xor( &T2, &T3 ); /* T2 = Sum0(a) */
T3 = r.b;
and( &T3, &r.a );
T4 = r.c;
and( &T4, &r.a );
xor( &T3, &T4 );
T4 = r.b;
and( &T4, &r.c );
xor( &T3, &T4 ); /* T3 = Maj(a,b,c) */
add( &T2, &T3 );
r.h = r.g;
r.g = r.f;
r.f = r.e;
r.e = r.d; add( &r.e, &T1 );
r.d = r.c;
r.c = r.b;
r.b = r.a;
r.a = T1; add( &r.a, &T2 );
/*#ifdef SHA512_TEST
printf( "[%02d] ", t );
SHA512_PRINT(&r);
#endif*/
}
/* finally, add new registers to old; result becomes new hash */
/* unroll this loop */
add( &H->a, &r.a );
add( &H->b, &r.b );
add( &H->c, &r.c );
add( &H->d, &r.d );
add( &H->e, &r.e );
add( &H->f, &r.f );
add( &H->g, &r.g );
add( &H->h, &r.h );
/* SHA512_PRINT(H); */
}
/* processes up to 1024 bit message block M, output is a 512 bit hash in H.
Words in M are big endian.
Exact length of M in bytes is in 'length'.
Total hashed length is in total_length, also in bytes.
Length is expected to always be even to 8 bit (because we work with bytes)
*/
static void sha512_finalize( SHA512_REGS * const H,
const sha512_message M[] /* points to double size buffer */,
unsigned length, sha512_length * const total_length )
{
int padding_length;
unsigned two=0;
pgpAssert( length < 1024/8 );
((PGPByte *)M)[length] = 0x80;
/* padding_length = block size - length(M) - length(10000000b) - length(total_length) */
padding_length = 1024/8 - length - 1 - 128/8;
if( padding_length < 0 ) { /* extra block */
padding_length += 1024/8;
two = 1;
}
memset( (PGPByte *)M+length+1, 0, padding_length );
sha512Mul8( total_length ); /* total_length *= 8 */
swap_sha512_word( (sha512_word *)((PGPByte *)M+length+1+padding_length), &total_length->high );
swap_sha512_word( (sha512_word *)((PGPByte *)M+length+1+padding_length)+1, &total_length->low );
sha512_process( H, M );
if( two )
sha512_process( H, M+1 );
sha256WordSwapInPlace( (sha512_word*)H, sizeof(*H)/sizeof(sha512_word) );
}
typedef struct PGPSHA512Context_
{
sha512_message M[2];/* partial message block */
SHA512_REGS H; /* SHA-512 registers */
sha512_length l; /* 128 bit length */
} PGPSHA512Context;
/* Initialize the SHA values */
static void
pgpSHA384Init(void *priv)
{
PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
memset( ctx, 0, sizeof(*ctx) );
sha384_init( &(ctx->H) );
}
static void
pgpSHA512Init(void *priv)
{
PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
memset( ctx, 0, sizeof(*ctx) );
sha512_init( &(ctx->H) );
}
/* Update SHA for a block of data. */
static void
pgpSHA384_512Update( void *priv, void const *bufIn, PGPSize len)
{
PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
unsigned const old_tail= (unsigned)(ctx->l.low.low & (1024/8 - 1));
unsigned blocks;
unsigned tail;
unsigned i;
const PGPByte *buf = bufIn;
sha512Add( &(ctx->l), len ); /* first, update number of processed bytes */
i = sizeof(sha512_message)-old_tail; /* bytes to add to the message block */
if( i>len ) { /* still have no complete block */
memcpy( ((PGPByte*)ctx->M) + old_tail, buf, len );
return;
}
if( old_tail ) {
memcpy( ((PGPByte*)ctx->M) + old_tail, buf, i );
buf += i;
len -= i;
sha512_process( &(ctx->H), (const sha512_message*)ctx->M );
}
blocks = len / (1024/8);
tail = len & (1024/8 - 1);
for( i=0; i<blocks; i++ )
sha512_process( &(ctx->H), ((const sha512_message*)buf)+i );
if( tail )
memcpy( ctx->M, ((const sha512_message*)buf)+blocks, tail );
}
#ifdef SHA512_TEST
/* prints SHA-512 result after pgpSHA384_512Finalize was called, or
prints intermediate SHA-512 registers */
static void pgpSHA512Print( PGPSHA512Context *ctx ) {
sha512_print( &(ctx->H) );
}
#endif
static void const *
pgpSHA384_512Finalize(void *priv)
{
PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
sha512_finalize( &(ctx->H), (const sha512_message *)ctx->M,
(unsigned)(ctx->l.low.low & (1024/8 - 1)), &(ctx->l) );
return &(ctx->H);
}
/*
* SHA384 has an OID of 2.16.840.1.101.3.4.2.2
* SHA512 has an OID of 2.16.840.1.101.3.4.2.3
* From draft-ietf-openpgp-rfc2440bis-03.txt
*/
static PGPByte const SHA384DERprefix[] = {
0x30, /* Universal, Constructed, Sequence */
0x41, /* Length 65 (bytes following) */
0x30, /* Universal, Constructed, Sequence */
0x0d, /* Length 13 */
0x06, /* Universal, Primitive, object-identifier */
0x09, /* Length 9 */
96, /* 96 = ISO(2)*40 + 16 */
0x86, 0x48,
1,
101,
3,
4,
2,
2,
0x05, /* Universal, Primitive, NULL */
0x00, /* Length 0 */
0x04, /* Universal, Primitive, Octet string */
0x30 /* Length 48 */
/* 48 SHA384 digest bytes go here */
};
static PGPByte const SHA512DERprefix[] = {
0x30, /* Universal, Constructed, Sequence */
0x51, /* Length 81 (bytes following) */
0x30, /* Universal, Constructed, Sequence */
0x0d, /* Length 13 */
0x06, /* Universal, Primitive, object-identifier */
0x09, /* Length 9 */
96, /* 96 = ISO(2)*40 + 16 */
0x86, 0x48,
1,
101,
3,
4,
2,
3,
0x05, /* Universal, Primitive, NULL */
0x00, /* Length 0 */
0x04, /* Universal, Primitive, Octet string */
0x40 /* Length 64 */
/* 64 SHA512 digest bytes go here */
};
PGPHashVTBL const HashSHA384 = {
"SHA384", kPGPHashAlgorithm_SHA384,
SHA384DERprefix, sizeof(SHA384DERprefix),
384/8,
1024/8,
sizeof(PGPSHA512Context),
sizeof(struct{char _a; PGPSHA512Context _b;}) -
sizeof(PGPSHA512Context),
pgpSHA384Init, pgpSHA384_512Update, pgpSHA384_512Finalize
};
PGPHashVTBL const HashSHA512 = {
"SHA512", kPGPHashAlgorithm_SHA512,
SHA512DERprefix, sizeof(SHA512DERprefix),
512/8,
1024/8,
sizeof(PGPSHA512Context),
sizeof(struct{char _a; PGPSHA512Context _b;}) -
sizeof(PGPSHA512Context),
pgpSHA512Init, pgpSHA384_512Update, pgpSHA384_512Finalize
};
#ifdef SHA512_TEST
static void test(unsigned is384) {
unsigned i,j;
time_t t;
PGPByte test1[] = "abc";
PGPByte test2[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
PGPByte test3[sizeof(sha512_message)];
PGPSHA512Context ctx;
printf("Beginning SHA %s test\n", is384 ? "384" : "512");
is384 ? pgpSHA384Init( &ctx ) : pgpSHA512Init( &ctx );
pgpSHA384_512Update( &ctx, test1, sizeof(test1)-1 );
pgpSHA384_512Finalize( &ctx );
pgpSHA512Print( &ctx );
is384 ? pgpSHA384Init( &ctx ) : pgpSHA512Init( &ctx );
pgpSHA384_512Update( &ctx, test2, sizeof(test2)-1 );
pgpSHA384_512Finalize( &ctx );
pgpSHA512Print( &ctx );
memset(test3, 'a', sizeof(test3));
t = time(NULL);
for(j=0; j<1; j++ ) {
is384 ? pgpSHA384Init( &ctx ) : pgpSHA512Init( &ctx );
for( i=1000000; i>=sizeof(test3); i-=sizeof(test3) )
pgpSHA384_512Update( &ctx, test3, sizeof(test3) );
pgpSHA384_512Update( &ctx, test3, i );
pgpSHA384_512Finalize( &ctx );
}
printf( "%d sec\n", time(NULL)-t );
pgpSHA512Print( &ctx );
}
void main() {
test(1);
test(0);
getchar();
}
#endif
#endif /* PGP_HAVE64 ] */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -