├── sm3.c ├── sm3.h ├── Makefile ├── README.md ├── LICENSE ├── sm4.h ├── sm2.h ├── test_sm2.c ├── sm4.c └── sm2.c /sm3.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangbaoliu/sm2-sm3-sm4-realizaton/HEAD/sm3.c -------------------------------------------------------------------------------- /sm3.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangbaoliu/sm2-sm3-sm4-realizaton/HEAD/sm3.h -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: test_sm2 2 | 3 | sm3.o: sm3.c sm3.h 4 | $(CC) -c -o sm3.o sm3.c 5 | 6 | sm2.o: sm2.c sm2.h sm3.c sm3.h 7 | $(CC) -c -o sm2.o sm2.c 8 | 9 | %.o: %.c sm2.h sm3.h 10 | $(CC) -c $< -o $@ 11 | 12 | test_sm2: test_sm2.o sm2.o sm3.o 13 | $(CC) -o test_sm2 test_sm2.o sm2.o sm3.o 14 | 15 | clean: 16 | rm -f *.o test_sm2 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | sm2-sm3-sm4-realizaton 2 | ======== 3 | 4 | 这是一个纯软c实现的SM2、SM3、SM4函数库,未使用openssl等第三方库,目前仅支持256位SM2。代码基于nano-sm2实现(8位处理器上的ecc实现,详情见https://github.com/Aries-orz/nano-sm2)。 5 | 6 | Changes 7 | -------- 8 | 9 | 本代码主要在以下几方面对nano-sm2进行了改动: 10 | 11 | * 字节顺序按照x86 linux系统的小端模式; 12 | 13 | * 签名过程 - sm2_sign本代码完全按照SM2签名过程实现; 14 | 15 | * 验签过程 - sm2_verify本代码完全按照SM2验签过程实现; 16 | 17 | * 加密过程 - sm2_encrypt本代码完全按照SM2加密过程实现; 18 | 19 | * 解密过程 - sm2_decrypt本代码完全按照SM2解密过程实现; 20 | 21 | * 提供了sm3、sm4相关的接口函数; 22 | 23 | Usage Notes 24 | ----------- 25 | 26 | 使用时只需将sm2.h、sm2.c、sm3.h、sm3.c加入自己的项目工程中,然后再include头文件sm2.h即可。test_sm2.c为测试算法的样例。 27 | 28 | Parameters 29 | ----------- 30 | 31 | 另附本代码使用的SM2官方推荐参数(256位): 32 | 椭圆曲线方程:y^2 = x^3 + ax + b 33 | 曲线参数: 34 | p=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF 35 | a=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC 36 | b=28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93 37 | n=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123 38 | Gx=32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7 39 | Gy=BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Mike Ryan 2 | Based on micro-ecc, Copyright (c) 2013, Kenneth MacKay 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /sm4.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file sm4.h 3 | */ 4 | #ifndef XYSSL_SM4_H 5 | #define XYSSL_SM4_H 6 | 7 | #define SM4_ENCRYPT 1 8 | #define SM4_DECRYPT 0 9 | 10 | /** 11 | * \brief SM4 context structure 12 | */ 13 | typedef struct 14 | { 15 | int mode; /*!< encrypt/decrypt */ 16 | unsigned int sk[32]; /*!< SM4 subkeys */ 17 | } 18 | sm4_context; 19 | 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** 26 | * \brief SM4 key schedule (128-bit, encryption) 27 | * 28 | * \param ctx SM4 context to be initialized 29 | * \param key 16-byte secret key 30 | */ 31 | void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] ); 32 | 33 | /** 34 | * \brief SM4 key schedule (128-bit, decryption) 35 | * 36 | * \param ctx SM4 context to be initialized 37 | * \param key 16-byte secret key 38 | */ 39 | void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] ); 40 | 41 | /** 42 | * \brief SM4-ECB block encryption/decryption 43 | * \param ctx SM4 context 44 | * \param mode SM4_ENCRYPT or SM4_DECRYPT 45 | * \param length length of the input data 46 | * \param input input block 47 | * \param output output block 48 | */ 49 | void sm4_crypt_ecb( sm4_context *ctx, 50 | unsigned int mode, 51 | unsigned int length, 52 | unsigned char *input, 53 | unsigned char *output); 54 | 55 | /** 56 | * \brief SM4-CBC buffer encryption/decryption 57 | * \param ctx SM4 context 58 | * \param mode SM4_ENCRYPT or SM4_DECRYPT 59 | * \param length length of the input data 60 | * \param iv initialization vector (updated after use) 61 | * \param input buffer holding the input data 62 | * \param output buffer holding the output data 63 | */ 64 | void sm4_crypt_cbc( sm4_context *ctx, 65 | unsigned int mode, 66 | unsigned int length, 67 | unsigned char iv[16], 68 | unsigned char *input, 69 | unsigned char *output ); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif /* sm4.h */ 76 | -------------------------------------------------------------------------------- /sm2.h: -------------------------------------------------------------------------------- 1 | #ifndef _MICRO_SM2_H_ 2 | #define _MICRO_SM2_H_ 3 | 4 | #include 5 | 6 | /*Define to enable SM2 debug function*/ 7 | //#define __SM2_DEBUG__ 8 | 9 | /* Define as 1 to enable ECDSA functions, 0 to disable. 10 | */ 11 | #define SM2_ECDSA 1 12 | 13 | /* Optimization settings. Define as 1 to enable an optimization, 0 to disable it. 14 | ECC_SQUARE_FUNC - If enabled, this will cause a specific function to be used for (scalar) squaring instead of the generic 15 | multiplication function. Improves speed by about 8% . 16 | */ 17 | #define ECC_SQUARE_FUNC 1 18 | 19 | /* Inline assembly options. 20 | Currently we do not provide any inline assembly options. In the future we plan to offer 21 | inline assembly for AVR and 8051. 22 | 23 | Note: You must choose the appropriate option for your target architecture, or compilation will fail 24 | with strange assembler messages. 25 | */ 26 | #define ecc_asm_none 0 27 | #ifndef ECC_ASM 28 | #define ECC_ASM ecc_asm_none 29 | #endif 30 | 31 | /* Currently only support 256-bit SM2 */ 32 | #define NUM_ECC_DIGITS 32 33 | 34 | typedef struct EccPoint 35 | { 36 | uint8_t x[NUM_ECC_DIGITS]; 37 | uint8_t y[NUM_ECC_DIGITS]; 38 | } EccPoint; 39 | 40 | typedef struct EccSig 41 | { 42 | uint8_t r[NUM_ECC_DIGITS]; 43 | uint8_t s[NUM_ECC_DIGITS]; 44 | } EccSig; 45 | 46 | 47 | /* ecc_make_key() function. 48 | Create a public/private key pair. 49 | 50 | You must use a new nonpredictable random number to generate each new key pair. 51 | 52 | Outputs: 53 | p_publicKey - Will be filled in with the point representing the public key. 54 | p_privateKey - Will be filled in with the private key. 55 | 56 | Inputs: 57 | p_random - The random number to use to generate the key pair. 58 | 59 | Returns 1 if the key pair was generated successfully, 0 if an error occurred. If 0 is returned, 60 | try again with a different random number. 61 | */ 62 | int ecc_make_key(EccPoint *p_publicKey, uint8_t p_privateKey[NUM_ECC_DIGITS], uint8_t p_random[NUM_ECC_DIGITS]); 63 | 64 | /* ecc_valid_public_key() function. 65 | Determine whether or not a given point is on the chosen elliptic curve (ie, is a valid public key). 66 | 67 | Inputs: 68 | p_publicKey - The point to check. 69 | 70 | Returns 1 if the given point is valid, 0 if it is invalid. 71 | */ 72 | int ecc_valid_public_key(EccPoint *p_publicKey); 73 | 74 | /* ecdh_shared_secret() function. 75 | Compute a shared secret given your secret key and someone else's public key. 76 | 77 | Optionally, you can provide a random multiplier for resistance to DPA attacks. The random multiplier 78 | should probably be different for each invocation of ecdh_shared_secret(). 79 | 80 | Outputs: 81 | p_secret - Will be filled in with the shared secret value. 82 | 83 | Inputs: 84 | p_publicKey - The public key of the remote party. 85 | p_privateKey - Your private key. 86 | p_random - An optional random number to resist DPA attacks. Pass in NULL if DPA attacks are not a concern. 87 | 88 | Returns 1 if the shared secret was computed successfully, 0 otherwise. 89 | 90 | Note: It is recommended that you hash the result of ecdh_shared_secret before using it for symmetric encryption or HMAC. 91 | If you do not hash the shared secret, you must call ecc_valid_public_key() to verify that the remote side's public key is valid. 92 | If this is not done, an attacker could create a public key that would cause your use of the shared secret to leak information 93 | about your private key. */ 94 | int ecdh_shared_secret(uint8_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey, uint8_t p_privateKey[NUM_ECC_DIGITS], uint8_t p_random[NUM_ECC_DIGITS]); 95 | 96 | #if SM2_ECDSA 97 | 98 | //added by lhb 99 | int sm2_get_e(char *IDa, int IDLen, unsigned char *xa, unsigned char *ya, unsigned char *plaintext, unsigned int plainLen, unsigned char *e); 100 | /*sm2 签名接口*/ 101 | int sm2_sign(EccSig *sig, uint8_t *msg, unsigned int msg_len, uint8_t *IDa, uint8_t IDa_len, uint8_t p_privateKey[NUM_ECC_DIGITS], uint8_t p_random[NUM_ECC_DIGITS]); 102 | /*sm2 验签接口*/ 103 | int sm2_verify(EccSig *sig, uint8_t *msg, unsigned int msg_len, uint8_t *IDa, uint8_t IDa_len, EccPoint *p_pubk); 104 | /*sm2 加密接口*/ 105 | int sm2_encrypt(uint8_t *cipher_text, unsigned int *cipher_len, EccPoint *p_publicKey, uint8_t p_random[NUM_ECC_DIGITS], uint8_t *plain_text, unsigned int plain_len); 106 | /*sm2 解密接口*/ 107 | int sm2_decrypt(uint8_t *plain_text, uint8_t *plain_len, uint8_t *cipher_text, uint8_t cipher_len, uint8_t p_privateKey[NUM_ECC_DIGITS]); 108 | 109 | 110 | /* ecdsa_sign() function. 111 | Generate an ECDSA signature for a given hash value. 112 | 113 | Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to 114 | this function along with your private key and a random number. 115 | You must use a new nonpredictable random number to generate each new signature. 116 | 117 | Outputs: 118 | r, s - Will be filled in with the signature values. 119 | 120 | Inputs: 121 | p_privateKey - Your private key. 122 | p_random - The random number to use to generate the signature. 123 | p_hash - The message hash to sign. 124 | 125 | Returns 1 if the signature generated successfully, 0 if an error occurred. If 0 is returned, 126 | try again with a different random number. 127 | */ 128 | int ecdsa_sign(uint8_t r[NUM_ECC_DIGITS], uint8_t s[NUM_ECC_DIGITS], uint8_t p_privateKey[NUM_ECC_DIGITS], 129 | uint8_t p_random[NUM_ECC_DIGITS], uint8_t p_hash[NUM_ECC_DIGITS]); 130 | 131 | /* ecdsa_verify() function. 132 | Verify an ECDSA signature. 133 | 134 | Usage: Compute the hash of the signed data using the same hash as the signer and 135 | pass it to this function along with the signer's public key and the signature values (r and s). 136 | 137 | Inputs: 138 | p_publicKey - The signer's public key 139 | p_hash - The hash of the signed data. 140 | r, s - The signature values. 141 | 142 | Returns 1 if the signature is valid, 0 if it is invalid. 143 | */ 144 | int ecdsa_verify(EccPoint *p_publicKey, uint8_t p_hash[NUM_ECC_DIGITS], uint8_t r[NUM_ECC_DIGITS], uint8_t s[NUM_ECC_DIGITS]); 145 | 146 | #endif /* ECC_ECDSA */ 147 | 148 | /* ecc_bytes2native() function. 149 | Convert an integer in standard octet representation to the native format. 150 | 151 | Outputs: 152 | p_native - Will be filled in with the native integer value. 153 | 154 | Inputs: 155 | p_bytes - The standard octet representation of the integer to convert. 156 | */ 157 | void ecc_bytes2native(uint8_t p_native[NUM_ECC_DIGITS], uint8_t p_bytes[NUM_ECC_DIGITS*4]); 158 | 159 | /* ecc_native2bytes() function. 160 | Convert an integer in native format to the standard octet representation. 161 | 162 | Outputs: 163 | p_bytes - Will be filled in with the standard octet representation of the integer. 164 | 165 | Inputs: 166 | p_native - The native integer value to convert. 167 | */ 168 | void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS*4], uint8_t p_native[NUM_ECC_DIGITS]); 169 | 170 | #endif /* _MICRO_SM2_H_ */ 171 | -------------------------------------------------------------------------------- /test_sm2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sm2.h" 3 | 4 | void tohex(const uint8_t *source, uint8_t *result, int len) 5 | { 6 | uint8_t h1,h2; 7 | uint8_t s1,s2; 8 | int i; 9 | for (i=0; i 9) 15 | s1 = s1 - ('A' - ':'); 16 | s2 = toupper(h2) - '0'; 17 | if (s2 > 9) 18 | s2 = s2 - ('A' - ':'); 19 | 20 | result[i] = s1*16 + s2; 21 | } 22 | } 23 | 24 | void test_sm2_verify() 25 | { 26 | int i = 0; 27 | EccSig sig; 28 | 29 | EccPoint p_publicKey = {\ 30 | {0x09, 0xF9, 0xDF, 0x31, 0x1E, 0x54, 0x21, 0xA1, 0x50, 0xDD, 0x7D, 0x16, 0x1E, 0x4B, 0xC5, 0xC6, 0x72, 0x17, 0x9F, 0xAD, 0x18, 0x33, 0xFC, 0x07, 0x6B, 0xB0, 0x8F, 0xF3, 0x56, 0xF3, 0x50, 0x20}, \ 31 | {0xCC, 0xEA, 0x49, 0x0C, 0xE2, 0x67, 0x75, 0xA5, 0x2D, 0xC6, 0xEA, 0x71, 0x8C, 0xC1, 0xAA, 0x60, 0x0A, 0xED, 0x05, 0xFB, 0xF3, 0x5E, 0x08, 0x4A, 0x66, 0x32, 0xF6, 0x07, 0x2D, 0xA9, 0xAD, 0x13}}; 32 | 33 | uint8_t id_buf[128]; 34 | uint8_t msg_buf[NUM_ECC_DIGITS]; 35 | 36 | uint8_t pukx_str[] = "27AE9564D854B5585BF1662225B9AF566A3877F389AB64B085D52ABE02D98859"; 37 | uint8_t puky_str[] = "3912F8185ED47FC41574FB6BDB5EE118643CA11FCF655E3336B3E6C36A8F1645"; 38 | uint8_t id_str[] = "C8A427891024E0F839875DC5435C4A20CA5BC75A8CE30B3B26A74D0E1EA4E4E0"; 39 | 40 | uint8_t msg_str[] = "2656AD299F2BADE95D38F7F7AA2AD096"; 41 | int msg_len = 0x10; 42 | 43 | uint8_t r_str[] = "D95A7B97A779DBFA5EA3426482C5DDDDD331C85122AEE8329813A3BBFE51AC93"; 44 | uint8_t s_str[] = "25AFEE39CDF951F9CBAAB98899799375A84DB02BB0BF7C99680579EE7C8406C6"; 45 | 46 | tohex(pukx_str, p_publicKey.x, NUM_ECC_DIGITS); 47 | tohex(puky_str, p_publicKey.y, NUM_ECC_DIGITS); 48 | 49 | tohex(id_str, id_buf, NUM_ECC_DIGITS); 50 | id_buf[NUM_ECC_DIGITS] = '\0'; 51 | tohex(msg_str, msg_buf, msg_len); 52 | tohex(r_str, sig.r, NUM_ECC_DIGITS); 53 | tohex(s_str, sig.s, NUM_ECC_DIGITS); 54 | 55 | printf("r:"); 56 | for (i = 0; i 57 | #include 58 | 59 | /* 60 | * 32-bit integer manipulation macros (big endian) 61 | */ 62 | #ifndef GET_ULONG_BE 63 | #define GET_ULONG_BE(n,b,i) \ 64 | { \ 65 | (n) = ( (unsigned int) (b)[(i) ] << 24 ) \ 66 | | ( (unsigned int) (b)[(i) + 1] << 16 ) \ 67 | | ( (unsigned int) (b)[(i) + 2] << 8 ) \ 68 | | ( (unsigned int) (b)[(i) + 3] ); \ 69 | } 70 | #endif 71 | 72 | #ifndef PUT_ULONG_BE 73 | #define PUT_ULONG_BE(n,b,i) \ 74 | { \ 75 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 76 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 77 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 78 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 79 | } 80 | #endif 81 | 82 | /* 83 | *rotate shift left marco definition 84 | * 85 | */ 86 | #define SHL(x,n) (((x) & 0xFFFFFFFF) << n) 87 | #define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n))) 88 | #define SWAP(a,b) { unsigned int t = a; a = b; b = t; t = 0; } 89 | 90 | /* 91 | * Expanded SM4 S-boxes 92 | /* Sbox table: 8bits input convert to 8 bits output*/ 93 | 94 | static const unsigned char SboxTable[16][16] = 95 | { 96 | {0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05}, 97 | {0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99}, 98 | {0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62}, 99 | {0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6}, 100 | {0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8}, 101 | {0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35}, 102 | {0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87}, 103 | {0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e}, 104 | {0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1}, 105 | {0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3}, 106 | {0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f}, 107 | {0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51}, 108 | {0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8}, 109 | {0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0}, 110 | {0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84}, 111 | {0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48} 112 | }; 113 | 114 | /* System parameter FK*/ 115 | static const unsigned int FK[4] = {0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc}; 116 | 117 | /* fixed parameter CK*/ 118 | static const unsigned int CK[32] = 119 | { 120 | 0x00070e15,0x1c232a31,0x383f464d,0x545b6269, 121 | 0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9, 122 | 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249, 123 | 0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9, 124 | 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229, 125 | 0x30373e45,0x4c535a61,0x686f767d,0x848b9299, 126 | 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209, 127 | 0x10171e25,0x2c333a41,0x484f565d,0x646b7279 128 | }; 129 | 130 | 131 | /* 132 | * private function: 133 | * look up in SboxTable and get the related value. 134 | * args: [in] inch: 0x00~0xFF (8 bits unsigned value). 135 | */ 136 | static unsigned char sm4Sbox(unsigned char inch) 137 | { 138 | unsigned char *pTable = (unsigned char *)SboxTable; 139 | unsigned char retVal = (unsigned char)(pTable[inch]); 140 | return retVal; 141 | } 142 | 143 | /* 144 | * private F(Lt) function: 145 | * "T algorithm" == "L algorithm" + "t algorithm". 146 | * args: [in] a: a is a 32 bits unsigned value; 147 | * return: c: c is calculated with line algorithm "L" and nonline algorithm "t" 148 | */ 149 | static unsigned int sm4Lt(unsigned int ka) 150 | { 151 | unsigned int bb = 0; 152 | unsigned int C = 0; 153 | unsigned char a[4]; 154 | unsigned char b[4]; 155 | PUT_ULONG_BE(ka,a,0) 156 | b[0] = sm4Sbox(a[0]); 157 | b[1] = sm4Sbox(a[1]); 158 | b[2] = sm4Sbox(a[2]); 159 | b[3] = sm4Sbox(a[3]); 160 | GET_ULONG_BE(bb,b,0) 161 | C = bb^(ROTL(bb, 2))^(ROTL(bb, 10))^(ROTL(bb, 18))^(ROTL(bb, 24)); 162 | return C; 163 | } 164 | 165 | /* 166 | * private F function: 167 | * Calculating and getting encryption/decryption contents. 168 | * args: [in] x0: original contents; 169 | * args: [in] x1: original contents; 170 | * args: [in] x2: original contents; 171 | * args: [in] x3: original contents; 172 | * args: [in] rk: encryption/decryption key; 173 | * return the contents of encryption/decryption contents. 174 | */ 175 | static unsigned int sm4F(unsigned int x0, unsigned int x1, unsigned int x2, unsigned int x3, unsigned int rk) 176 | { 177 | return (x0^sm4Lt(x1^x2^x3^rk)); 178 | } 179 | 180 | 181 | /* private function: 182 | * Calculating round encryption key. 183 | * args: [in] a: a is a 32 bits unsigned value; 184 | * return: sk[i]: i{0,1,2,3,...31}. 185 | */ 186 | static unsigned int sm4CalciRK(unsigned int ka) 187 | { 188 | unsigned int bb = 0; 189 | unsigned int rk = 0; 190 | unsigned char a[4]; 191 | unsigned char b[4]; 192 | PUT_ULONG_BE(ka,a,0) 193 | b[0] = sm4Sbox(a[0]); 194 | b[1] = sm4Sbox(a[1]); 195 | b[2] = sm4Sbox(a[2]); 196 | b[3] = sm4Sbox(a[3]); 197 | GET_ULONG_BE(bb,b,0) 198 | /*L'(B)*/ 199 | rk = bb^(ROTL(bb, 13))^(ROTL(bb, 23)); 200 | return rk; 201 | } 202 | 203 | /*key expand function*/ 204 | static void sm4_setkey( unsigned int SK[32], unsigned char key[16] ) 205 | { 206 | unsigned int MK[4]; 207 | unsigned int k[36]; 208 | unsigned int i = 0; 209 | 210 | GET_ULONG_BE( MK[0], key, 0 ); 211 | GET_ULONG_BE( MK[1], key, 4 ); 212 | GET_ULONG_BE( MK[2], key, 8 ); 213 | GET_ULONG_BE( MK[3], key, 12 ); 214 | k[0] = MK[0]^FK[0]; 215 | k[1] = MK[1]^FK[1]; 216 | k[2] = MK[2]^FK[2]; 217 | k[3] = MK[3]^FK[3]; 218 | for(; i<32; i++) 219 | { 220 | k[i+4] = k[i] ^ (sm4CalciRK(k[i+1]^k[i+2]^k[i+3]^CK[i])); 221 | SK[i] = k[i+4]; 222 | } 223 | } 224 | 225 | /* 226 | * SM4 standard one round processing 227 | * 228 | */ 229 | static void sm4_one_round(unsigned int sk[32], unsigned char input[16], unsigned char output[16] ) 230 | { 231 | unsigned int i = 0; 232 | unsigned int X[36]; 233 | 234 | memset(X, 0, sizeof(X)); 235 | GET_ULONG_BE( X[0], input, 0 ) 236 | GET_ULONG_BE( X[1], input, 4 ) 237 | GET_ULONG_BE( X[2], input, 8 ) 238 | GET_ULONG_BE( X[3], input, 12 ) 239 | while(i<32) 240 | { 241 | X[i+4] = sm4F(X[i], X[i+1], X[i+2], X[i+3], sk[i]); 242 | i++; 243 | } 244 | PUT_ULONG_BE(X[35], output,0); 245 | PUT_ULONG_BE(X[34], output,4); 246 | PUT_ULONG_BE(X[33], output,8); 247 | PUT_ULONG_BE(X[32], output,12); 248 | } 249 | 250 | /*encode and decode round key revert*/ 251 | /* 252 | * SM4 key schedule (128-bit, encryption) 253 | */ 254 | void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] ) 255 | { 256 | ctx->mode = SM4_ENCRYPT; 257 | sm4_setkey( ctx->sk, key ); 258 | } 259 | 260 | /* 261 | * SM4 key schedule (128-bit, decryption) 262 | */ 263 | void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] ) 264 | { 265 | int i; 266 | ctx->mode = SM4_DECRYPT; 267 | sm4_setkey( ctx->sk, key ); 268 | for( i = 0; i < 16; i ++ ) 269 | { 270 | SWAP( ctx->sk[ i ], ctx->sk[ 31-i] ); 271 | } 272 | } 273 | 274 | 275 | /* 276 | * SM4-ECB block encryption/decryption 277 | */ 278 | void sm4_crypt_ecb( sm4_context *ctx, 279 | unsigned int mode, 280 | unsigned int length, 281 | unsigned char *input, 282 | unsigned char *output) 283 | { 284 | while( length > 0 ) 285 | { 286 | sm4_one_round(ctx->sk, input, output ); 287 | input += 16; 288 | output += 16; 289 | length -= 16; 290 | } 291 | 292 | } 293 | 294 | /* 295 | * SM4-CBC buffer encryption/decryption 296 | */ 297 | void sm4_crypt_cbc( sm4_context *ctx, 298 | unsigned int mode, 299 | unsigned int length, 300 | unsigned char iv[16], 301 | unsigned char *input, 302 | unsigned char *output ) 303 | { 304 | int i; 305 | unsigned char temp[16]; 306 | 307 | if( mode == SM4_ENCRYPT ) 308 | { 309 | while( length > 0 ) 310 | { 311 | for( i = 0; i < 16; i++ ) 312 | output[i] = (unsigned char)( input[i] ^ iv[i] ); 313 | 314 | sm4_one_round( ctx->sk, output, output ); 315 | memcpy( iv, output, 16 ); 316 | 317 | input += 16; 318 | output += 16; 319 | length -= 16; 320 | } 321 | } 322 | else /* SM4_DECRYPT */ 323 | { 324 | while( length > 0 ) 325 | { 326 | memcpy( temp, input, 16 ); 327 | sm4_one_round( ctx->sk, input, output ); 328 | 329 | for( i = 0; i < 16; i++ ) 330 | output[i] = (unsigned char)( output[i] ^ iv[i] ); 331 | 332 | memcpy( iv, temp, 16 ); 333 | 334 | input += 16; 335 | output += 16; 336 | length -= 16; 337 | } 338 | } 339 | } 340 | -------------------------------------------------------------------------------- /sm2.c: -------------------------------------------------------------------------------- 1 | #include "sm3.h" 2 | #include "sm2.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef unsigned int uint; 9 | 10 | #define CONCAT1(a, b) a##b 11 | #define CONCAT(a, b) CONCAT1(a, b) 12 | 13 | #define Curve_A_32 {0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF} 14 | 15 | #define Curve_P_32 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF} 16 | 17 | #define Curve_B_32 {0x93, 0x0E, 0x94, 0x4D, 0x41, 0xBD, 0xBC, 0xDD, 0x92, 0x8F, 0xAB, 0x15, 0xF5, 0x89, 0x97, 0xF3, 0xA7, 0x09, 0x65, 0xCF, 0x4B, 0x9E, 0x5A, 0x4D, 0x34, 0x5E, 0x9F, 0x9D, 0x9E, 0xFA, 0xE9, 0x28} 18 | 19 | #define Curve_G_32 { \ 20 | {0xC7, 0x74, 0x4C, 0x33, 0x89, 0x45, 0x5A, 0x71, 0xE1, 0x0B, 0x66, 0xF2, 0xBF, 0x0B, 0xE3, 0x8F, 0x94, 0xC9, 0x39, 0x6A, 0x46, 0x04, 0x99, 0x5F, 0x19, 0x81, 0x19, 0x1F, 0x2C, 0xAE, 0xC4, 0x32}, \ 21 | {0xA0, 0xF0, 0x39, 0x21, 0xE5, 0x32, 0xDF, 0x02, 0x40, 0x47, 0x2A, 0xC6, 0x7C, 0x87, 0xA9, 0xD0, 0x53, 0x21, 0x69, 0x6B, 0xE3, 0xCE, 0xBD, 0x59, 0x9C, 0x77, 0xF6, 0xF4, 0xA2, 0x36, 0x37, 0xBC}} 22 | 23 | #define Curve_N_32 {0x23, 0x41, 0xD5, 0x39, 0x09, 0xF4, 0xBB, 0x53, 0x2B, 0x05, 0xC6, 0x21, 0x6B, 0xDF, 0x03, 0x72, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF} 24 | 25 | static uint8_t curve_a[NUM_ECC_DIGITS] = CONCAT(Curve_A_, NUM_ECC_DIGITS); 26 | static uint8_t curve_p[NUM_ECC_DIGITS] = CONCAT(Curve_P_, NUM_ECC_DIGITS); 27 | static uint8_t curve_b[NUM_ECC_DIGITS] = CONCAT(Curve_B_, NUM_ECC_DIGITS); 28 | static EccPoint curve_G = CONCAT(Curve_G_, NUM_ECC_DIGITS); 29 | static uint8_t curve_n[NUM_ECC_DIGITS] = CONCAT(Curve_N_, NUM_ECC_DIGITS); 30 | 31 | static void vli_modMult(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right, uint8_t *p_mod); 32 | 33 | static void vli_clear(uint8_t *p_vli) 34 | { 35 | uint i; 36 | for(i=0; i= 0 && p_vli[i] == 0; --i) 69 | { 70 | } 71 | 72 | return (i + 1); 73 | } 74 | 75 | /* Counts the number of bits required for p_vli. */ 76 | static uint vli_numBits(uint8_t *p_vli) 77 | { 78 | uint i; 79 | uint8_t l_digit; 80 | 81 | uint l_numDigits = vli_numDigits(p_vli); 82 | if(l_numDigits == 0) 83 | { 84 | return 0; 85 | } 86 | 87 | l_digit = p_vli[l_numDigits - 1]; 88 | for(i=0; l_digit; ++i) 89 | { 90 | l_digit >>= 1; 91 | } 92 | 93 | return ((l_numDigits - 1) * 8 + i); 94 | } 95 | 96 | /* Sets p_dest = p_src. */ 97 | static void vli_set(uint8_t *p_dest, uint8_t *p_src) 98 | { 99 | uint i; 100 | for(i=0; i= 0; --i) 111 | { 112 | if(p_left[i] > p_right[i]) 113 | { 114 | return 1; 115 | } 116 | else if(p_left[i] < p_right[i]) 117 | { 118 | return -1; 119 | } 120 | } 121 | return 0; 122 | } 123 | 124 | /* Computes p_result = p_in << c, returning carry. Can modify in place (if p_result == p_in). 0 < p_shift < 8. */ 125 | static uint8_t vli_lshift(uint8_t *p_result, uint8_t *p_in, uint p_shift) 126 | { 127 | uint8_t l_carry = 0; 128 | uint i; 129 | for(i = 0; i < NUM_ECC_DIGITS; ++i) 130 | { 131 | uint8_t l_temp = p_in[i]; 132 | p_result[i] = (l_temp << p_shift) | l_carry; 133 | l_carry = l_temp >> (8 - p_shift); 134 | } 135 | 136 | return l_carry; 137 | } 138 | 139 | /* Computes p_vli = p_vli >> 1. */ 140 | static void vli_rshift1(uint8_t *p_vli) 141 | { 142 | uint8_t *l_end = p_vli; 143 | uint8_t l_carry = 0; 144 | 145 | p_vli += NUM_ECC_DIGITS; 146 | while(p_vli-- > l_end) 147 | { 148 | uint8_t l_temp = *p_vli; 149 | *p_vli = (l_temp >> 1) | l_carry; 150 | l_carry = l_temp << 7; 151 | } 152 | } 153 | 154 | /* Computes p_result = p_left + p_right, returning carry. Can modify in place. */ 155 | static uint8_t vli_add(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) 156 | { 157 | uint8_t l_carry = 0; 158 | uint i; 159 | for(i=0; i p_left[i]); 183 | } 184 | p_result[i] = l_diff; 185 | } 186 | return l_borrow; 187 | } 188 | 189 | /* Computes p_result = p_left * p_right. */ 190 | static void vli_mult(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) 191 | { 192 | uint16_t r01 = 0; 193 | uint8_t r2 = 0; 194 | 195 | uint i, k; 196 | 197 | /* Compute each digit of p_result in sequence, maintaining the carries. */ 198 | for(k=0; k < NUM_ECC_DIGITS*2 - 1; ++k) 199 | { 200 | uint l_min = (k < NUM_ECC_DIGITS ? 0 : (k + 1) - NUM_ECC_DIGITS); 201 | for(i=l_min; i<=k && i> 8) | (((uint16_t)r2) << 8); 209 | r2 = 0; 210 | } 211 | 212 | p_result[NUM_ECC_DIGITS*2 - 1] = (uint8_t)r01; 213 | } 214 | 215 | /* Computes p_result = (p_left + p_right) % p_mod. 216 | Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ 217 | static void vli_modAdd(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right, uint8_t *p_mod) 218 | { 219 | uint8_t l_carry = vli_add(p_result, p_left, p_right); 220 | if(l_carry || vli_cmp(p_result, p_mod) >= 0) 221 | { /* p_result > p_mod (p_result = p_mod + remainder), so subtract p_mod to get remainder. */ 222 | vli_sub(p_result, p_result, p_mod); 223 | } 224 | } 225 | 226 | /* Computes p_result = (p_left - p_right) % p_mod. 227 | Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ 228 | static void vli_modSub(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right, uint8_t *p_mod) 229 | { 230 | uint8_t l_borrow = vli_sub(p_result, p_left, p_right); 231 | if(l_borrow) 232 | { /* In this case, p_result == -diff == (max int) - diff. 233 | Since -x % d == d - x, we can get the correct result from p_result + p_mod (with overflow). */ 234 | vli_add(p_result, p_result, p_mod); 235 | } 236 | } 237 | 238 | static void vli_mmod_fast(uint8_t *p_result, uint8_t *p_product) { 239 | uint8_t l_tmp1[NUM_ECC_DIGITS]; 240 | uint8_t l_tmp2[NUM_ECC_DIGITS]; 241 | uint8_t l_tmp3[NUM_ECC_DIGITS]; 242 | int l_carry = 0; 243 | 244 | vli_set(p_result, p_product); 245 | vli_clear(l_tmp1); 246 | vli_clear(l_tmp2); 247 | vli_clear(l_tmp3); 248 | 249 | /* Y0 */ 250 | l_tmp1[0] = l_tmp1[12] = l_tmp1[28] = p_product[32]; 251 | l_tmp1[1] = l_tmp1[13] = l_tmp1[29] = p_product[33]; 252 | l_tmp1[2] = l_tmp1[14] = l_tmp1[30] = p_product[34]; 253 | l_tmp1[3] = l_tmp1[15] = l_tmp1[31] = p_product[35]; 254 | l_tmp2[8] = p_product[32]; 255 | l_tmp2[9] = p_product[33]; 256 | l_tmp2[10] = p_product[34]; 257 | l_tmp2[11] = p_product[35]; 258 | l_carry += vli_add(p_result, p_result, l_tmp1); 259 | l_carry -= vli_sub(p_result, p_result, l_tmp2); 260 | 261 | /* Y1 */ 262 | l_tmp1[0] = l_tmp1[4] = l_tmp1[16] = l_tmp1[28] = p_product[36]; 263 | l_tmp1[1] = l_tmp1[5] = l_tmp1[17] = l_tmp1[29] = p_product[37]; 264 | l_tmp1[2] = l_tmp1[6] = l_tmp1[18] = l_tmp1[30] = p_product[38]; 265 | l_tmp1[3] = l_tmp1[7] = l_tmp1[19] = l_tmp1[31] = p_product[39]; 266 | l_tmp1[12] = l_tmp1[13] = l_tmp1[14] = l_tmp1[15] = 0; 267 | l_tmp2[8] = p_product[36]; 268 | l_tmp2[9] = p_product[37]; 269 | l_tmp2[10] = p_product[38]; 270 | l_tmp2[11] = p_product[39]; 271 | l_carry += vli_add(p_result, p_result, l_tmp1); 272 | l_carry -= vli_sub(p_result, p_result, l_tmp2); 273 | 274 | /* Y2 */ 275 | l_tmp1[0] = l_tmp1[4] = l_tmp1[20] = l_tmp1[28] = p_product[40]; 276 | l_tmp1[1] = l_tmp1[5] = l_tmp1[21] = l_tmp1[29] = p_product[41]; 277 | l_tmp1[2] = l_tmp1[6] = l_tmp1[22] = l_tmp1[30] = p_product[42]; 278 | l_tmp1[3] = l_tmp1[7] = l_tmp1[23] = l_tmp1[31] = p_product[43]; 279 | l_tmp1[16] = l_tmp1[17] = l_tmp1[18] = l_tmp1[19] = 0; 280 | l_carry += vli_add(p_result, p_result, l_tmp1); 281 | 282 | /* Y3 */ 283 | l_tmp1[0] = l_tmp1[4] = l_tmp1[12] = l_tmp1[24] = l_tmp1[28] = p_product[44]; 284 | l_tmp1[1] = l_tmp1[5] = l_tmp1[13] = l_tmp1[25] = l_tmp1[29] = p_product[45]; 285 | l_tmp1[2] = l_tmp1[6] = l_tmp1[14] = l_tmp1[26] = l_tmp1[30] = p_product[46]; 286 | l_tmp1[3] = l_tmp1[7] = l_tmp1[15] = l_tmp1[27] = l_tmp1[31] = p_product[47]; 287 | l_tmp1[20] = l_tmp1[21] = l_tmp1[22] = l_tmp1[23] = 0; 288 | l_carry += vli_add(p_result, p_result, l_tmp1); 289 | 290 | /* Y4 */ 291 | l_tmp1[0] = l_tmp1[4] = l_tmp1[12] = l_tmp1[16] = l_tmp1[28] = l_tmp3[28] = p_product[48]; 292 | l_tmp1[1] = l_tmp1[5] = l_tmp1[13] = l_tmp1[17] = l_tmp1[29] = l_tmp3[29] = p_product[49]; 293 | l_tmp1[2] = l_tmp1[6] = l_tmp1[14] = l_tmp1[18] = l_tmp1[30] = l_tmp3[30] = p_product[50]; 294 | l_tmp1[3] = l_tmp1[7] = l_tmp1[15] = l_tmp1[19] = l_tmp1[31] = l_tmp3[31] = p_product[51]; 295 | l_tmp1[24] = l_tmp1[25] = l_tmp1[26] = l_tmp1[27] = 0; 296 | l_carry += vli_add(p_result, p_result, l_tmp1); 297 | l_carry += vli_add(p_result, p_result, l_tmp3); 298 | 299 | /* Y5 */ 300 | l_tmp1[0] = l_tmp1[4] = l_tmp1[12] = l_tmp1[16] = l_tmp1[20] = l_tmp1[28] = p_product[52]; 301 | l_tmp1[1] = l_tmp1[5] = l_tmp1[13] = l_tmp1[17] = l_tmp1[21] = l_tmp1[29] = p_product[53]; 302 | l_tmp1[2] = l_tmp1[6] = l_tmp1[14] = l_tmp1[18] = l_tmp1[22] = l_tmp1[30] = p_product[54]; 303 | l_tmp1[3] = l_tmp1[7] = l_tmp1[15] = l_tmp1[19] = l_tmp1[23] = l_tmp1[31] = p_product[55]; 304 | l_tmp2[8] = p_product[52]; 305 | l_tmp2[9] = p_product[53]; 306 | l_tmp2[10] = p_product[54]; 307 | l_tmp2[11] = p_product[55]; 308 | l_tmp3[0] = l_tmp3[12] = l_tmp3[28] = p_product[52]; 309 | l_tmp3[1] = l_tmp3[13] = l_tmp3[29] = p_product[53]; 310 | l_tmp3[2] = l_tmp3[14] = l_tmp3[30] = p_product[54]; 311 | l_tmp3[3] = l_tmp3[15] = l_tmp3[31] = p_product[55]; 312 | l_carry += vli_add(p_result, p_result, l_tmp1); 313 | l_carry += vli_add(p_result, p_result, l_tmp3); 314 | l_carry -= vli_sub(p_result, p_result, l_tmp2); 315 | 316 | /* Y6 */ 317 | l_tmp1[0] = l_tmp1[4] = l_tmp1[12] = l_tmp1[16] = l_tmp1[20] = l_tmp1[24] = l_tmp1[28] = p_product[56]; 318 | l_tmp1[1] = l_tmp1[5] = l_tmp1[13] = l_tmp1[17] = l_tmp1[21] = l_tmp1[25] = l_tmp1[29] = p_product[57]; 319 | l_tmp1[2] = l_tmp1[6] = l_tmp1[14] = l_tmp1[18] = l_tmp1[22] = l_tmp1[26] = l_tmp1[30] = p_product[58]; 320 | l_tmp1[3] = l_tmp1[7] = l_tmp1[15] = l_tmp1[19] = l_tmp1[23] = l_tmp1[27] = l_tmp1[31] = p_product[59]; 321 | l_tmp2[8] = p_product[56]; 322 | l_tmp2[9] = p_product[57]; 323 | l_tmp2[10] = p_product[58]; 324 | l_tmp2[11] = p_product[59]; 325 | l_tmp3[0] = l_tmp3[4] = l_tmp3[16] = l_tmp3[28] = p_product[56]; 326 | l_tmp3[1] = l_tmp3[5] = l_tmp3[17] = l_tmp3[29] = p_product[57]; 327 | l_tmp3[2] = l_tmp3[6] = l_tmp3[18] = l_tmp3[30] = p_product[58]; 328 | l_tmp3[3] = l_tmp3[7] = l_tmp3[19] = l_tmp3[31] = p_product[59]; 329 | l_tmp3[12] = l_tmp3[13] = l_tmp3[14] = l_tmp3[15] = 0; 330 | l_carry += vli_add(p_result, p_result, l_tmp1); 331 | l_carry += vli_add(p_result, p_result, l_tmp3); 332 | l_carry -= vli_sub(p_result, p_result, l_tmp2); 333 | 334 | /* Y7 */ 335 | l_tmp1[0] = l_tmp1[4] = l_tmp1[12] = l_tmp1[16] = l_tmp1[20] = l_tmp1[24] = l_tmp1[28] = p_product[60]; 336 | l_tmp1[1] = l_tmp1[5] = l_tmp1[13] = l_tmp1[17] = l_tmp1[21] = l_tmp1[25] = l_tmp1[29] = p_product[61]; 337 | l_tmp1[2] = l_tmp1[6] = l_tmp1[14] = l_tmp1[18] = l_tmp1[22] = l_tmp1[26] = l_tmp1[30] = p_product[62]; 338 | l_tmp1[3] = l_tmp1[7] = l_tmp1[15] = l_tmp1[19] = l_tmp1[23] = l_tmp1[27] = l_tmp1[31] = p_product[63]; 339 | l_tmp3[0] = l_tmp3[4] = l_tmp3[20] = p_product[60]; 340 | l_tmp3[1] = l_tmp3[5] = l_tmp3[21] = p_product[61]; 341 | l_tmp3[2] = l_tmp3[6] = l_tmp3[22] = p_product[62]; 342 | l_tmp3[3] = l_tmp3[7] = l_tmp3[23] = p_product[63]; 343 | l_tmp3[16] = l_tmp3[17] = l_tmp3[18] = l_tmp3[19] = l_tmp3[28] = l_tmp3[29] = l_tmp3[30] = l_tmp3[31] = 0; 344 | l_tmp2[28] = p_product[60]; 345 | l_tmp2[29] = p_product[61]; 346 | l_tmp2[30] = p_product[62]; 347 | l_tmp2[31] = p_product[63]; 348 | l_tmp2[8] = l_tmp2[9] = l_tmp2[10] = l_tmp2[11] = 0; 349 | l_carry += vli_lshift(l_tmp2, l_tmp2, 1); 350 | l_carry += vli_add(p_result, p_result, l_tmp1); 351 | l_carry += vli_add(p_result, p_result, l_tmp3); 352 | l_carry += vli_add(p_result, p_result, l_tmp2); 353 | 354 | if(l_carry < 0) 355 | { 356 | do 357 | { 358 | l_carry += vli_add(p_result, p_result, curve_p); 359 | } while(l_carry < 0); 360 | } 361 | else 362 | { 363 | while(l_carry || vli_cmp(curve_p, p_result) != 1) 364 | { 365 | l_carry -= vli_sub(p_result, p_result, curve_p); 366 | } 367 | } 368 | } 369 | 370 | /* Computes p_result = (p_left * p_right) % curve_p. */ 371 | static void vli_modMult_fast(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) 372 | { 373 | uint8_t l_product[2 * NUM_ECC_DIGITS]; 374 | vli_mult(l_product, p_left, p_right); 375 | vli_mmod_fast(p_result, l_product); 376 | } 377 | 378 | #if ECC_SQUARE_FUNC 379 | 380 | /* Computes p_result = p_left^2. */ 381 | static void vli_square(uint8_t *p_result, uint8_t *p_left) 382 | { 383 | uint16_t r01 = 0; 384 | uint8_t r2 = 0; 385 | 386 | uint i, k; 387 | for(k=0; k < NUM_ECC_DIGITS*2 - 1; ++k) 388 | { 389 | uint l_min = (k < NUM_ECC_DIGITS ? 0 : (k + 1) - NUM_ECC_DIGITS); 390 | for(i=l_min; i<=k && i<=k-i; ++i) 391 | { 392 | uint16_t l_product = (uint16_t)p_left[i] * p_left[k-i]; 393 | if(i < k-i) 394 | { 395 | r2 += l_product >> 15; 396 | l_product *= 2; 397 | } 398 | r01 += l_product; 399 | r2 += (r01 < l_product); 400 | } 401 | p_result[k] = (uint8_t)r01; 402 | r01 = (r01 >> 8) | (((uint16_t)r2) << 8); 403 | r2 = 0; 404 | } 405 | 406 | p_result[NUM_ECC_DIGITS*2 - 1] = (uint8_t)r01; 407 | } 408 | 409 | /* Computes p_result = p_left^2 % curve_p. */ 410 | static void vli_modSquare_fast(uint8_t *p_result, uint8_t *p_left) 411 | { 412 | uint8_t l_product[2 * NUM_ECC_DIGITS]; 413 | vli_square(l_product, p_left); 414 | vli_mmod_fast(p_result, l_product); 415 | } 416 | 417 | #else /* ECC_SQUARE_FUNC */ 418 | 419 | #define vli_square(result, left, size) vli_mult((result), (left), (left), (size)) 420 | #define vli_modSquare_fast(result, left) vli_modMult_fast((result), (left), (left)) 421 | 422 | #endif /* ECC_SQUARE_FUNC */ 423 | 424 | #define EVEN(vli) (!(vli[0] & 1)) 425 | /* Computes p_result = (1 / p_input) % p_mod. All VLIs are the same size. 426 | See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" 427 | https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf */ 428 | static void vli_modInv(uint8_t *p_result, uint8_t *p_input, uint8_t *p_mod) 429 | { 430 | uint8_t a[NUM_ECC_DIGITS], b[NUM_ECC_DIGITS], u[NUM_ECC_DIGITS], v[NUM_ECC_DIGITS]; 431 | uint8_t l_carry; 432 | 433 | vli_set(a, p_input); 434 | vli_set(b, p_mod); 435 | vli_clear(u); 436 | u[0] = 1; 437 | vli_clear(v); 438 | 439 | int l_cmpResult; 440 | while((l_cmpResult = vli_cmp(a, b)) != 0) 441 | { 442 | l_carry = 0; 443 | if(EVEN(a)) 444 | { 445 | vli_rshift1(a); 446 | if(!EVEN(u)) 447 | { 448 | l_carry = vli_add(u, u, p_mod); 449 | } 450 | vli_rshift1(u); 451 | if(l_carry) 452 | { 453 | u[NUM_ECC_DIGITS-1] |= 0x80; 454 | } 455 | } 456 | else if(EVEN(b)) 457 | { 458 | vli_rshift1(b); 459 | if(!EVEN(v)) 460 | { 461 | l_carry = vli_add(v, v, p_mod); 462 | } 463 | vli_rshift1(v); 464 | if(l_carry) 465 | { 466 | v[NUM_ECC_DIGITS-1] |= 0x80; 467 | } 468 | } 469 | else if(l_cmpResult > 0) 470 | { 471 | vli_sub(a, a, b); 472 | vli_rshift1(a); 473 | if(vli_cmp(u, v) < 0) 474 | { 475 | vli_add(u, u, p_mod); 476 | } 477 | vli_sub(u, u, v); 478 | if(!EVEN(u)) 479 | { 480 | l_carry = vli_add(u, u, p_mod); 481 | } 482 | vli_rshift1(u); 483 | if(l_carry) 484 | { 485 | u[NUM_ECC_DIGITS-1] |= 0x80; 486 | } 487 | } 488 | else 489 | { 490 | vli_sub(b, b, a); 491 | vli_rshift1(b); 492 | if(vli_cmp(v, u) < 0) 493 | { 494 | vli_add(v, v, p_mod); 495 | } 496 | vli_sub(v, v, u); 497 | if(!EVEN(v)) 498 | { 499 | l_carry = vli_add(v, v, p_mod); 500 | } 501 | vli_rshift1(v); 502 | if(l_carry) 503 | { 504 | v[NUM_ECC_DIGITS-1] |= 0x80; 505 | } 506 | } 507 | } 508 | 509 | vli_set(p_result, u); 510 | } 511 | 512 | /* ------ Point operations ------ */ 513 | 514 | /* Returns 1 if p_point is the point at infinity, 0 otherwise. */ 515 | static int EccPoint_isZero(EccPoint *p_point) 516 | { 517 | return (vli_isZero(p_point->x) && vli_isZero(p_point->y)); 518 | } 519 | 520 | /* Point multiplication algorithm using Montgomery's ladder with co-Z coordinates. 521 | From http://eprint.iacr.org/2011/338.pdf 522 | */ 523 | 524 | /* Double in place */ 525 | static void EccPoint_double_jacobian(uint8_t *X1, uint8_t *Y1, uint8_t *Z1) 526 | { 527 | /* t1 = X, t2 = Y, t3 = Z */ 528 | uint8_t t4[NUM_ECC_DIGITS]; 529 | uint8_t t5[NUM_ECC_DIGITS]; 530 | 531 | if(vli_isZero(Z1)) 532 | { 533 | return; 534 | } 535 | 536 | vli_modSquare_fast(t4, Y1); /* t4 = y1^2 */ 537 | vli_modMult_fast(t5, X1, t4); /* t5 = x1*y1^2 = A */ 538 | vli_modSquare_fast(t4, t4); /* t4 = y1^4 */ 539 | vli_modMult_fast(Y1, Y1, Z1); /* t2 = y1*z1 = z3 */ 540 | vli_modSquare_fast(Z1, Z1); /* t3 = z1^2 */ 541 | 542 | vli_modAdd(X1, X1, Z1, curve_p); /* t1 = x1 + z1^2 */ 543 | vli_modAdd(Z1, Z1, Z1, curve_p); /* t3 = 2*z1^2 */ 544 | vli_modSub(Z1, X1, Z1, curve_p); /* t3 = x1 - z1^2 */ 545 | vli_modMult_fast(X1, X1, Z1); /* t1 = x1^2 - z1^4 */ 546 | 547 | vli_modAdd(Z1, X1, X1, curve_p); /* t3 = 2*(x1^2 - z1^4) */ 548 | vli_modAdd(X1, X1, Z1, curve_p); /* t1 = 3*(x1^2 - z1^4) */ 549 | if(vli_testBit(X1, 0)) 550 | { 551 | uint8_t l_carry = vli_add(X1, X1, curve_p); 552 | vli_rshift1(X1); 553 | X1[NUM_ECC_DIGITS-1] |= l_carry << 7; 554 | } 555 | else 556 | { 557 | vli_rshift1(X1); 558 | } 559 | /* t1 = 3/2*(x1^2 - z1^4) = B */ 560 | 561 | vli_modSquare_fast(Z1, X1); /* t3 = B^2 */ 562 | vli_modSub(Z1, Z1, t5, curve_p); /* t3 = B^2 - A */ 563 | vli_modSub(Z1, Z1, t5, curve_p); /* t3 = B^2 - 2A = x3 */ 564 | vli_modSub(t5, t5, Z1, curve_p); /* t5 = A - x3 */ 565 | vli_modMult_fast(X1, X1, t5); /* t1 = B * (A - x3) */ 566 | vli_modSub(t4, X1, t4, curve_p); /* t4 = B * (A - x3) - y1^4 = y3 */ 567 | 568 | vli_set(X1, Z1); 569 | vli_set(Z1, Y1); 570 | vli_set(Y1, t4); 571 | } 572 | 573 | /* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */ 574 | static void apply_z(uint8_t *X1, uint8_t *Y1, uint8_t *Z) 575 | { 576 | uint8_t t1[NUM_ECC_DIGITS]; 577 | 578 | vli_modSquare_fast(t1, Z); /* z^2 */ 579 | vli_modMult_fast(X1, X1, t1); /* x1 * z^2 */ 580 | vli_modMult_fast(t1, t1, Z); /* z^3 */ 581 | vli_modMult_fast(Y1, Y1, t1); /* y1 * z^3 */ 582 | } 583 | 584 | /* P = (x1, y1) => 2P, (x2, y2) => P' */ 585 | static void XYcZ_initial_double(uint8_t *X1, uint8_t *Y1, uint8_t *X2, uint8_t *Y2, uint8_t *p_initialZ) 586 | { 587 | uint8_t z[NUM_ECC_DIGITS]; 588 | 589 | vli_set(X2, X1); 590 | vli_set(Y2, Y1); 591 | 592 | vli_clear(z); 593 | z[0] = 1; 594 | if(p_initialZ) 595 | { 596 | vli_set(z, p_initialZ); 597 | } 598 | apply_z(X1, Y1, z); 599 | 600 | EccPoint_double_jacobian(X1, Y1, z); 601 | 602 | apply_z(X2, Y2, z); 603 | } 604 | 605 | /* Input P = (x1, y1, Z), Q = (x2, y2, Z) 606 | Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3) 607 | Output:x2=x3,y2=y3 608 | or P => P', Q => P + Q 609 | */ 610 | static void XYcZ_add(uint8_t *X1, uint8_t *Y1, uint8_t *X2, uint8_t *Y2) 611 | { 612 | /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ 613 | uint8_t t5[NUM_ECC_DIGITS]; 614 | 615 | //X3 = D ? (B + C) ; Y3 = (Y2 ? Y1)(B ? X3) ? E and Z3 = Z(X2 ? X1) 616 | //A = (X2 ? X1)2, B = X1A, C = X2A, D = (Y2 ? Y1)2 and E = Y1(C ? B) 617 | 618 | vli_modSub(t5, X2, X1, curve_p); /* t5 = x2 - x1 */ 619 | vli_modSquare_fast(t5, t5); /* t5 = (x2 - x1)^2 = A */ 620 | vli_modMult_fast(X1, X1, t5); /* X1 = t1 = x1*A = B */ 621 | vli_modMult_fast(X2, X2, t5); /* X2 = t3 = x2*A = C */ 622 | vli_modSub(Y2, Y2, Y1, curve_p); /* Y2 = t4 = y2 - y1 */ 623 | vli_modSquare_fast(t5, Y2); /* t5 = (y2 - y1)^2 = D */ 624 | 625 | //X3 = D ? (B + C) 626 | vli_modSub(t5, t5, X1, curve_p); /* t5 = D - B */ 627 | vli_modSub(t5, t5, X2, curve_p); /* t5 = D - B - C = x3 */ 628 | 629 | vli_modSub(X2, X2, X1, curve_p); /* X2 = t3 = C - B */ 630 | vli_modMult_fast(Y1, Y1, X2); /* Y1 = t2 = y1*(C - B) = E*/ 631 | vli_modSub(X2, X1, t5, curve_p); /* X2 = t3 = B - x3 */ 632 | vli_modMult_fast(Y2, Y2, X2); /* Y2 = t4 = (y2 - y1)*(B - x3) */ 633 | //y2=y3 634 | vli_modSub(Y2, Y2, Y1, curve_p); /* Y2 = t4 = y3 */ 635 | 636 | //x2=t5=x3 637 | vli_set(X2, t5); 638 | } 639 | 640 | /* Input P = (x1, y1, Z), Q = (x2, y2, Z) 641 | Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3) 642 | Output:x1=x3',y1=y3';x2=x3,y2=y3 643 | or P => P - Q, Q => P + Q 644 | */ 645 | static void XYcZ_addC(uint8_t *X1, uint8_t *Y1, uint8_t *X2, uint8_t *Y2) 646 | { 647 | /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ 648 | uint8_t t5[NUM_ECC_DIGITS]; 649 | uint8_t t6[NUM_ECC_DIGITS]; 650 | uint8_t t7[NUM_ECC_DIGITS]; 651 | 652 | //s1 653 | vli_modSub(t5, X2, X1, curve_p); /* t5 = x2 - x1 */ 654 | vli_modSquare_fast(t5, t5); /* t5 = (x2 - x1)^2 = A */ 655 | //s2 656 | vli_modMult_fast(X1, X1, t5); /* X1 = t1 = x1*A = B */ 657 | //s3 658 | vli_modMult_fast(X2, X2, t5); /* X2 = t3 = x2*A = C */ 659 | 660 | //s4 661 | vli_modAdd(t5, Y2, Y1, curve_p); /* t5 = t4 = y2 + y1 */ 662 | vli_modSub(Y2, Y2, Y1, curve_p); /* Y2 = t4 = y2 - y1 */ 663 | 664 | //s5 :E = Y1(C ? B) 665 | vli_modSub(t6, X2, X1, curve_p); /* t6 = C - B */ 666 | vli_modMult_fast(Y1, Y1, t6); /* t2 = y1 * (C - B) */ 667 | //s6 :B + C 668 | vli_modAdd(t6, X1, X2, curve_p); /* t6 = B + C */ 669 | //s4:D=(Y2 ? Y1)^2 670 | vli_modSquare_fast(X2, Y2); /* X2 = t3 = (y2 - y1)^2 */ 671 | //s6:X3=D ? (B + C) 672 | vli_modSub(X2, X2, t6, curve_p); /* X2 = t3 = x3 */ 673 | 674 | //s7:Y3 = (Y2 ? Y1)(B ? X3) ? E 675 | vli_modSub(t7, X1, X2, curve_p); /* t7 = B - x3 */ 676 | vli_modMult_fast(Y2, Y2, t7); /* t4 = (y2 - y1)*(B - x3) */ 677 | vli_modSub(Y2, Y2, Y1, curve_p); /* t4 = y3 */ 678 | 679 | //s4 680 | vli_modSquare_fast(t7, t5); /* t7 = (y2 + y1)^2 = F */ 681 | 682 | //s8:F-(B+C) 683 | vli_modSub(t7, t7, t6, curve_p); /* t7 = x3' */ 684 | 685 | //s9 686 | vli_modSub(t6, t7, X1, curve_p); /* t6 = x3' - B */ 687 | vli_modMult_fast(t6, t6, t5); /* t6 = (y2 + y1)*(x3' - B) */ 688 | vli_modSub(Y1, t6, Y1, curve_p); /* t2 = y3' */ 689 | 690 | vli_set(X1, t7); 691 | } 692 | 693 | static void EccPoint_mult(EccPoint *p_result, EccPoint *p_point, uint8_t *p_scalar, uint8_t *p_initialZ) 694 | { 695 | /* R0 and R1 */ 696 | uint8_t Rx[2][NUM_ECC_DIGITS]; 697 | uint8_t Ry[2][NUM_ECC_DIGITS]; 698 | uint8_t z[NUM_ECC_DIGITS]; 699 | 700 | uint i, nb; 701 | 702 | vli_set(Rx[1], p_point->x); 703 | vli_set(Ry[1], p_point->y); 704 | 705 | XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], p_initialZ); 706 | 707 | for(i = vli_numBits(p_scalar) - 2; i > 0; --i) 708 | { 709 | nb = !vli_testBit(p_scalar, i); 710 | XYcZ_addC(Rx[1-nb], Ry[1-nb], Rx[nb], Ry[nb]); 711 | XYcZ_add(Rx[nb], Ry[nb], Rx[1-nb], Ry[1-nb]); 712 | } 713 | 714 | nb = !vli_testBit(p_scalar, 0); 715 | XYcZ_addC(Rx[1-nb], Ry[1-nb], Rx[nb], Ry[nb]); 716 | 717 | /* Find final 1/Z value. */ 718 | vli_modSub(z, Rx[1], Rx[0], curve_p); /* X1 - X0 */ 719 | vli_modMult_fast(z, z, Ry[1-nb]); /* Yb * (X1 - X0) */ 720 | vli_modMult_fast(z, z, p_point->x); /* xP * Yb * (X1 - X0) */ 721 | vli_modInv(z, z, curve_p); /* 1 / (xP * Yb * (X1 - X0)) */ 722 | vli_modMult_fast(z, z, p_point->y); /* yP / (xP * Yb * (X1 - X0)) */ 723 | vli_modMult_fast(z, z, Rx[1-nb]); /* Xb * yP / (xP * Yb * (X1 - X0)) */ 724 | /* End 1/Z calculation */ 725 | 726 | XYcZ_add(Rx[nb], Ry[nb], Rx[1-nb], Ry[1-nb]); 727 | 728 | apply_z(Rx[0], Ry[0], z); 729 | 730 | vli_set(p_result->x, Rx[0]); 731 | vli_set(p_result->y, Ry[0]); 732 | } 733 | 734 | int ecc_make_key(EccPoint *p_publicKey, uint8_t p_privateKey[NUM_ECC_DIGITS], uint8_t p_random[NUM_ECC_DIGITS]) 735 | { 736 | /* Make sure the private key is in the range [1, n-1]. 737 | For the supported curves, n is always large enough that we only need to subtract once at most. */ 738 | vli_set(p_privateKey, p_random); 739 | if(vli_cmp(curve_n, p_privateKey) != 1) 740 | { 741 | vli_sub(p_privateKey, p_privateKey, curve_n); 742 | } 743 | 744 | if(vli_isZero(p_privateKey)) 745 | { 746 | return 0; /* The private key cannot be 0 (mod p). */ 747 | } 748 | 749 | EccPoint_mult(p_publicKey, &curve_G, p_privateKey, NULL); 750 | return 1; 751 | } 752 | 753 | int ecc_valid_public_key(EccPoint *p_publicKey) 754 | { 755 | uint8_t na[NUM_ECC_DIGITS] = {3}; /* a mod p = (-3) mod p */ 756 | 757 | uint8_t l_tmp1[NUM_ECC_DIGITS]; 758 | uint8_t l_tmp2[NUM_ECC_DIGITS]; 759 | 760 | if(EccPoint_isZero(p_publicKey)) 761 | { 762 | return 0; 763 | } 764 | 765 | if(vli_cmp(curve_p, p_publicKey->x) != 1 || vli_cmp(curve_p, p_publicKey->y) != 1) 766 | { 767 | return 0; 768 | } 769 | 770 | vli_modSquare_fast(l_tmp1, p_publicKey->y); /* tmp1 = y^2 */ 771 | vli_modSquare_fast(l_tmp2, p_publicKey->x); /* tmp2 = x^2 */ 772 | vli_modSub(l_tmp2, l_tmp2, na, curve_p); /* tmp2 = x^2 + a = x^2 - 3 */ 773 | vli_modMult_fast(l_tmp2, l_tmp2, p_publicKey->x); /* tmp2 = x^3 + ax */ 774 | vli_modAdd(l_tmp2, l_tmp2, curve_b, curve_p); /* tmp2 = x^3 + ax + b */ 775 | 776 | /* Make sure that y^2 == x^3 + ax + b */ 777 | if(vli_cmp(l_tmp1, l_tmp2) != 0) 778 | { 779 | return 0; 780 | } 781 | 782 | return 1; 783 | } 784 | 785 | int ecdh_shared_secret(uint8_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey, uint8_t p_privateKey[NUM_ECC_DIGITS], uint8_t p_random[NUM_ECC_DIGITS]) 786 | { 787 | EccPoint l_product; 788 | 789 | EccPoint_mult(&l_product, p_publicKey, p_privateKey, p_random); 790 | if(EccPoint_isZero(&l_product)) 791 | { 792 | return 0; 793 | } 794 | 795 | vli_set(p_secret, l_product.x); 796 | 797 | return 1; 798 | } 799 | 800 | #if SM2_ECDSA 801 | 802 | extern int sm2_get_z(unsigned char *IDa, int IDLen, unsigned char *xa, unsigned char *ya, unsigned char *Za); 803 | extern void sm3(unsigned char *input, int ilen, unsigned char output[32]); 804 | 805 | int sm2_get_e(char *IDa, int IDLen, unsigned char *xa, unsigned char *ya, unsigned char *plaintext, unsigned int plainLen, unsigned char *e) 806 | { 807 | #define SM3_OUTSIZE 32 808 | 809 | unsigned char Za[64]; 810 | unsigned char *M; 811 | 812 | sm2_get_z((unsigned char *)IDa, strlen(IDa), xa, ya, Za); 813 | M = (unsigned char *)malloc(plainLen + SM3_OUTSIZE); 814 | memset(M, 0, plainLen + SM3_OUTSIZE); 815 | memcpy(M, Za, SM3_OUTSIZE); 816 | memcpy(M + SM3_OUTSIZE, plaintext, plainLen); 817 | sm3(M, SM3_OUTSIZE + plainLen, e); 818 | 819 | #if 0 820 | int i = 0; 821 | printf("HASH:"); 822 | for (i = 0; i < 32; i++){ 823 | printf("%02X ",e[i]); 824 | } 825 | printf("\n"); 826 | #endif 827 | 828 | free(M); 829 | return 1; 830 | } 831 | 832 | /* ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA)ã€?*/ 833 | int sm2_get_z(unsigned char *IDa, int IDLen, unsigned char *xa, unsigned char *ya, unsigned char *Za) 834 | { 835 | 836 | unsigned char Z[256]; 837 | unsigned char *p = Z; 838 | unsigned int len = 0; 839 | 840 | unsigned char a[] = { 841 | 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 842 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 843 | 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 844 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC 845 | }; 846 | 847 | unsigned char b[] = { 848 | 0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34, 849 | 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7, 850 | 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92, 851 | 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93 852 | }; 853 | 854 | unsigned char xG[] = { 855 | 0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19, 856 | 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94, 857 | 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1, 858 | 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7 859 | }; 860 | 861 | unsigned char yG[] = { 862 | 0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C, 863 | 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53, 864 | 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40, 865 | 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0 866 | }; 867 | 868 | unsigned short idBitLen = IDLen * 8; 869 | 870 | if (IDLen > 32) 871 | return -1; 872 | 873 | *p = (idBitLen >> 8) & 0xff; 874 | *(p + 1) = idBitLen & 0xff; 875 | p += sizeof(idBitLen); 876 | len += sizeof(idBitLen); 877 | 878 | memcpy(p, IDa, IDLen); 879 | p += IDLen; 880 | len += IDLen; 881 | 882 | memcpy(p, a, sizeof(a)); 883 | p += sizeof(a); 884 | len += sizeof(a); 885 | 886 | memcpy(p, b, sizeof(b)); 887 | p += sizeof(b); 888 | len += sizeof(b); 889 | 890 | memcpy(p, xG, sizeof(xG)); 891 | p += sizeof(xG); 892 | len += sizeof(xG); 893 | 894 | memcpy(p, yG, sizeof(yG)); 895 | p += sizeof(yG); 896 | len += sizeof(yG); 897 | 898 | memcpy(p, xa, 32); 899 | p += 32; 900 | len += 32; 901 | 902 | memcpy(p, ya, 32); 903 | //p += 32; 904 | len += 32; 905 | 906 | //len = (unsigned int)p - (unsigned int)Z; 907 | sm3(Z, len, Za); 908 | 909 | return 0; 910 | } 911 | 912 | /* -------- ECDSA code -------- */ 913 | 914 | /* Computes p_result = (p_left * p_right) % p_mod. */ 915 | static void vli_modMult(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right, uint8_t *p_mod) 916 | { 917 | uint8_t l_product[2 * NUM_ECC_DIGITS]; 918 | uint8_t l_modMultiple[2 * NUM_ECC_DIGITS]; 919 | uint l_digitShift, l_bitShift; 920 | uint l_productBits; 921 | uint l_modBits = vli_numBits(p_mod); 922 | 923 | vli_mult(l_product, p_left, p_right); 924 | l_productBits = vli_numBits(l_product + NUM_ECC_DIGITS); 925 | if(l_productBits) 926 | { 927 | l_productBits += NUM_ECC_DIGITS * 8; 928 | } 929 | else 930 | { 931 | l_productBits = vli_numBits(l_product); 932 | } 933 | 934 | if(l_productBits < l_modBits) 935 | { /* l_product < p_mod. */ 936 | vli_set(p_result, l_product); 937 | return; 938 | } 939 | 940 | /* Shift p_mod by (l_leftBits - l_modBits). This multiplies p_mod by the largest 941 | power of two possible while still resulting in a number less than p_left. */ 942 | vli_clear(l_modMultiple); 943 | vli_clear(l_modMultiple + NUM_ECC_DIGITS); 944 | l_digitShift = (l_productBits - l_modBits) / 8; 945 | l_bitShift = (l_productBits - l_modBits) % 8; 946 | if(l_bitShift) 947 | { 948 | l_modMultiple[l_digitShift + NUM_ECC_DIGITS] = vli_lshift(l_modMultiple + l_digitShift, p_mod, l_bitShift); 949 | } 950 | else 951 | { 952 | vli_set(l_modMultiple + l_digitShift, p_mod); 953 | } 954 | 955 | /* Subtract all multiples of p_mod to get the remainder. */ 956 | vli_clear(p_result); 957 | p_result[0] = 1; /* Use p_result as a temp var to store 1 (for subtraction) */ 958 | while(l_productBits > NUM_ECC_DIGITS * 8 || vli_cmp(l_modMultiple, p_mod) >= 0) 959 | { 960 | int l_cmp = vli_cmp(l_modMultiple + NUM_ECC_DIGITS, l_product + NUM_ECC_DIGITS); 961 | if(l_cmp < 0 || (l_cmp == 0 && vli_cmp(l_modMultiple, l_product) <= 0)) 962 | { 963 | if(vli_sub(l_product, l_product, l_modMultiple)) 964 | { /* borrow */ 965 | vli_sub(l_product + NUM_ECC_DIGITS, l_product + NUM_ECC_DIGITS, p_result); 966 | } 967 | vli_sub(l_product + NUM_ECC_DIGITS, l_product + NUM_ECC_DIGITS, l_modMultiple + NUM_ECC_DIGITS); 968 | } 969 | uint8_t l_carry = (l_modMultiple[NUM_ECC_DIGITS] & 0x01) << 7; 970 | vli_rshift1(l_modMultiple + NUM_ECC_DIGITS); 971 | vli_rshift1(l_modMultiple); 972 | l_modMultiple[NUM_ECC_DIGITS-1] |= l_carry; 973 | 974 | --l_productBits; 975 | } 976 | vli_set(p_result, l_product); 977 | } 978 | 979 | static uint max(uint a, uint b) 980 | { 981 | return (a > b ? a : b); 982 | } 983 | 984 | //************ DSA Sign with SM2 ************// 985 | int ecdsa_sign(uint8_t r[NUM_ECC_DIGITS], uint8_t s[NUM_ECC_DIGITS], uint8_t p_privateKey[NUM_ECC_DIGITS], 986 | uint8_t p_random[NUM_ECC_DIGITS], uint8_t p_hash[NUM_ECC_DIGITS]) 987 | { 988 | uint8_t k[NUM_ECC_DIGITS]; 989 | EccPoint p; 990 | 991 | if(vli_isZero(p_random)) 992 | { /* The random number must not be 0. */ 993 | return 0; 994 | } 995 | 996 | vli_set(k, p_random); 997 | if(vli_cmp(curve_n, k) != 1) 998 | { 999 | vli_sub(k, k, curve_n); 1000 | } 1001 | 1002 | /* tmp = k * G */ 1003 | EccPoint_mult(&p, &curve_G, k, NULL); 1004 | 1005 | /* r = x1 + e (mod n) */ 1006 | vli_set(r, p.x); 1007 | vli_modAdd(r, r, p_hash, curve_n); 1008 | if(vli_cmp(curve_n, r) != 1) 1009 | { 1010 | vli_sub(r, r, curve_n); 1011 | } 1012 | if(vli_isZero(r)) 1013 | { /* If r == 0, fail (need a different random number). */ 1014 | return 0; 1015 | } 1016 | 1017 | vli_modMult(s, r, p_privateKey, curve_n); /* s = r*d */ 1018 | vli_modSub(s, k, s, curve_n); /* k-r*d */ 1019 | uint8_t one[NUM_ECC_DIGITS] = {1}; 1020 | vli_modAdd(p_privateKey, p_privateKey, one, curve_n); /* 1+d */ 1021 | vli_modInv(p_privateKey, p_privateKey, curve_n); /* (1+d)' */ 1022 | vli_modMult(s, p_privateKey, s, curve_n); /* (1+d)'*(k-r*d) */ 1023 | 1024 | return 1; 1025 | } 1026 | 1027 | /************ DSA Verify with SM2 ************/ 1028 | int ecdsa_verify(EccPoint *p_publicKey, uint8_t p_hash[NUM_ECC_DIGITS], uint8_t r[NUM_ECC_DIGITS], uint8_t s[NUM_ECC_DIGITS]) 1029 | { 1030 | uint8_t z[NUM_ECC_DIGITS]; 1031 | EccPoint l_sum; 1032 | uint8_t rx[NUM_ECC_DIGITS]; 1033 | uint8_t ry[NUM_ECC_DIGITS]; 1034 | uint8_t tx[NUM_ECC_DIGITS]; 1035 | uint8_t ty[NUM_ECC_DIGITS]; 1036 | uint8_t tz[NUM_ECC_DIGITS]; 1037 | 1038 | if(vli_isZero(r) || vli_isZero(s)) 1039 | { /* r, s must not be 0. */ 1040 | return 0; 1041 | } 1042 | 1043 | if(vli_cmp(curve_n, r) != 1 || vli_cmp(curve_n, s) != 1) 1044 | { /* r, s must be < n. */ 1045 | return 0; 1046 | } 1047 | 1048 | uint8_t t[NUM_ECC_DIGITS]; 1049 | vli_modAdd(t, r, s, curve_n); // r + s 1050 | if (t == 0) return 0; 1051 | 1052 | //sG + tPa 1053 | /* Calculate l_sum = G + Q. */ 1054 | vli_set(l_sum.x, p_publicKey->x); 1055 | vli_set(l_sum.y, p_publicKey->y); 1056 | vli_set(tx, curve_G.x); 1057 | vli_set(ty, curve_G.y); 1058 | vli_modSub(z, l_sum.x, tx, curve_p); /* Z = x2 - x1 */ 1059 | XYcZ_add(tx, ty, l_sum.x, l_sum.y); 1060 | vli_modInv(z, z, curve_p); /* Z = 1/Z */ 1061 | apply_z(l_sum.x, l_sum.y, z);//l_sum.x/Z^2, l_sum.y/Z^3 1062 | 1063 | /* Use Shamir's trick to calculate u1*G + u2*Q */ 1064 | EccPoint *l_points[4] = {NULL, &curve_G, p_publicKey, &l_sum}; 1065 | uint l_numBits = max(vli_numBits(s), vli_numBits(t)); 1066 | 1067 | EccPoint *l_point = l_points[(!!vli_testBit(s, l_numBits-1)) | ((!!vli_testBit(t, l_numBits-1)) << 1)]; 1068 | vli_set(rx, l_point->x); 1069 | vli_set(ry, l_point->y); 1070 | vli_clear(z); 1071 | z[0] = 1; 1072 | 1073 | int i; 1074 | for(i = l_numBits - 2; i >= 0; --i) 1075 | { 1076 | EccPoint_double_jacobian(rx, ry, z); 1077 | 1078 | int l_index = (!!vli_testBit(s, i)) | ((!!vli_testBit(t, i)) << 1); 1079 | EccPoint *l_point = l_points[l_index]; 1080 | if(l_point) 1081 | { 1082 | vli_set(tx, l_point->x); 1083 | vli_set(ty, l_point->y); 1084 | apply_z(tx, ty, z); 1085 | vli_modSub(tz, rx, tx, curve_p); /* Z = x2 - x1 */ 1086 | XYcZ_add(tx, ty, rx, ry); 1087 | vli_modMult_fast(z, z, tz); 1088 | } 1089 | } 1090 | 1091 | vli_modInv(z, z, curve_p); /* Z = 1/Z */ 1092 | apply_z(rx, ry, z); 1093 | 1094 | /* v = x1 + e (mod n) */ 1095 | vli_modAdd(rx, rx, p_hash, curve_n); 1096 | 1097 | if(vli_cmp(curve_n, rx) != 1) 1098 | { 1099 | vli_sub(rx, rx, curve_n); 1100 | } 1101 | 1102 | /* Accept only if v == r. */ 1103 | return (vli_cmp(rx, r) == 0); 1104 | } 1105 | 1106 | int sm2_sign(EccSig *sig, uint8_t *msg, unsigned int msg_len, uint8_t *IDa, uint8_t IDa_len, uint8_t p_privateKey[NUM_ECC_DIGITS], uint8_t p_random[NUM_ECC_DIGITS]) 1107 | { 1108 | int i = 0; 1109 | int ret = 0; 1110 | uint8_t tmp = 0; 1111 | uint8_t br[NUM_ECC_DIGITS];//r 1112 | uint8_t bs[NUM_ECC_DIGITS];//s 1113 | uint8_t p_pvk[NUM_ECC_DIGITS];//p_pvk 1114 | uint8_t p_rnd[NUM_ECC_DIGITS];//p_rand 1115 | uint8_t e_hash[NUM_ECC_DIGITS]; 1116 | EccPoint p_publicKey, p_pubk; 1117 | 1118 | for (i=0; ir[i] = br[NUM_ECC_DIGITS - 1 -i]; 1196 | sig->s[i] = bs[NUM_ECC_DIGITS - 1 -i]; 1197 | } 1198 | 1199 | return 1; 1200 | } 1201 | 1202 | int sm2_verify(EccSig *sig, uint8_t *msg, unsigned int msg_len, uint8_t *IDa, uint8_t IDa_len, EccPoint *p_pubk) 1203 | { 1204 | int i = 0; 1205 | uint8_t br[NUM_ECC_DIGITS];//r 1206 | uint8_t bs[NUM_ECC_DIGITS];//s 1207 | uint8_t p_pvk[NUM_ECC_DIGITS];//p_pvk 1208 | uint8_t p_rnd[NUM_ECC_DIGITS];//p_rand 1209 | uint8_t e_hash[NUM_ECC_DIGITS]; 1210 | uint8_t p_hash[NUM_ECC_DIGITS]; 1211 | 1212 | EccPoint p_publicKey; 1213 | 1214 | //Õý³£¼ÆËãeÖµ 1215 | sm2_get_e(IDa, IDa_len, p_pubk->x, p_pubk->y, msg, msg_len, e_hash); 1216 | 1217 | for (i=0; ir[NUM_ECC_DIGITS - 1 - i]; 1220 | bs[i] = sig->s[NUM_ECC_DIGITS - 1 - i]; 1221 | p_publicKey.x[i] = p_pubk->x[NUM_ECC_DIGITS - 1 - i]; 1222 | p_publicKey.y[i] = p_pubk->y[NUM_ECC_DIGITS - 1 - i]; 1223 | p_hash[i] = e_hash[NUM_ECC_DIGITS - 1 - i]; 1224 | } 1225 | #ifdef __SM2_DEBUG__ 1226 | printf("\nbr:"); 1227 | for (i = 0; ix[NUM_ECC_DIGITS - i - 1]; 1333 | Pb.y[i] = p_publicKey->y[NUM_ECC_DIGITS - i - 1]; 1334 | } 1335 | if(EccPoint_isZero(&Pb)) 1336 | { 1337 | printf("S at infinity...\n"); 1338 | return 0; 1339 | } 1340 | 1341 | //A4:[k]Pb = (x2, y2); 1342 | EccPoint_mult(&point2, &Pb, k, NULL); 1343 | for (i=0; i < NUM_ECC_DIGITS; i++) 1344 | { 1345 | point2_revert.x[i] = point2.x[NUM_ECC_DIGITS - i - 1]; 1346 | point2_revert.y[i] = point2.y[NUM_ECC_DIGITS - i - 1]; 1347 | } 1348 | 1349 | //A5: t =KDF(x2||y2, klen) 1350 | memcpy(x2y2, point2_revert.x, NUM_ECC_DIGITS); 1351 | memcpy(x2y2 + NUM_ECC_DIGITS, point2_revert.y, NUM_ECC_DIGITS); 1352 | 1353 | x9_63_kdf_sm3(x2y2, NUM_ECC_DIGITS * 2, C2, plain_len); 1354 | if(vli_isZero(C2)) 1355 | { /* If r == 0, fail (need a different random number). */ 1356 | return 0; 1357 | } 1358 | 1359 | //A6: C2 = M^t; 1360 | for (i = 0; i < plain_len; i++) 1361 | { 1362 | C2[i] ^= plain_text[i]; 1363 | } 1364 | 1365 | //A7:C3 = Hash(x2, M, y2); 1366 | sm3_starts(&sm3_ctx); 1367 | sm3_update(&sm3_ctx, point2_revert.x, NUM_ECC_DIGITS); 1368 | sm3_update(&sm3_ctx, plain_text, plain_len); 1369 | sm3_update(&sm3_ctx, point2_revert.y, NUM_ECC_DIGITS); 1370 | sm3_finish(&sm3_ctx, C3); 1371 | 1372 | //A8:C=C1||C3||C2 1373 | cipher_text[0] = PC; 1374 | *cipher_len = 1; 1375 | memcpy(cipher_text + *cipher_len, C1.x, NUM_ECC_DIGITS * 2); 1376 | *cipher_len += NUM_ECC_DIGITS * 2; 1377 | memcpy(cipher_text + *cipher_len, C3, NUM_ECC_DIGITS); 1378 | *cipher_len += NUM_ECC_DIGITS; 1379 | memcpy(cipher_text + *cipher_len, C2, plain_len); 1380 | *cipher_len += plain_len; 1381 | 1382 | return 1; 1383 | } 1384 | 1385 | int sm2_decrypt(uint8_t *plain_text, uint8_t *plain_len, uint8_t *cipher_text, uint8_t cipher_len, uint8_t p_privateKey[NUM_ECC_DIGITS]) 1386 | { 1387 | int i = 0; 1388 | int ret = 0; 1389 | sm3_context sm3_ctx; 1390 | EccPoint point2; 1391 | EccPoint point2_revrt; 1392 | uint8_t mac[NUM_ECC_DIGITS]; 1393 | uint8_t x2y2[NUM_ECC_DIGITS * 2]; 1394 | EccPoint C1; 1395 | EccPoint S; 1396 | uint8_t p_pvk[NUM_ECC_DIGITS]; 1397 | 1398 | EccPoint *p_C1; 1399 | uint8_t *p_C3; 1400 | uint8_t *p_C2; 1401 | int C2_len = 0; 1402 | 1403 | p_C1 = (EccPoint *)(cipher_text + 1); 1404 | p_C3 = cipher_text + NUM_ECC_DIGITS*2 + 1; 1405 | p_C2 = cipher_text + NUM_ECC_DIGITS*3 + 1; 1406 | C2_len = cipher_len - NUM_ECC_DIGITS*3 - 1; 1407 | 1408 | if (*plain_len < C2_len) 1409 | { 1410 | printf("plaintext buffer len error\n"); 1411 | return 0; 1412 | } 1413 | 1414 | for (i = 0; i < NUM_ECC_DIGITS; i++) 1415 | { 1416 | C1.x[i] = p_C1->x[NUM_ECC_DIGITS - i - 1]; 1417 | C1.y[i] = p_C1->y[NUM_ECC_DIGITS - i - 1]; 1418 | p_pvk[i] = p_privateKey[NUM_ECC_DIGITS - i - 1]; 1419 | } 1420 | 1421 | ret = EccPoint_is_on_curve(C1); 1422 | if (1 != ret) 1423 | { 1424 | printf("C1 error\n"); 1425 | return 0; 1426 | } 1427 | 1428 | //B2:h=1;S=[h]C1; 1429 | if(EccPoint_isZero(&C1)) 1430 | { 1431 | printf("S at infinity...\n"); 1432 | return 0; 1433 | } 1434 | 1435 | #ifdef __SM2_DEBUG__ 1436 | printf("p_privateKey:"); 1437 | for (i = 0; iC1.x:"); 1443 | for (i = 0; iC1.y:"); 1449 | for (i = 0; iM:"); 1524 | for (i = 0; i < NUM_ECC_DIGITS; i++) 1525 | { 1526 | printf("%02X", p_C3[i]); 1527 | } 1528 | printf("\n"); 1529 | #endif 1530 | 1531 | if (0 != memcmp(p_C3, mac, NUM_ECC_DIGITS)) 1532 | { 1533 | printf("hash error\n"); 1534 | return 0; 1535 | } 1536 | 1537 | return 1; 1538 | } 1539 | 1540 | 1541 | 1542 | 1543 | #endif /* SM2_ECDSA */ 1544 | 1545 | void ecc_bytes2native(uint8_t p_native[NUM_ECC_DIGITS], uint8_t p_bytes[NUM_ECC_DIGITS*4]) 1546 | { 1547 | unsigned i; 1548 | for(i=0; i