mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-07 21:53:41 +08:00
SM3 compress blocks
This commit is contained in:
119
crypto/sm3/sm3.c
119
crypto/sm3/sm3.c
@@ -53,6 +53,9 @@
|
|||||||
#include "internal/byteorder.h"
|
#include "internal/byteorder.h"
|
||||||
#include "modes_lcl.h"
|
#include "modes_lcl.h"
|
||||||
|
|
||||||
|
static void sm3_compress_blocks(uint32_t digest[8],
|
||||||
|
const unsigned char *data, size_t blocks);
|
||||||
|
|
||||||
void sm3_init(sm3_ctx_t *ctx)
|
void sm3_init(sm3_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
@@ -68,6 +71,8 @@ void sm3_init(sm3_ctx_t *ctx)
|
|||||||
|
|
||||||
void sm3_update(sm3_ctx_t *ctx, const unsigned char *data, size_t data_len)
|
void sm3_update(sm3_ctx_t *ctx, const unsigned char *data, size_t data_len)
|
||||||
{
|
{
|
||||||
|
size_t blocks = data_len / SM3_BLOCK_SIZE;
|
||||||
|
|
||||||
if (ctx->num) {
|
if (ctx->num) {
|
||||||
unsigned int left = SM3_BLOCK_SIZE - ctx->num;
|
unsigned int left = SM3_BLOCK_SIZE - ctx->num;
|
||||||
if (data_len < left) {
|
if (data_len < left) {
|
||||||
@@ -82,12 +87,12 @@ void sm3_update(sm3_ctx_t *ctx, const unsigned char *data, size_t data_len)
|
|||||||
data_len -= left;
|
data_len -= left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (data_len >= SM3_BLOCK_SIZE) {
|
|
||||||
sm3_compress(ctx->digest, data);
|
sm3_compress_blocks(ctx->digest, data, blocks);
|
||||||
ctx->nblocks++;
|
ctx->nblocks += blocks;
|
||||||
data += SM3_BLOCK_SIZE;
|
data += SM3_BLOCK_SIZE * blocks;
|
||||||
data_len -= SM3_BLOCK_SIZE;
|
data_len -= SM3_BLOCK_SIZE * blocks;
|
||||||
}
|
|
||||||
ctx->num = data_len;
|
ctx->num = data_len;
|
||||||
if (data_len) {
|
if (data_len) {
|
||||||
memcpy(ctx->block, data, data_len);
|
memcpy(ctx->block, data, data_len);
|
||||||
@@ -125,6 +130,27 @@ void sm3_final(sm3_ctx_t *ctx, unsigned char *digest)
|
|||||||
#define GG00(x,y,z) ((x) ^ (y) ^ (z))
|
#define GG00(x,y,z) ((x) ^ (y) ^ (z))
|
||||||
#define GG16(x,y,z) ((((y)^(z)) & (x)) ^ (z))
|
#define GG16(x,y,z) ((((y)^(z)) & (x)) ^ (z))
|
||||||
|
|
||||||
|
#define R(A, B, C, D, E, F, G, H, xx) \
|
||||||
|
SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); \
|
||||||
|
SS2 = SS1 ^ ROL32(A, 12); \
|
||||||
|
TT1 = FF##xx(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); \
|
||||||
|
TT2 = GG##xx(E, F, G) + H + SS1 + W[j]; \
|
||||||
|
B = ROL32(B, 9); \
|
||||||
|
H = TT1; \
|
||||||
|
F = ROL32(F, 19); \
|
||||||
|
D = P0(TT2); \
|
||||||
|
j++
|
||||||
|
|
||||||
|
#define R8(A, B, C, D, E, F, G, H, xx) \
|
||||||
|
R(A, B, C, D, E, F, G, H, xx); \
|
||||||
|
R(H, A, B, C, D, E, F, G, xx); \
|
||||||
|
R(G, H, A, B, C, D, E, F, xx); \
|
||||||
|
R(F, G, H, A, B, C, D, E, xx); \
|
||||||
|
R(E, F, G, H, A, B, C, D, xx); \
|
||||||
|
R(D, E, F, G, H, A, B, C, xx); \
|
||||||
|
R(C, D, E, F, G, H, A, B, xx); \
|
||||||
|
R(B, C, D, E, F, G, H, A, xx)
|
||||||
|
|
||||||
#define T00 0x79cc4519U
|
#define T00 0x79cc4519U
|
||||||
#define T16 0x7a879d8aU
|
#define T16 0x7a879d8aU
|
||||||
|
|
||||||
@@ -147,22 +173,34 @@ uint32_t K[64] = {
|
|||||||
0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U,
|
0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U,
|
||||||
};
|
};
|
||||||
|
|
||||||
void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
static void sm3_compress_blocks(uint32_t digest[8],
|
||||||
|
const unsigned char *data, size_t blocks)
|
||||||
{
|
{
|
||||||
uint32_t A = digest[0];
|
uint32_t A;
|
||||||
uint32_t B = digest[1];
|
uint32_t B;
|
||||||
uint32_t C = digest[2];
|
uint32_t C;
|
||||||
uint32_t D = digest[3];
|
uint32_t D;
|
||||||
uint32_t E = digest[4];
|
uint32_t E;
|
||||||
uint32_t F = digest[5];
|
uint32_t F;
|
||||||
uint32_t G = digest[6];
|
uint32_t G;
|
||||||
uint32_t H = digest[7];
|
uint32_t H;
|
||||||
uint32_t W[68];
|
uint32_t W[68];
|
||||||
uint32_t SS1, SS2, TT1, TT2;
|
uint32_t SS1, SS2, TT1, TT2;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
while (blocks--) {
|
||||||
|
|
||||||
|
A = digest[0];
|
||||||
|
B = digest[1];
|
||||||
|
C = digest[2];
|
||||||
|
D = digest[3];
|
||||||
|
E = digest[4];
|
||||||
|
F = digest[5];
|
||||||
|
G = digest[6];
|
||||||
|
H = digest[7];
|
||||||
|
|
||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
W[j] = GETU32(block + j*4);
|
W[j] = GETU32(data + j*4);
|
||||||
|
|
||||||
for (; j < 68; j++)
|
for (; j < 68; j++)
|
||||||
W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15))
|
W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15))
|
||||||
@@ -171,7 +209,16 @@ void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
|||||||
j = 0;
|
j = 0;
|
||||||
|
|
||||||
#define FULL_UNROLL
|
#define FULL_UNROLL
|
||||||
#ifndef FULL_UNROLL
|
#ifdef FULL_UNROLL
|
||||||
|
R8(A, B, C, D, E, F, G, H, 00);
|
||||||
|
R8(A, B, C, D, E, F, G, H, 00);
|
||||||
|
R8(A, B, C, D, E, F, G, H, 16);
|
||||||
|
R8(A, B, C, D, E, F, G, H, 16);
|
||||||
|
R8(A, B, C, D, E, F, G, H, 16);
|
||||||
|
R8(A, B, C, D, E, F, G, H, 16);
|
||||||
|
R8(A, B, C, D, E, F, G, H, 16);
|
||||||
|
R8(A, B, C, D, E, F, G, H, 16);
|
||||||
|
#else
|
||||||
for (; j < 16; j++) {
|
for (; j < 16; j++) {
|
||||||
SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7);
|
SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7);
|
||||||
SS2 = SS1 ^ ROL32(A, 12);
|
SS2 = SS1 ^ ROL32(A, 12);
|
||||||
@@ -201,36 +248,6 @@ void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
|||||||
F = E;
|
F = E;
|
||||||
E = P0(TT2);
|
E = P0(TT2);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
# define R(A, B, C, D, E, F, G, H, xx) \
|
|
||||||
SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); \
|
|
||||||
SS2 = SS1 ^ ROL32(A, 12); \
|
|
||||||
TT1 = FF##xx(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); \
|
|
||||||
TT2 = GG##xx(E, F, G) + H + SS1 + W[j]; \
|
|
||||||
B = ROL32(B, 9); \
|
|
||||||
H = TT1; \
|
|
||||||
F = ROL32(F, 19); \
|
|
||||||
D = P0(TT2); \
|
|
||||||
j++
|
|
||||||
|
|
||||||
# define R8(A, B, C, D, E, F, G, H, xx) \
|
|
||||||
R(A, B, C, D, E, F, G, H, xx); \
|
|
||||||
R(H, A, B, C, D, E, F, G, xx); \
|
|
||||||
R(G, H, A, B, C, D, E, F, xx); \
|
|
||||||
R(F, G, H, A, B, C, D, E, xx); \
|
|
||||||
R(E, F, G, H, A, B, C, D, xx); \
|
|
||||||
R(D, E, F, G, H, A, B, C, xx); \
|
|
||||||
R(C, D, E, F, G, H, A, B, xx); \
|
|
||||||
R(B, C, D, E, F, G, H, A, xx)
|
|
||||||
|
|
||||||
R8(A, B, C, D, E, F, G, H, 00);
|
|
||||||
R8(A, B, C, D, E, F, G, H, 00);
|
|
||||||
R8(A, B, C, D, E, F, G, H, 16);
|
|
||||||
R8(A, B, C, D, E, F, G, H, 16);
|
|
||||||
R8(A, B, C, D, E, F, G, H, 16);
|
|
||||||
R8(A, B, C, D, E, F, G, H, 16);
|
|
||||||
R8(A, B, C, D, E, F, G, H, 16);
|
|
||||||
R8(A, B, C, D, E, F, G, H, 16);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
digest[0] ^= A;
|
digest[0] ^= A;
|
||||||
@@ -241,6 +258,14 @@ void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
|||||||
digest[5] ^= F;
|
digest[5] ^= F;
|
||||||
digest[6] ^= G;
|
digest[6] ^= G;
|
||||||
digest[7] ^= H;
|
digest[7] ^= H;
|
||||||
|
|
||||||
|
data += 64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
||||||
|
{
|
||||||
|
return sm3_compress_blocks(digest, block, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3(const unsigned char *msg, size_t msglen,
|
void sm3(const unsigned char *msg, size_t msglen,
|
||||||
|
|||||||
Reference in New Issue
Block a user