OC方法
-(void)sm3Method:(NSString *)password
{
NSData *testData = [password dataUsingEncoding: NSUTF8StringEncoding];
Byte *input = (Byte *)[testData bytes];
const char *byteLength = [password UTF8String];
size_t length = strlen(byteLength);
Word* hash = SM3::hash(input, length);
NSMutableString *result = [NSMutableString string];
for (int i = 0; i < 8; i++) {
printf(“%x “, hash[i]);
[result appendFormat:@”%x”,hash[i]];
}
NSLog(@”result = %@”,result);
}
C++文件 .h
#ifndef SM3_SM3_H
#define SM3_SM3_H
#include <vector>
typedef uint32_t Word;
typedef uint8_t Byte;
class SM3 {
private:
static void CF(Word* V, Byte* B);
static Word P0(Word X);
static Word P1(Word X);
static Word FF(int j, Word X, Word Y, Word Z);
static Word GG(int j, Word X, Word Y, Word Z);
static Word T(int j);
public:
static Word* hash(Byte* input, uint64_t inputLen);
};
#endif //SM3_SM3_H
C++文件 .cpp
#include “SM3.h”
#define ROTATELEFT(X, n) (((X)<<(n)) | ((X)>>(32-(n))))
Word *SM3::hash(Byte *input, uint64_t inputLen) {
Word VI[] = {0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e};
Word* state = new Word[8];
memcpy(state, VI, 8*sizeof(VI));
Byte buf[64];
int inputPtr = 0;
int bufPtr = 0;
while (inputPtr < inputLen) {
buf[bufPtr] = input[inputPtr];
inputPtr++;
bufPtr++;
if (bufPtr == 64) {
CF(state, buf);
bufPtr = 0;
}
}
buf[bufPtr++] = 0x80;
if (64 – bufPtr < 8) {
while (bufPtr < 64) buf[bufPtr++] = 0;
bufPtr = 0;
CF(state, buf);
}
while (bufPtr < 56) buf[bufPtr++] = 0;
inputLen *= 8;
buf[63] = static_cast<Byte>(inputLen & 0x00000000000000ff);
buf[62] = static_cast<Byte>((inputLen & 0x000000000000ff00) >> 8);
buf[61] = static_cast<Byte>((inputLen & 0x0000000000ff0000) >> 16);
buf[60] = static_cast<Byte>((inputLen & 0x00000000ff000000) >> 24);
buf[59] = static_cast<Byte>((inputLen & 0x000000ff00000000) >> 32);
buf[58] = static_cast<Byte>((inputLen & 0x0000ff0000000000) >> 40);
buf[57] = static_cast<Byte>((inputLen & 0x00ff000000000000) >> 48);
buf[56] = static_cast<Byte>((inputLen & 0xff00000000000000) >> 56);
CF(state, buf);
return state;
}
void SM3::CF(Word *V, Byte *Bi) {
auto W = std::vector<Word>(68, 0); // W
auto WW = std::vector<Word>(64, 0); // W’
for (int i = 0; i < 16; ++i) {
W[i] = 0;
W[i] |= ((Word) Bi[i * 4] << 24);
W[i] |= ((Word) Bi[i * 4 + 1] << 16);
W[i] |= ((Word) Bi[i * 4 + 2] << 8);
W[i] |= ((Word) Bi[i * 4 + 3]);
}
for (int i = 16; i <= 67; ++i) {
W[i] = P1(W[i – 16] ^ W[i – 9] ^ ROTATELEFT(W[i – 3], 15)) ^ ROTATELEFT(W[i – 13], 7) ^ (W[i – 6]);
}
for (int i = 0; i <= 63; ++i) {
WW[i] = W[i] ^ W[i + 4];
}
constexpr int A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7;
Word reg[8];
for (int j = 0; j < 8; ++j) {
reg[j] = V[j];
}
for (int j = 0; j <= 63; ++j) {
Word SS1, SS2, TT1, TT2;
SS1 = ROTATELEFT(ROTATELEFT(reg[A], 12) + reg[E] + ROTATELEFT(T(j), j), 7);
SS2 = SS1 ^ ROTATELEFT(reg[A], 12);
TT1 = FF(j, reg[A], reg[B], reg[C]) + reg[D] + SS2 + WW[j];
TT2 = GG(j, reg[E], reg[F], reg[G]) + reg[H] + SS1 + W[j];
reg[D] = reg[C];
reg[C] = ROTATELEFT(reg[B], 9);
reg[B] = reg[A];
reg[A] = TT1;
reg[H] = reg[G];
reg[G] = ROTATELEFT(reg[F], 19);
reg[F] = reg[E];
reg[E] = P0(TT2);
}
for (int i = 0; i < 8; ++i) {
V[i] ^= reg[i];
}
}
Word SM3::P0(Word X) {
return X ^ ROTATELEFT(X, 9) ^ ROTATELEFT(X, 17);
}
Word SM3::P1(Word X) {
return X ^ ROTATELEFT(X, 15) ^ ROTATELEFT(X, 23);
}
Word SM3::T(int j) {
if (j <= 15) {
return 0x79cc4519;
} else {
return 0x7a879d8a;
}
}
Word SM3::FF(int j, Word X, Word Y, Word Z) {
if (j <= 15) {
return X ^ Y ^ Z;
} else {
return (X & Y) | (X & Z) | (Y & Z);
}
}
Word SM3::GG(int j, Word X, Word Y, Word Z) {
if (j <= 15) {
return X ^ Y ^ Z;
} else {
return (X & Y) | ((~X) & Z);
}
}