typedef signed char int8_t; typedef short int16_t; typedef int int32_t; typedef long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long uint64_t; typedef signed char int_least8_t; typedef short int_least16_t; typedef int int_least32_t; typedef long long int_least64_t; typedef unsigned char uint_least8_t; typedef unsigned short uint_least16_t; typedef unsigned int uint_least32_t; typedef unsigned long uint_least64_t; typedef signed char int_fast8_t; typedef int int_fast16_t; typedef int int_fast32_t; typedef long long int_fast64_t; typedef unsigned char uint_fast8_t; typedef unsigned int uint_fast16_t; typedef unsigned int uint_fast32_t; typedef unsigned long uint_fast64_t; typedef long long intmax_t; typedef unsigned long uintmax_t; typedef unsigned int uint; typedef uint64_t uint256_t[4]; //-------------------------------------------------- //ecc.h /* Curve selection options. */ #define secp128r1 16 #define secp192r1 24 #define secp256r1 32 #define secp384r1 48 #ifndef ECC_CURVE #define ECC_CURVE secp256r1 #endif #if (ECC_CURVE != secp128r1 && ECC_CURVE != secp192r1 && ECC_CURVE != secp256r1 && ECC_CURVE != secp384r1) #error "Must define ECC_CURVE to one of the available curves" #endif #define ECC_BYTES ECC_CURVE #define NUM_ECC_DIGITS (ECC_BYTES/8) #define MAX_TRIES 16 typedef struct { uint64_t m_low; uint64_t m_high; } uint128_t; #define LK_GVALUE_LEN 64 #define LK_WORD_SIZE 32 #define LK_GVALUE_BITLEN 256 #define LK_HASH_NMEMB 8 typedef unsigned int UINT; #ifdef i386 typedef unsigned long long UWORD; #else typedef unsigned long UWORD; #endif typedef unsigned char UCHAR; //���� // 0 <= j <= 15 #define LK_T0 0x79cc4519 // 16 <= j <= 63 #define LK_T1 0x7a879d8a //ѭ������ #define LOOPSHFT(a, n) ( ((a) << (n)) | ((a) >> (LK_WORD_SIZE - (n)))) //�������� #define LK_FF0(x, y, z) ((x)^(y)^(z)) #define LK_FF1(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) #define LK_GG0(x, y, z) ((x)^(y)^(z)) #define LK_GG1(x, y, z) (( (x) & (y) ) | ((~x) & (z))) //�û����� #define LK_P0(x) (\ (x)^(LOOPSHFT((x), 9))^(LOOPSHFT((x), 17)) ) #define LK_P1(x) (\ (x)^(LOOPSHFT((x), 15))^(LOOPSHFT((x), 23)) ) //��׼�и�����IV��ʼֵ #define LK_INIT_VALUE(t) {\ lk_sm3_context_t *x = (t);\ x->v[0] = 0x7380166f;\ x->v[1] = 0x4914b2b9;\ x->v[2] = 0x172442d7;\ x->v[3] = 0xda8a0600;\ x->v[4] = 0xa96f30bc;\ x->v[5] = 0x163138aa;\ x->v[6] = 0xe38dee4d;\ x->v[7] = 0xb0fb0e4e;\ memset(x->data, 0, LK_GVALUE_LEN);\ x->total = 0;\ x->len = 0;} #define LK_LE_ONE(t) {\ lk_sm3_context_t *x = (t);\ UINT l_z, l_d;\ for (l_z = 0; l_z < LK_HASH_NMEMB; l_z++) {\ l_d = x->v[l_z];\ x->output[l_z*4] = ((l_d >> 24) & 0x000000ff);\ x->output[l_z*4 + 1] = ((l_d >> 16) & 0x000000ff);\ x->output[l_z*4 + 2] = ((l_d >> 8) & 0x000000ff);\ x->output[l_z*4 + 3] = (l_d & 0x000000ff);\ }} //���ת�� #define LK_GE_ONE(c) (\ ((c&0x00000000000000ffUL) << 56) | (((c&0x000000000000ff00UL) << 40)) |\ ((c&0x0000000000ff0000UL) << 24) | (((c&0x00000000ff000000UL) << 8)) |\ ((c&0x000000ff00000000UL) >> 8) | (((c&0x0000ff0000000000UL) >> 24)) |\ ((c&0x00ff000000000000UL) >> 40) | (((c&0xff00000000000000UL) >> 56)) ) #define LK_GE(w, c) \ int j2;\ for (j = 0; j <= 15; j++) {\ j2 = j*4;\ w[j] = ((c[j2] << 24) | ((c[j2+1] << 16)) |\ (c[j2+2] << 8) | (c[j2+3]));\ } //ѹ������ժҪ���� #define LK_MSG_CF(t) {\ UINT j;\ lk_sm3_context_t *x = t;\ UCHAR *data = x->data;\ UINT W1[68];\ UINT W2[64];\ UINT a,b,c,d,e,f,g,h;\ a = x->v[0];\ b = x->v[1];\ c = x->v[2];\ d = x->v[3];\ e = x->v[4];\ f = x->v[5];\ g = x->v[6];\ h = x->v[7];\ LK_GE(W1, data)\ for ( j = 16; j <= 67; j++ ) {\ W1[j] = LK_P1(W1[j-16]^W1[j-9]^(LOOPSHFT(W1[j-3], 15))) ^ LOOPSHFT(W1[j-13], 7) ^ W1[j-6];\ }\ for ( j = 0; j <= 63; j++ ) {\ W2[j] = W1[j] ^ W1[j+4];\ }\ for ( j = 0; j <= 63; j++ ) {\ UINT T, ss1, ss2, tt1, tt2;\ if ( j >= 0 && j <= 15 )\ T = LK_T0;\ else\ T = LK_T1;\ ss1 = LOOPSHFT( (LOOPSHFT(a, 12) + e + LOOPSHFT(T, j)), 7 );\ ss2 = ss1 ^ LOOPSHFT(a, 12);\ if ( j >= 0 && j <= 15 ) {\ tt1 = LK_FF0(a, b, c) + d + ss2 + W2[j];\ tt2 = LK_GG0(e, f, g) + h + ss1 + W1[j];\ } else {\ tt1 = LK_FF1(a, b, c) + d + ss2 + W2[j];\ tt2 = LK_GG1(e, f, g) + h + ss1 + W1[j];\ }\ d = c;\ c = LOOPSHFT(b, 9);\ b = a;\ a = tt1;\ h = g;\ g = LOOPSHFT(f, 19);\ f = e;\ e = LK_P0(tt2);\ }\ x->v[0] = a ^ x->v[0];\ x->v[1] = b ^ x->v[1];\ x->v[2] = c ^ x->v[2];\ x->v[3] = d ^ x->v[3];\ x->v[4] = e ^ x->v[4];\ x->v[5] = f ^ x->v[5];\ x->v[6] = g ^ x->v[6];\ x->v[7] = h ^ x->v[7];\ x->len = 0;\ } typedef struct { uint64_t x[NUM_ECC_DIGITS]; uint64_t y[NUM_ECC_DIGITS]; } EccPoint; typedef struct lk_sm3_context_s { uint32_t len; uint32_t total; uint8_t data[LK_GVALUE_LEN]; uint32_t v[LK_HASH_NMEMB]; uint8_t output[LK_WORD_SIZE]; } lk_sm3_context_t; typedef struct { uint256_t a; uint256_t b; uint256_t p; }EllipticCurveDef; typedef struct { uint8_t r[32]; uint8_t s[32]; }SM2Signature; typedef struct { uint64_t* data; uint64_t sizeInLongLong; }BIG; typedef struct { uint8_t ZA[32]; uint8_t ZB[32]; uint256_t dA; EccPoint* PA; EccPoint* PB; uint32_t w; uint32_t h; uint256_t n; EccPoint* G; }KeyExchangeAOriginalInfoDef;//��Կ�����е�ԭʼ��Ϣ typedef struct { uint8_t ZA[32];//����IDA���Ӵ�ֵ uint8_t ZB[32];//����IDB���Ӵ�ֵ uint256_t dB;//˽ԿB EccPoint* PA;//��ԿA EccPoint* PB;//��ԿB uint32_t w; uint32_t h; uint256_t n; //����Ľ� EccPoint* G; //���� }KeyExchangeBOriginalInfoDef; //-------------------------------------------------- __constant uint256_t UINT256_MAX = { 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff }; __constant uint256_t ellipticCurve_a = { 0x787968B4FA32C3FD, 0x2417842E73BBFEFF, 0x2F3C848B6831D7E0, 0xEC65228B3937E498 }; __constant uint256_t ellipticCurve_b = { 0x63E4C6D3B23B0C84, 0x9CF84241484BFE48, 0xF61D59A5B16BA06E, 0x6E12D1DA27C5249A }; __constant uint256_t ellipticCurve_p = { 0x8542D69E4C044F18, 0xE8B92435BF6FF7DE, 0x457283915C45517D, 0x722EDB8B08F1DFC3 }; __constant uint256_t ellipticCurve_n = { 0x8542D69E4C044F18, 0xE8B92435BF6FF7DD, 0x297720630485628D, 0x5AE74EE7C32E79B7 }; __constant uint256_t ellipticCurve_Gx = { 0x421DEBD61B62EAB6, 0x746434EBC3CC315E, 0x32220B3BADD50BDC, 0x4C4E6C147FEDD43D }; __constant uint256_t ellipticCurve_Gy = { 0x0680512BCBB42C07, 0xD47349D2153B70C4, 0xE5D7FDFCBFA36EA1, 0xA85841B9E46E09A2 }; /*����SM2�Ƽ�����*/ //uint256_t ellipticCurve_a = { 0xfffffffeffffffff, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFC }; //uint256_t ellipticCurve_b = { 0x28E9FA9E9D9F5E34, 0x4D5A9E4BCF6509A7, 0xF39789F515AB8F92, 0xDDBCBD414D940E93 }; //uint256_t ellipticCurve_p = { 0xFFFFFFFEFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xffffffffffffffff }; //uint256_t ellipticCurve_n = { 0xfffffffeffffffff, 0xFFFFFFFFFFFFFFFF, 0x7203DF6B21C6052B, 0x53BBF40939D54123 }; //uint256_t ellipticCurve_Gx = { 0x32C4AE2C1F198119, 0x5F9904466A39C994, 0x8FE30BBFF2660BE1, 0x715A4589334C74C7 }; //uint256_t ellipticCurve_Gy = { 0xBC3736A2F4F6779C, 0x59BDCEE36B692153, 0xD0A9877CC62A4740, 0x02DF32E52139F0A0 }; /*examples, for DEBUG ONLY!!!*/ //exampe for SM2encrypt //uint256_t exPrivateKey = { 0x1649AB77A00637BD, 0x5E2EFE283FBF3535, 0x34AA7F7CB89463F2, 0x08DDBC2920BB0DA0 }; //uint256_t exRandomK = { 0x4C62EEFD6ECFC2B9, 0x5B92FD6C3D957514, 0x8AFA17425546D490, 0x18E5388D49DD7B4F }; //exampe for SM2sign __constant uint256_t exPrivateKey = { 0x128B2FA8BD433C6C, 0x068C8D803DFF7979, 0x2A519A55171B1B65, 0x0C23661D15897263 }; __constant uint256_t exRandomK = { 0x6CB28D99385C175C ,0x94F94E934817663F ,0xC176D925DD72B727 ,0x260DBAAE1FB2F96F }; __constant uint256_t exPrivateKey_A = { 0x6FCBA2EF9AE0AB90, 0x2BC3BDE3FF915D44, 0xBA4CC78F88E2F8E7, 0xF8996D3B8CCEEDEE }; __constant uint256_t exPrivateKey_B = { 0x5E35D7D3F3C54DBA, 0xC72E61819E730B01, 0x9A84208CA3A35E4C, 0x2E353DFCCB2A3B53 }; __constant uint256_t exRandom_rA = { 0x83A2C9C8B96E5AF7, 0x0BD480B472409A9A, 0x327257F1EBB73F5B, 0x073354B248668563 }; __constant uint256_t exRandom_rB = { 0x33FE21940342161C, 0x55619C4A0C060293, 0xD543C80AF19748CE, 0x176D83477DE71C80 }; __constant uint256_t exPublicKey_Ax = { 0x3099093BF3C137D8, 0xFCBBCDF4A2AE50F3, 0xB0F216C3122D7942, 0x5FE03A45DBFE1655 }; __constant uint256_t exPublicKey_Ay = { 0x3DF79E8DAC1CF0EC, 0xBAA2F2B49D51A4B3, 0x87F2EFAF48233908, 0x6A27A8E05BAED98B }; __constant uint256_t exPublicKey_Bx = { 0x245493D446C38D8C, 0xC0F118374690E7DF, 0x633A8A4BFB3329B5, 0xECE604B2B4F37F43 }; __constant uint256_t exPublicKey_By = { 0x53C0869F4B9E1777, 0x3DE68FEC45E14904, 0xE0DEA45BF6CECF99, 0x18C85EA047C60A4C }; __constant EccPoint pointZero = { {0, 0, 0, 0}, {0, 0, 0, 0} }; //��� typedef int BOOL; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif //c����ʵ��memset void* memset(void* ptr, int value, int num) { unsigned char* p = ptr; while (num--) { *p++ = (unsigned char)value; } //return ptr; } //c����ʵ��memcpy void* memcpy(uint8_t* dest, const void* src, int n) { char* dp = dest; const char* sp = src; while (n--) { *dp++ = *sp++; } //return dest; } #define CONCAT1(a, b) a##b #define CONCAT(a, b) CONCAT1(a, b) #define Curve_P_16 {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFDFFFFFFFF} #define Curve_P_24 {0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFFFFFFFFFFull} //#define Curve_P_32 {0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull, 0x0000000000000000ull, 0xFFFFFFFF00000001ull} #define Curve_P_32 {0x722EDB8B08F1DFC3ULL, 0x457283915C45517DULL, 0xE8B92435BF6FF7DEULL, 0x8542D69E4C044F18ULL} #define Curve_P_48 {0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF} #define Curve_B_16 {0xD824993C2CEE5ED3, 0xE87579C11079F43D} #define Curve_B_24 {0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull, 0x64210519E59C80E7ull} //#define Curve_B_32 {0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull, 0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull} #define Curve_B_32 {0x6E12D1DA27C5249Aull, 0xF61D59A5B16BA06Eull, 0x9CF84241484BFE48ull, 0x63E4C6D3B23B0C84ull} #define Curve_B_48 {0x2A85C8EDD3EC2AEF, 0xC656398D8A2ED19D, 0x0314088F5013875A, 0x181D9C6EFE814112, 0x988E056BE3F82D19, 0xB3312FA7E23EE7E4} #define Curve_G_16 { \ {0x0C28607CA52C5B86, 0x161FF7528B899B2D}, \ {0xC02DA292DDED7A83, 0xCF5AC8395BAFEB13}} #define Curve_G_24 { \ {0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull, 0x188DA80EB03090F6ull}, \ {0x73F977A11E794811ull, 0x631011ED6B24CDD5ull, 0x07192B95FFC8DA78ull}} #define Curve_G_32 { \ {0xF4A13945D898C296ull, 0x77037D812DEB33A0ull, 0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull}, \ {0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull, 0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull}} #define Curve_G_32 {\ {0x4C4E6C147FEDD43D, 0x32220B3BADD50BDC, 0x746434EBC3CC315E, 0x421DEBD61B62EAB6},\ {0xA85841B9E46E09A2, 0xE5D7FDFCBFA36EA1, 0xD47349D2153B70C4, 0x0680512BCBB42C07}} #define Curve_G_48 { \ {0x3A545E3872760AB7, 0x5502F25DBF55296C, 0x59F741E082542A38, 0x6E1D3B628BA79B98, 0x8EB1C71EF320AD74, 0xAA87CA22BE8B0537}, \ {0x7A431D7C90EA0E5F, 0x0A60B1CE1D7E819D, 0xE9DA3113B5F0B8C0, 0xF8F41DBD289A147C, 0x5D9E98BF9292DC29, 0x3617DE4A96262C6F}} #define Curve_N_16 {0x75A30D1B9038A115, 0xFFFFFFFE00000000} #define Curve_N_24 {0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull, 0xFFFFFFFFFFFFFFFFull} #define Curve_N_32 {0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull} #define Curve_N_32 {0x5AE74EE7C32E79B7,0x297720630485628D,0xE8B92435BF6FF7DD,0x8542D69E4C044F18} #define Curve_N_48 {0xECEC196ACCC52973, 0x581A0DB248B0A77A, 0xC7634D81F4372DDF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF} __constant static uint64_t curve_p[NUM_ECC_DIGITS] = CONCAT(Curve_P_, ECC_CURVE); __constant static uint64_t curve_b[NUM_ECC_DIGITS] = CONCAT(Curve_B_, ECC_CURVE); __constant static EccPoint curve_G = CONCAT(Curve_G_, ECC_CURVE); __constant static uint64_t curve_n[NUM_ECC_DIGITS] = CONCAT(Curve_N_, ECC_CURVE); #if (defined(_WIN32) || defined(_WIN64)) /* Windows */ #define WIN32_LEAN_AND_MEAN #else /* _WIN32 */ #ifndef O_CLOEXEC #define O_CLOEXEC 0 #endif #endif /* _WIN32 */ //�������� static void vli_clear(uint64_t* p_vli) { uint i; for (i = 0; i < NUM_ECC_DIGITS; ++i) { p_vli[i] = 0; } } /* Returns 1 if p_vli == 0, 0 otherwise. */ static int vli_isZero(uint64_t* p_vli) { uint i; for (i = 0; i < NUM_ECC_DIGITS; ++i) { if (p_vli[i]) { return 0; } } return 1; } /* Returns nonzero if bit p_bit of p_vli is set. */ static uint64_t vli_testBit(uint64_t* p_vli, uint p_bit) { return (p_vli[p_bit / 64] & ((uint64_t)1 << (p_bit % 64))); } /* Counts the number of 64-bit "digits" in p_vli. */ static uint vli_numDigits(uint64_t* p_vli) { int i; /* Search from the end until we find a non-zero digit. We do it in reverse because we expect that most digits will be nonzero. */ for (i = NUM_ECC_DIGITS - 1; i >= 0 && p_vli[i] == 0; --i) { } return (i + 1); } /* Counts the number of bits required for p_vli. */ static uint vli_numBits(uint64_t* p_vli) { uint i; uint64_t l_digit; uint l_numDigits = vli_numDigits(p_vli); if (l_numDigits == 0) { return 0; } l_digit = p_vli[l_numDigits - 1]; for (i = 0; l_digit; ++i) { l_digit >>= 1; } return ((l_numDigits - 1) * 64 + i); } /* Sets p_dest = p_src. */ void vli_set(uint64_t* p_dest, uint64_t* p_src) { uint i; for (i = 0; i < NUM_ECC_DIGITS; ++i) { p_dest[i] = p_src[i]; } } /* Returns sign of p_left - p_right. */ int vli_cmp(uint64_t* p_left, uint64_t* p_right) { int i; for (i = NUM_ECC_DIGITS - 1; i >= 0; --i) { if (p_left[i] > p_right[i]) { return 1; } else if (p_left[i] < p_right[i]) { return -1; } } return 0; } static uint64_t vli_lshift(uint64_t* p_result, uint64_t* p_in, uint p_shift) { uint64_t l_carry = 0; uint i; for (i = 0; i < NUM_ECC_DIGITS; ++i) { uint64_t l_temp = p_in[i]; p_result[i] = (l_temp << p_shift) | l_carry; l_carry = l_temp >> (64 - p_shift); } return l_carry; } static void vli_rshift1(uint64_t* p_vli) { uint64_t* l_end = p_vli; uint64_t l_carry = 0; p_vli += NUM_ECC_DIGITS; while (p_vli-- > l_end) { uint64_t l_temp = *p_vli; *p_vli = (l_temp >> 1) | l_carry; l_carry = l_temp << 63; } } /* Computes p_result = p_left + p_right, returning carry. Can modify in place. */ uint64_t vli_add(uint64_t* p_result, uint64_t* p_left, uint64_t* p_right) { uint64_t l_carry = 0; uint i; for (i = 0; i < NUM_ECC_DIGITS; ++i) { uint64_t l_sum = p_left[i] + p_right[i] + l_carry; if (l_sum != p_left[i]) { l_carry = (l_sum < p_left[i]); } p_result[i] = l_sum; } return l_carry; } uint64_t vli_sub(uint64_t* p_result, uint64_t* p_left, uint64_t* p_right) { uint64_t l_borrow = 0; uint i; for (i = 0; i < NUM_ECC_DIGITS; ++i) { uint64_t l_diff = p_left[i] - p_right[i] - l_borrow; if (l_diff != p_left[i]) { l_borrow = (l_diff > p_left[i]); } p_result[i] = l_diff; } return l_borrow; } #if SUPPORTS_INT128 static void vli_mult(uint64_t* p_result, uint64_t* p_left, uint64_t* p_right) { uint128_t r01 = 0; uint64_t r2 = 0; uint i, k; /* Compute each digit of p_result in sequence, maintaining the carries. */ for (k = 0; k < NUM_ECC_DIGITS * 2 - 1; ++k) { uint l_min = (k < NUM_ECC_DIGITS ? 0 : (k + 1) - NUM_ECC_DIGITS); for (i = l_min; i <= k && i < NUM_ECC_DIGITS; ++i) { uint128_t l_product = (uint128_t)p_left[i] * p_right[k - i]; r01 += l_product; r2 += (r01 < l_product); } p_result[k] = (uint64_t)r01; r01 = (r01 >> 64) | (((uint128_t)r2) << 64); r2 = 0; } p_result[NUM_ECC_DIGITS * 2 - 1] = (uint64_t)r01; } static void vli_square(uint64_t* p_result, uint64_t* p_left) { uint128_t r01 = 0; uint64_t r2 = 0; uint i, k; for (k = 0; k < NUM_ECC_DIGITS * 2 - 1; ++k) { uint l_min = (k < NUM_ECC_DIGITS ? 0 : (k + 1) - NUM_ECC_DIGITS); for (i = l_min; i <= k && i <= k - i; ++i) { uint128_t l_product = (uint128_t)p_left[i] * p_left[k - i]; if (i < k - i) { r2 += l_product >> 127; l_product *= 2; } r01 += l_product; r2 += (r01 < l_product); } p_result[k] = (uint64_t)r01; r01 = (r01 >> 64) | (((uint128_t)r2) << 64); r2 = 0; } p_result[NUM_ECC_DIGITS * 2 - 1] = (uint64_t)r01; } #else /* #if SUPPORTS_INT128 */ static uint128_t mul_64_64(uint64_t p_left, uint64_t p_right) { uint128_t l_result; uint64_t a0 = p_left & 0xffffffffull; uint64_t a1 = p_left >> 32; uint64_t b0 = p_right & 0xffffffffull; uint64_t b1 = p_right >> 32; uint64_t m0 = a0 * b0; uint64_t m1 = a0 * b1; uint64_t m2 = a1 * b0; uint64_t m3 = a1 * b1; m2 += (m0 >> 32); m2 += m1; if (m2 < m1) { // overflow m3 += 0x100000000ull; } l_result.m_low = (m0 & 0xffffffffull) | (m2 << 32); l_result.m_high = m3 + (m2 >> 32); return l_result; } static uint128_t add_128_128(uint128_t a, uint128_t b) { uint128_t l_result; l_result.m_low = a.m_low + b.m_low; l_result.m_high = a.m_high + b.m_high + (l_result.m_low < a.m_low); return l_result; } void vli_mult(uint64_t* p_result, uint64_t* p_left, uint64_t* p_right) { uint128_t r01 = { 0, 0 }; uint64_t r2 = 0; uint i, k; /* Compute each digit of p_result in sequence, maintaining the carries. */ for (k = 0; k < NUM_ECC_DIGITS * 2 - 1; ++k) { uint l_min = (k < NUM_ECC_DIGITS ? 0 : (k + 1) - NUM_ECC_DIGITS); for (i = l_min; i <= k && i < NUM_ECC_DIGITS; ++i) { uint128_t l_product = mul_64_64(p_left[i], p_right[k - i]); r01 = add_128_128(r01, l_product); r2 += (r01.m_high < l_product.m_high); } p_result[k] = r01.m_low; r01.m_low = r01.m_high; r01.m_high = r2; r2 = 0; } p_result[NUM_ECC_DIGITS * 2 - 1] = r01.m_low; } #endif /* SUPPORTS_INT128 */ /* Computes p_result = (p_left + p_right) % p_mod. Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ void vli_modAdd(uint64_t* p_result, uint64_t* p_left, uint64_t* p_right, uint64_t* p_mod) { uint64_t l_carry = vli_add(p_result, p_left, p_right); while (l_carry || vli_cmp(p_result, p_mod) >= 0) { if (l_carry == 1 && vli_cmp(p_result, p_mod) == -1) //���μ�����Ҫ��λ��l_carry == 1�ͺ�����ж���ʵ����Զ��ȵģ�����������������ٶ� { l_carry = 0; } /* p_result > p_mod (p_result = p_mod + remainder), so subtract p_mod to get remainder. */ vli_sub(p_result, p_result, p_mod); } } /* Computes p_result = (p_left - p_right) % p_mod. Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ void vli_modSub(uint64_t* p_result, uint64_t* p_left, uint64_t* p_right, uint64_t* p_mod) { uint64_t l_borrow = vli_sub(p_result, p_left, p_right); if (l_borrow) { /* In this case, p_result == -diff == (max int) - diff. Since -x % d == d - x, we can get the correct result from p_result + p_mod (with overflow). */ vli_add(p_result, p_result, p_mod); } } #define EVEN(vli) (!(vli[0] & 1)) /* Computes p_result = (1 / p_input) % p_mod. All VLIs are the same size. See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf */ void vli_modInv(uint64_t* p_result, uint64_t* p_input, uint64_t* p_mod) { uint64_t a[NUM_ECC_DIGITS], b[NUM_ECC_DIGITS], u[NUM_ECC_DIGITS], v[NUM_ECC_DIGITS]; uint64_t l_carry; int l_cmpResult; if (vli_isZero(p_input)) { vli_clear(p_result); return; } vli_set(a, p_input); vli_set(b, p_mod); vli_clear(u); u[0] = 1; vli_clear(v); while ((l_cmpResult = vli_cmp(a, b)) != 0) { l_carry = 0; if (EVEN(a)) { vli_rshift1(a); if (!EVEN(u)) { l_carry = vli_add(u, u, p_mod); } vli_rshift1(u); if (l_carry) { u[NUM_ECC_DIGITS - 1] |= 0x8000000000000000ull; } } else if (EVEN(b)) { vli_rshift1(b); if (!EVEN(v)) { l_carry = vli_add(v, v, p_mod); } vli_rshift1(v); if (l_carry) { v[NUM_ECC_DIGITS - 1] |= 0x8000000000000000ull; } } else if (l_cmpResult > 0) { vli_sub(a, a, b); vli_rshift1(a); if (vli_cmp(u, v) < 0) { vli_add(u, u, p_mod); } vli_sub(u, u, v); if (!EVEN(u)) { l_carry = vli_add(u, u, p_mod); } vli_rshift1(u); if (l_carry) { u[NUM_ECC_DIGITS - 1] |= 0x8000000000000000ull; } } else { vli_sub(b, b, a); vli_rshift1(b); if (vli_cmp(v, u) < 0) { vli_add(v, v, p_mod); } vli_sub(v, v, u); if (!EVEN(v)) { l_carry = vli_add(v, v, p_mod); } vli_rshift1(v); if (l_carry) { v[NUM_ECC_DIGITS - 1] |= 0x8000000000000000ull; } } } vli_set(p_result, u); } /* -------- ECDSA code -------- */ /* Computes p_result = (p_left * p_right) % p_mod. */ void vli_modMult(uint64_t* p_result, uint64_t* p_left, uint64_t* p_right, uint64_t* p_mod) { uint64_t l_product[2 * NUM_ECC_DIGITS]; uint64_t l_modMultiple[2 * NUM_ECC_DIGITS]; uint l_digitShift, l_bitShift; uint l_productBits; uint l_modBits = vli_numBits(p_mod); uint64_t l_carry; vli_set(p_result, l_product); //vli_mult(l_product, p_left, p_right); //l_productBits = vli_numBits(l_product + NUM_ECC_DIGITS); //if (l_productBits) //{ // l_productBits += NUM_ECC_DIGITS * 64; //} //else //{ // l_productBits = vli_numBits(l_product); //} // //if (l_productBits < l_modBits) //{ // /* l_product < p_mod. */ // vli_set(p_result, l_product); // return; //} // ///* Shift p_mod by (l_leftBits - l_modBits). This multiplies p_mod by the largest // power of two possible while still resulting in a number less than p_left. */ //vli_clear(l_modMultiple); //vli_clear(l_modMultiple + NUM_ECC_DIGITS); //l_digitShift = (l_productBits - l_modBits) / 64; //l_bitShift = (l_productBits - l_modBits) % 64; //if (l_bitShift) //{ // l_modMultiple[l_digitShift + NUM_ECC_DIGITS] = vli_lshift(l_modMultiple + l_digitShift, p_mod, l_bitShift); //} //else //{ // vli_set(l_modMultiple + l_digitShift, p_mod); //} // //vli_set(p_result, l_product); ///* Subtract all multiples of p_mod to get the remainder. */ ////vli_clear(p_result); //p_result[0] = 1; /* Use p_result as a temp var to store 1 (for subtraction) */ //while (l_productBits > NUM_ECC_DIGITS * 64 || vli_cmp(l_modMultiple, p_mod) >= 0) //{ // int l_cmp = vli_cmp(l_modMultiple + NUM_ECC_DIGITS, l_product + NUM_ECC_DIGITS); // if (l_cmp < 0 || (l_cmp == 0 && vli_cmp(l_modMultiple, l_product) <= 0)) // { // if (vli_sub(l_product, l_product, l_modMultiple)) // { // /* borrow */ // vli_sub(l_product + NUM_ECC_DIGITS, l_product + NUM_ECC_DIGITS, p_result); // } // vli_sub(l_product + NUM_ECC_DIGITS, l_product + NUM_ECC_DIGITS, l_modMultiple + NUM_ECC_DIGITS); // } // l_carry = (l_modMultiple[NUM_ECC_DIGITS] & 0x01) << 63; // vli_rshift1(l_modMultiple + NUM_ECC_DIGITS); // vli_rshift1(l_modMultiple); // l_modMultiple[NUM_ECC_DIGITS - 1] |= l_carry; // // --l_productBits; //} ////vli_set(p_result, l_product); //uint i; //p_result[0] =l_product[0];// //1; //p_result[1] = l_product[1]; //p_result[2] = l_product[2]; //p_result[3] = l_product[3]; //for (i = 0; i < NUM_ECC_DIGITS; ++i) //{ // p_result[i] = l_product[i]; //} } static uint umax(uint a, uint b) { return (a > b ? a : b); } static void lk_sm3_cf(lk_sm3_context_t* context) { LK_MSG_CF(context) } void lk_sm3_update(lk_sm3_context_t* context, UCHAR* data, UINT len) { int real_len, free, offset = 0; real_len = len + context->len; if (real_len < LK_GVALUE_LEN) { //�������ݲ���һ�������С,�Ȼ������� memcpy(context->data + context->len, data + offset, len); context->len = real_len; context->total += len; return; } free = LK_GVALUE_LEN - context->len; memcpy(context->data + context->len, data + offset, free); context->total += free; offset += free; len -= free; //���е���ѹ�� lk_sm3_cf(context); while (1) { if (len < LK_GVALUE_LEN) { //�������ݲ���һ�������С,�Ȼ������� memcpy(context->data + context->len, data + offset, len); context->len = len; context->total += len; return; } memcpy(context->data + context->len, data + offset, LK_GVALUE_LEN); offset += LK_GVALUE_LEN; len -= LK_GVALUE_LEN; context->total += LK_GVALUE_LEN; //���е���ѹ�� lk_sm3_cf(context); } } void lk_sm3_final(lk_sm3_context_t* context) { UINT tk, k, free, i, len; UCHAR tmp[LK_GVALUE_LEN] = { 0 }; tk = context->total * 8 % 512; if (tk < 448) { k = 448 - tk; } else { k = 448 - tk + 512; } //������Ҫ�����ֽ� k = k / 8 + 8; free = LK_GVALUE_LEN - context->len; k--; context->data[context->len] = 0x80; len = context->total * 8; for (i = context->len + 1; i < LK_GVALUE_LEN; i++, k--) { if (k != 8) context->data[i] = 0x00; else { memset(context->data + i, 0, 8); UWORD* pdata = (UWORD*)(4 + &(context->data[i])); *pdata = LK_GE_ONE(len); break; } } //���е���ѹ�� lk_sm3_cf(context); if (64 == k) { for (i = 0; i < LK_GVALUE_LEN; i++, k--) { if (k != 8) context->data[i] = 0x00; else { memset(context->data + i, 0, 8); UWORD* pdata = (UWORD*)(4 + &(context->data[i])); *pdata = LK_GE_ONE(len); break; } } //���е���ѹ�� lk_sm3_cf(context); } //get result LK_LE_ONE(context) } void SM3(char* cdata, int sizeInByte, char* res) { lk_sm3_context_t context; LK_INIT_VALUE(&context); char buffer[1024] = { 0 }; lk_sm3_update(&context, cdata, sizeInByte); lk_sm3_final(&context); for (int i = 0; i < 32; i++) res[i] = context.output[i]; } //BOOL IsValidPoint(EccPoint* point, EllipticCurveDef* Ec) //{ // uint64_t left[4], //= (uint64_t*)malloc(sizeof(uint64_t) * 4), // right[4], //= (uint64_t*)malloc(sizeof(uint64_t) * 4), // tmpRight[4];// = (uint64_t*)malloc(sizeof(uint64_t) * 4); // // vli_modMult(left, point->y, point->y, Ec->p); //left = y^2 // vli_modMult(tmpRight, point->x, point->x, Ec->p); // vli_modMult(right, tmpRight, point->x, Ec->p); //x^3 // vli_modMult(tmpRight, Ec->a, point->x, Ec->p); //a*x // vli_modAdd(tmpRight, right, tmpRight, Ec->p); //x^3 + a*x // vli_modAdd(right, tmpRight, Ec->b, Ec->p); //right = x^3 + a*x + b // // int res = vli_cmp(left, right); // //free(left); // //free(right); // //free(tmpRight); // // return !res; //} BOOL IsZeroPoint(EccPoint* point) { for (int i = 0; i < 4; i++) { if (point->x[i]) { return 0; } if (point->y[i]) { return 0; } } return 1; } BOOL IsZeroUint256(uint64_t* num) { for (int i = 0; i < 4; i++) { if (num[i]) { return 0; } } return 1; } void CurvePointAdd(EccPoint* res, EccPoint* p1, EccPoint* p2) { EllipticCurveDef Ec[1]; //Ec = malloc(sizeof(EllipticCurveDef)); for (int i = 0; i < 4; i++) { Ec->a[i] = ellipticCurve_a[3 - i]; Ec->b[i] = ellipticCurve_b[3 - i]; Ec->p[i] = ellipticCurve_p[3 - i]; } uint64_t tmp1[4] = { 0 }, tmp2 = { 0 }, k = { 0 }, k2 = { 0 }, num2[4] = { {2},{0},{0},{0} }, num3[4] = { {3},{0},{0},{0} }; int i = 0; if (IsZeroPoint(p2)) { for (i = 0; i < 4; i++) { res->x[i] = p1->x[i]; res->y[i] = p1->y[i]; } return; } if (IsZeroPoint(p1)) { for (i = 0; i < 4; i++) { res->x[i] = p2->x[i]; res->y[i] = p2->y[i]; } return; } for (i = 0; i < 4; i++) { if (p1->x[i] != p2->x[i]) { break; } } if (i == 4) { vli_modMult(tmp1, p1->x, p1->x, Ec->p);//tmp1 = x1^2 vli_modMult(tmp1, num3, tmp1, Ec->p);//tmp1 = 3*x1^2 // vli_modAdd(tmp1, tmp1, Ec->a, Ec->p);//tmp1 = 3*x1^2+a // vli_modMult(tmp2, num2, p2->y, Ec->p);//tmp2 = 2*y1 // vli_modInv(k, tmp2, Ec->p); //k = 1/(2*y1) // vli_modMult(k, k, tmp1, Ec->p);//k = (3*x1^2+a)/(2*y1) // vli_modMult(k2, k, k, Ec->p);//k2 = k^2 // vli_modAdd(tmp1, p1->x, p2->x, Ec->p);//tmp1 = x1+x2 // vli_modSub(tmp2, k2, tmp1, Ec->p);//tmp2 = x3 = x4 // // vli_modSub(tmp1, p1->x, tmp2, Ec->p);//tmp1 = x1 - x3 // vli_modMult(tmp1, k, tmp1, Ec->p);//tmp1 = k(x1-x3) // vli_modSub(tmp1, tmp1, p1->y, Ec->p);//tmp1 = y4 } //else //{ // vli_modSub(tmp1, p1->x, p2->x, Ec->p);//tmp1 = x1-x2 // vli_modSub(tmp2, p1->y, p2->y, Ec->p);//tmp2 = y1-y2 // vli_modInv(k, tmp1, Ec->p); //k = 1/(x1-x2) // vli_modMult(k, k, tmp2, Ec->p);//k = (y1-y2)/(x1-x2) // vli_modMult(k2, k, k, Ec->p);//k2 = k^2 // vli_modAdd(tmp1, p1->x, p2->x, Ec->p);//tmp1 = x1+x2 // vli_modSub(tmp2, k2, tmp1, Ec->p);//tmp2 = x3 = x4 // // vli_modSub(tmp1, p1->x, tmp2, Ec->p);//tmp1 = x1 - x3 // vli_modMult(tmp1, k, tmp1, Ec->p);//tmp1 = k(x1-x3) // vli_modSub(tmp1, tmp1, p1->y, Ec->p);//tmp1 = y4 //} //for (i = 0; i < 4; i++) //{ // res->x[i] = tmp2[i]; // res->y[i] = tmp1[i]; //} } void Uint256BitShift(uint64_t* num, int shift) { if (shift < 0) { while (shift++) { //num[3] = (num[3] >> 1) | ((num[2] & 1ULL) << 63); //num[2] = (num[2] >> 1) | ((num[1] & 1ULL) << 63); //num[1] = (num[1] >> 1) | ((num[0] & 1ULL) << 63); //num[0] = num[0] >> 1; num[0] = (num[0] >> 1) | ((num[1] & 1ULL) << 63); num[1] = (num[1] >> 1) | ((num[2] & 1ULL) << 63); num[2] = (num[2] >> 1) | ((num[3] & 1ULL) << 63); num[3] = num[3] >> 1; } } else if (shift > 0) { while (shift--) { num[3] = (num[3] << 1) | ((num[2] & (1ULL << 63)) >> 63); num[2] = (num[2] << 1) | ((num[1] & (1ULL << 63)) >> 63); num[1] = (num[1] << 1) | ((num[0] & (1ULL << 63)) >> 63); num[2] = (num[0] << 1); } } } //void BigBitShift(BIG* num, BOOL shift)//�˺���ʵ��δ�õ�������Ҫ�� //{ // num->data = malloc(sizeof(uint64_t) * (num->sizeInLongLong + 1)); // if (shift == 0) // { // if (num->data[num->sizeInLongLong - 1] == 1ULL) // { // num->sizeInLongLong = num->sizeInLongLong - 1; // } // for (int64_t i = 0; i < num->sizeInLongLong; i++) // { // num->data[i] = (num->data[i] >> 1) | // (i + 1 < num->sizeInLongLong ? ((num->data[i + 1] & 1ULL) << 63) : 0); // } // } // else if (shift > 0) // { // if (num->data[num->sizeInLongLong - 1] & (0x8000000000000000ULL)) // { // num->data[num->sizeInLongLong] = 1; // num->sizeInLongLong = num->sizeInLongLong + 1; // } // for (int64_t i = num->sizeInLongLong - 1; i >= 0; i--) // { // num->data[i] = (num->data[i] << 1) | // (i - 1 >= 0 ? ((num->data[i - 1] & 0x8000000000000000ULL) >> 63) : 0); // } // } //} void Uint256Cpy(uint64_t* des, uint64_t* src) { for (int i = 0; i < 4; i++) { des[i] = src[i]; } } void CurvePointMul(EccPoint* res, EccPoint* p1, uint64_t* times) { EccPoint tmpPoint[1],// = malloc(sizeof(EccPoint)), tmpPoint1[1];// = malloc(sizeof(EccPoint)); uint64_t tmpTimes[4];// = malloc(sizeof(EccPoint));����ԭ���Ǵ��ģ������ڴ���� Uint256Cpy(tmpPoint->x, p1->x); Uint256Cpy(tmpPoint->y, p1->y); Uint256Cpy(tmpTimes, times); for (int i = 0; i < 4; i++) { res->x[i] = 0; res->y[i] = 0; } while (!IsZeroUint256(tmpTimes)) { if (tmpTimes[0] & 0x1) { CurvePointAdd(res, res, tmpPoint); //res = res + tmpPoint } Uint256BitShift(tmpTimes, -1); //times >>= 1 Uint256Cpy(tmpPoint1->x, tmpPoint->x); Uint256Cpy(tmpPoint1->y, tmpPoint->y); CurvePointAdd(tmpPoint, tmpPoint, tmpPoint1); //tmpPoint *= 2 } } void Uint256ToString(uint8_t* res, uint256_t num) { int pos = 0; for (int i = 3; i >= 0; i--) { for (int j = 7; j >= 0; j--) { res[pos++] = (num[i] & (0xffULL << (j * 8))) >> (j * 8); } } } void StringToUint256(uint64_t* res, uint8_t* num) { int pos = 0; memset(res, 0, 32); for (int i = 3; i >= 0; i--) { for (int j = 7; j >= 0; j--) { uint64_t tmp = 0xff & (uint64_t)num[pos++]; res[i] |= tmp << (j * 8); } } } void CalculateC1(EccPoint* result, uint256_t k, EccPoint* G) { CurvePointMul(result, G, k); } void CalculateKPb(EccPoint* result, uint256_t k, EccPoint* Pb) { CurvePointMul(result, Pb, k); } void CalculateC2(uint8_t* result, char* M, uint8_t* t, int lenInByte) { for (int i = 0; i < lenInByte; i++) { result[i] = M[i] ^ t[i]; } } void KDF(uint8_t* result, uint8_t* Z, int dataLenInBit, int keyLenInBit)//��Ȼ�˴������޸ģ���Ϊ��ʹ����kdf�IJ����иı䣬ÿ��memset�����������������ֵ������û�б�Ҫ����Ϊ��������Ŀռ�̫���� { uint8_t tmpRes[408], //= (uint8_t*)malloc(keyLenInBit / 8), //408 tmpData[68]; //= (uint8_t*)malloc(dataLenInBit / 8 + 4);//68 keyLenInBit /= 8; dataLenInBit /= 8;//תΪbyte�� memset(tmpRes, 0, keyLenInBit); memset(tmpData, 0, dataLenInBit + 4); uint32_t ct = 1; //a.��ʼ��32bit������ uint8_t hash[32] = { 0 }, ct2Byte[4] = { 0 }; //ct2Byte���������ֵһ��,ֻ��Ϊ�˷������ int realHashLen = 32; //ժҪ���� int maxLoopNum = (keyLenInBit + 31) / 32; //times = [klenInBit/v](����ȡ��) int i = 0; memcpy(tmpData, Z, dataLenInBit); for (i = 0; i < maxLoopNum; i++) { ct2Byte[0] = (ct >> 24) & 0xFF; ct2Byte[1] = (ct >> 16) & 0xFF; ct2Byte[2] = (ct >> 8) & 0xFF; ct2Byte[3] = (ct) & 0xFF; memcpy(tmpData + dataLenInBit, ct2Byte, 4); // Z || ct SM3(tmpData, dataLenInBit + 4, hash); //b. ����Hai = Hv(Z || ct) if (i == maxLoopNum - 1) //c. ����keylen/32�Ƿ���������ȡժҪ��ֵ { if (keyLenInBit % 32 != 0) { realHashLen = keyLenInBit % 32; } } memcpy(tmpRes + 32 * i, hash, realHashLen); //d. ÿ�ΰѽ�������� //i++; ct++; } memcpy(result, tmpRes, keyLenInBit); /*if (result != NULL) { }*/ //free(tmpRes); //free(tmpData); } void CalculateMessage(uint8_t* result, uint8_t* C2, uint8_t* t, int lenInByte) { for (int i = 0; i < lenInByte; i++) { result[i] = C2[i] ^ t[i]; } } //__global uint8_t C[505];//���������ý���ʱ���ֲ����������ݿ����Ѿ����������ˡ�C��Ψһһ��û��free�� __kernel void SM2Encrypt(__global uint8_t* Cw, __global char* messagePlain1, __global int* messageSizeInBit, __global EccPoint* pubKey1, __global uint256_t* randomK1, __global EccPoint* G1) { //EllipticCurveDef Ec[1]; EccPoint pointC1[1], kPb[1]; uint8_t t[408], x2[64], y2[32], C1[65], x1[32], y1[32], C2[408], C3[472]; char messagePlain[408]; int idx=get_global_id(0); for(int i=0;i<408;i++) { messagePlain[i]=messagePlain1[i]; } uint8_t C[505]; EccPoint G2={0}; G2.x[0]=G1->x[0]; G2.x[1]=G1->x[1]; G2.x[2]=G1->x[2]; G2.x[3]=G1->x[3]; G2.y[0]=G1->y[0]; G2.y[1]=G1->y[1]; G2.y[2]=G1->y[2]; G2.y[3]=G1->y[3]; EccPoint* G=&G2; EccPoint pubKey2={0}; pubKey2.x[0]=pubKey1->x[0]; pubKey2.x[1]=pubKey1->x[1]; pubKey2.x[2]=pubKey1->x[2]; pubKey2.x[3]=pubKey1->x[3]; pubKey2.y[0]=pubKey1->y[0]; pubKey2.y[1]=pubKey1->y[1]; pubKey2.y[2]=pubKey1->y[2]; pubKey2.y[3]=pubKey1->y[3]; EccPoint* pubKey=&pubKey2; uint256_t randomK={0}; randomK[0]=randomK1[idx][0]; randomK[1]=randomK1[idx][1]; randomK[2]=randomK1[idx][2]; randomK[3]=randomK1[idx][3]; CalculateC1(pointC1, randomK, G); //Uint256ToString(x1, pointC1->x); //Uint256ToString(y1, pointC1->y); //C1[0] = 0x04; //memcpy(C1 + 1, x1, 32); //memcpy(C1 + 33, y1, 32);//C1 = 04||x1||y1 //CalculateKPb(kPb, randomK, pubKey); //Uint256ToString(x2, kPb->x); //Uint256ToString(y2, kPb->y); //memcpy(C3, x2, 32); //memcpy(C3 + 32, messagePlain, messageSizeInBit[idx] / 8); //memcpy(C3 + 32 + messageSizeInBit[idx] / 8, y2, 32); //memcpy(x2 + 32, y2, 32);//x2 = x2 || y2 //KDF(t, x2, 64 * 8, messageSizeInBit[idx]); //t = KDF() //CalculateC2(C2, messagePlain, t, messageSizeInBit[idx] / 8); //C2 = M^t //SM3((uint8_t*)C3, 64 + messageSizeInBit[idx] / 8, (uint8_t*)C3); //C3 = SM3(x2||M||y2) //memcpy(C, C1, 65); //memcpy(C + 65, C2, messageSizeInBit[idx] / 8); //memcpy(C + 65 + messageSizeInBit[idx] / 8, C3, 32); //C = C1 || C2 || C3 for(int i=0;i<505;i++) { Cw[i]=C[i]; } }