iOS SM3序列化加密算法,不可逆

2020-12-01  本文已影响0人  移动的键盘
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface ShgSM3OC : NSObject

///  SM3 加密算法,不可逆
/// @param data 需要加密的数据
/// @param callBack 回调数据 data:加密的数据 ,base64:加密数据以base64串形似返回,hex:加密数据以16进制串返回
+ (void)sm3Encryto:(NSData *)data finish:(void (^)(NSData *data,NSString *base64,NSString *hex))callBack;

@end

NS_ASSUME_NONNULL_END

.m实现

#import "ShgSM3OC.h"

typedef unsigned char ShgUnsignedChar;

typedef unsigned long ShgUnsignedLong;

typedef const char ShgConstChar;

typedef int ShgInt;

typedef uint32_t ShgUInt32;

#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i)                             \
{                                                       \
(n) = ( (ShgUInt32) (b)[(i)    ] << 24 )        \
| ( (ShgUInt32) (b)[(i) + 1] << 16 )        \
| ( (ShgUInt32) (b)[(i) + 2] <<  8 )        \
| ( (ShgUInt32) (b)[(i) + 3]       );       \
}
#endif

#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i)                             \
{                                                       \
(b)[(i)    ] = (ShgUnsignedChar) ( (n) >> 24 );       \
(b)[(i) + 1] = (ShgUnsignedChar) ( (n) >> 16 );       \
(b)[(i) + 2] = (ShgUnsignedChar) ( (n) >>  8 );       \
(b)[(i) + 3] = (ShgUnsignedChar) ( (n)       );       \
}
#endif

typedef struct {

ShgUnsignedLong total[2];

ShgUnsignedLong state[8];

ShgUnsignedChar buffer[64];

ShgUnsignedChar inpading[64];

ShgUnsignedChar outpading[64];

}ShgSm3Context;

static const ShgUnsignedChar ShgSm3Padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

@implementation ShgSM3OC


+ (void)sm3Encryto:(NSData *)data finish:(void (^)(NSData *, NSString *, NSString *))callBack
{
if (data == nil) {
    callBack(nil,nil,nil);
    return;
}

if (data.length == 0) {
    callBack(nil,nil,nil);
    return;
}

ShgInt inputLenght = (ShgInt)data.length;

ShgUnsignedChar inputChar[inputLenght];

memcpy(inputChar, data.bytes, inputLenght);

ShgInt outLenght = 32;

ShgUnsignedChar output[outLenght];

ShgSm3Context ctx;

[self shgSm3Starts:&ctx];

[self shgSm3Update:&ctx input:inputChar inLength:inputLenght];

[self shgSm3Finish:&ctx output:output];

memset(&ctx, 0, sizeof(ShgSm3Context));

NSData *outData = [[NSData alloc] initWithBytes:output length:outLenght];

NSMutableString *hexstr = @"".mutableCopy;

for (ShgInt i = 0; i < outLenght; i++) {
    [hexstr appendFormat:@"%02x",output[i]];
}

NSString *base64 = [outData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

callBack(outData,base64,hexstr.mutableCopy);
}

+ (void)shgSm3Starts:(ShgSm3Context *)ctx
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x7380166F;
ctx->state[1] = 0x4914B2B9;
ctx->state[2] = 0x172442D7;
ctx->state[3] = 0xDA8A0600;
ctx->state[4] = 0xA96F30BC;
ctx->state[5] = 0x163138AA;
ctx->state[6] = 0xE38DEE4D;
ctx->state[7] = 0xB0FB0E4E;
}

+ (void)shgSm3Update:(ShgSm3Context *)ctx input:(ShgUnsignedChar *)input inLength:(ShgInt)ilen
{
ShgInt fill;

ShgUInt32  left;

if (ilen <= 0) {
    return;
}

left = ctx->total[0] & 0x3F;

fill = 64 - left;

ctx->total[0] += ilen;

ctx->total[0] &= 0xFFFFFFFF;

if (ctx->total[0] < (ShgUInt32)ilen) {
    ctx->total[1]++;
}

if (left && ilen >= fill) {
    memcpy((void *)(ctx->buffer + left),(void *)input, fill);
    
    [self shgSm3Process:ctx data:ctx->buffer];
    
    input += fill;
    
    ilen  -= fill;
    
    left = 0;
}

while(ilen >= 64)
{
    [self shgSm3Process:ctx data:input];
    
    input += 64;
    
    ilen  -= 64;
}

if (ilen > 0) {
    memcpy((void *)(ctx->buffer + left),(void *)input, ilen);
}
}

+ (void)shgSm3Finish:(ShgSm3Context *)ctx output:(ShgUnsignedChar[32])output
{
ShgUInt32  last, padn;

ShgUInt32  high, low;

ShgUnsignedChar msglen[8];

high = (ShgUInt32)((ctx->total[0] >> 29) | (ctx->total[1] <<  3));

low  = (ShgUInt32)(ctx->total[0] << 3);

PUT_ULONG_BE( high, msglen, 0 );
PUT_ULONG_BE( low,  msglen, 4 );

last = ctx->total[0] & 0x3F;

padn = (last < 56) ? (56 - last) : (120 - last);

[self shgSm3Update:ctx input:(ShgUnsignedChar *)ShgSm3Padding inLength:padn];

[self shgSm3Update:ctx input:msglen inLength:8];

PUT_ULONG_BE( ctx->state[0], output,  0 );
PUT_ULONG_BE( ctx->state[1], output,  4 );
PUT_ULONG_BE( ctx->state[2], output,  8 );
PUT_ULONG_BE( ctx->state[3], output, 12 );
PUT_ULONG_BE( ctx->state[4], output, 16 );
PUT_ULONG_BE( ctx->state[5], output, 20 );
PUT_ULONG_BE( ctx->state[6], output, 24 );
PUT_ULONG_BE( ctx->state[7], output, 28 );
}

+ (void)shgSm3Process:(ShgSm3Context *)ctx data:(ShgUnsignedChar[64])data
{
ShgUInt32  SS1, SS2, TT1, TT2, W[68],W1[64];

ShgUInt32  A, B, C, D, E, F, G, H;

ShgUInt32  T[64];

ShgUInt32  Temp1,Temp2,Temp3,Temp4,Temp5;

for(ShgInt j = 0; j < 16; j++) {
    T[j] = 0x79CC4519;
}
for(ShgInt j =16; j < 64; j++) {
    T[j] = 0x7A879D8A;
}

GET_ULONG_BE( W[ 0], data, 0 );
GET_ULONG_BE( W[ 1], data,  4 );
GET_ULONG_BE( W[ 2], data,  8 );
GET_ULONG_BE( W[ 3], data, 12 );
GET_ULONG_BE( W[ 4], data, 16 );
GET_ULONG_BE( W[ 5], data, 20 );
GET_ULONG_BE( W[ 6], data, 24 );
GET_ULONG_BE( W[ 7], data, 28 );
GET_ULONG_BE( W[ 8], data, 32 );
GET_ULONG_BE( W[ 9], data, 36 );
GET_ULONG_BE( W[10], data, 40 );
GET_ULONG_BE( W[11], data, 44 );
GET_ULONG_BE( W[12], data, 48 );
GET_ULONG_BE( W[13], data, 52 );
GET_ULONG_BE( W[14], data, 56 );
GET_ULONG_BE( W[15], data, 60 );

#define FF0(x,y,z) ( (x) ^ (y) ^ (z))
#define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))

#define GG0(x,y,z) ( (x) ^ (y) ^ (z))
#define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )


#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n)
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))

#define P0(x) ((x) ^  ROTL((x),9) ^ ROTL((x),17))
#define P1(x) ((x) ^  ROTL((x),15) ^ ROTL((x),23))

for(ShgInt j = 16; j < 68; j++) {
    
    Temp1 = W[j-16] ^ W[j-9];
    Temp2 = ROTL(W[j-3],15);
    Temp3 = Temp1 ^ Temp2;
    Temp4 = P1(Temp3);
    Temp5 =  ROTL(W[j - 13],7 ) ^ W[j-6];
    W[j] = Temp4 ^ Temp5;
}

for(ShgInt j =  0; j < 64; j++) {
    W1[j] = W[j] ^ W[j+4];
}

A = (ShgUInt32)ctx->state[0];
B = (ShgUInt32)ctx->state[1];
C = (ShgUInt32)ctx->state[2];
D = (ShgUInt32)ctx->state[3];
E = (ShgUInt32)ctx->state[4];
F = (ShgUInt32)ctx->state[5];
G = (ShgUInt32)ctx->state[6];
H = (ShgUInt32)ctx->state[7];

for(ShgInt j =0; j < 16; j++) {
    
    SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
    SS2 = SS1 ^ ROTL(A,12);
    TT1 = FF0(A,B,C) + D + SS2 + W1[j];
    TT2 = GG0(E,F,G) + H + SS1 + W[j];
    D = C;
    C = ROTL(B,9);
    B = A;
    A = TT1;
    H = G;
    G = ROTL(F,19);
    F = E;
    E = P0(TT2);
}

for(ShgInt j =16; j < 64; j++) {
    
    SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
    SS2 = SS1 ^ ROTL(A,12);
    TT1 = FF1(A,B,C) + D + SS2 + W1[j];
    TT2 = GG1(E,F,G) + H + SS1 + W[j];
    D = C;
    C = ROTL(B,9);
    B = A;
    A = TT1;
    H = G;
    G = ROTL(F,19);
    F = E;
    E = P0(TT2);
}

ctx->state[0] ^= A;
ctx->state[1] ^= B;
ctx->state[2] ^= C;
ctx->state[3] ^= D;
ctx->state[4] ^= E;
ctx->state[5] ^= F;
ctx->state[6] ^= G;
ctx->state[7] ^= H;
}

@end

原文件 sm3.c

上一篇 下一篇

猜你喜欢

热点阅读