• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the License); you may
5  *  not use this file except in compliance with the License.
6  *
7  *  http://www.apache.org/licenses/LICENSE-2.0
8  */
9 
10 
11 
12 #ifndef GMSSL_SM2_H
13 #define GMSSL_SM2_H
14 
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <stdlib.h>
18 #include <gmssl/sm3.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 
25 /*
26 SM2 Public API
27 
28 	SM2_DEFAULT_ID
29 	SM2_MAX_ID_LENGTH
30 	SM2_MAX_SIGNATURE_SIZE
31 	SM2_MAX_PLAINTEXT_SIZE
32 	SM2_MAX_CIPHERTEXT_SIZE
33 
34 	SM2_KEY
35 	sm2_key_generate
36 	sm2_private_key_info_encrypt_to_der
37 	sm2_private_key_info_decrypt_from_der
38 	sm2_private_key_info_encrypt_to_pem
39 	sm2_private_key_info_decrypt_from_pem
40 	sm2_public_key_info_to_der
41 	sm2_public_key_info_from_der
42 	sm2_public_key_info_to_pem
43 	sm2_public_key_info_from_pem
44 
45 	sm2_sign
46 	sm2_verify
47 	sm2_encrypt
48 	sm2_decrypt
49 	sm2_ecdh
50 
51 	SM2_SIGN_CTX
52 	sm2_sign_init
53 	sm2_sign_update
54 	sm2_sign_finish
55 	sm2_verify_init
56 	sm2_verify_update
57 	sm2_verify_finish
58 */
59 
60 typedef uint64_t SM2_BN[8];
61 
62 int sm2_bn_is_zero(const SM2_BN a);
63 int sm2_bn_is_one(const SM2_BN a);
64 int sm2_bn_is_odd(const SM2_BN a);
65 int sm2_bn_cmp(const SM2_BN a, const SM2_BN b);
66 int sm2_bn_from_hex(SM2_BN r, const char hex[64]);
67 int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen);
68 int sm2_bn_equ_hex(const SM2_BN a, const char *hex);
69 int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a);
70 
71 void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]);
72 void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]);
73 void sm2_bn_to_hex(const SM2_BN a, char hex[64]);
74 void sm2_bn_to_bits(const SM2_BN a, char bits[256]);
75 void sm2_bn_set_word(SM2_BN r, uint32_t a);
76 void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b);
77 void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b);
78 void sm2_bn_rand_range(SM2_BN r, const SM2_BN range); // 这个函数需要修改一下,从外部引入随机数
79 
80 #define sm2_bn_init(r) memset((r),0,sizeof(SM2_BN))
81 #define sm2_bn_set_zero(r) memset((r),0,sizeof(SM2_BN))
82 #define sm2_bn_set_one(r) sm2_bn_set_word((r),1)
83 #define sm2_bn_copy(r,a) memcpy((r),(a),sizeof(SM2_BN))
84 #define sm2_bn_clean(r) memset((r),0,sizeof(SM2_BN))
85 
86 
87 // GF(p)
88 typedef SM2_BN SM2_Fp;
89 
90 void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
91 void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
92 void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
93 void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e);
94 void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a);
95 void sm2_fp_tri(SM2_Fp r, const SM2_Fp a);
96 void sm2_fp_div2(SM2_Fp r, const SM2_Fp a);
97 void sm2_fp_neg(SM2_Fp r, const SM2_Fp a);
98 void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a);
99 void sm2_fp_inv(SM2_Fp r, const SM2_Fp a);
100 void sm2_fp_rand(SM2_Fp r); // 外部提供随机性,如果满足条件就输出,如果不满足条件就哈希一下再输出
101 
102 #define sm2_fp_init(r)		sm2_bn_init(r)
103 #define sm2_fp_set_zero(r)	sm2_bn_set_zero(r)
104 #define sm2_fp_set_one(r)	sm2_bn_set_one(r)
105 #define sm2_fp_copy(r,a)	sm2_bn_copy(r,a)
106 #define sm2_fp_clean(r)		sm2_bn_clean(r)
107 
108 // GF(n)
109 typedef SM2_BN SM2_Fn;
110 
111 void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
112 void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
113 void sm2_fn_mul(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
114 void sm2_fn_exp(SM2_Fn r, const SM2_Fn a, const SM2_Fn e);
115 void sm2_fn_neg(SM2_Fn r, const SM2_Fn a);
116 void sm2_fn_sqr(SM2_Fn r, const SM2_Fn a);
117 void sm2_fn_inv(SM2_Fn r, const SM2_Fn a);
118 void sm2_fn_rand(SM2_Fn r);
119 
120 #define sm2_fn_init(r)		sm2_bn_init(r)
121 #define sm2_fn_set_zero(r)	sm2_bn_set_zero(r)
122 #define sm2_fn_set_one(r)	sm2_bn_set_one(r)
123 #define sm2_fn_copy(r,a)	sm2_bn_copy(r,a)
124 #define sm2_fn_clean(r)		sm2_bn_clean(r)
125 
126 
127 typedef struct {
128 	SM2_BN X;
129 	SM2_BN Y;
130 	SM2_BN Z;
131 } SM2_JACOBIAN_POINT;
132 
133 void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R);
134 void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y); // 应该返回错误
135 void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y);
136 void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P);
137 void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P);
138 void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q);
139 void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q);
140 void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P);
141 void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]);
142 void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]);
143 void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k);
144 void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s); // 应该返回错误
145 void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]); // 应该返回错误
146 
147 int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P);
148 int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P);
149 int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]);
150 int sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P);
151 
152 #define sm2_jacobian_point_set_infinity(R) sm2_jacobian_point_init(R)
153 #define sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(SM2_JACOBIAN_POINT))
154 
155 
156 
157 /*
158 SM2 Public API
159 
160 SM2接口有两个层次,基本的和ASN.1/PKI161 基本的接口不依赖ASN.1编码,可以直接将结构体的内存输出(endian一致即可)
162 基本的接口也不进行输入的格式检查,调用方应保证输入不为空
163 */
164 
165 
166 // 这里应该用#define 给出常量的值
167 extern const SM2_BN SM2_P;
168 //extern const SM2_BN SM2_A;
169 extern const SM2_BN SM2_B;
170 extern const SM2_BN SM2_N;
171 extern const SM2_BN SM2_ONE;
172 extern const SM2_BN SM2_TWO;
173 extern const SM2_BN SM2_THREE;
174 extern const SM2_BN SM2_U_PLUS_ONE;
175 extern const SM2_JACOBIAN_POINT *SM2_G; // 应该同时给出Affine的
176 
177 
178 typedef struct {
179 	uint8_t x[32];
180 	uint8_t y[32];
181 } SM2_POINT;
182 
183 void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]);
184 void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]);
185 int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen);
186 
187 
188 int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y);
189 int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]);
190 int sm2_point_is_on_curve(const SM2_POINT *P);
191 int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P);
192 int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]);
193 int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); // R = k * P + s * G
194 
195 /*
196 RFC 5480 Elliptic Curve Cryptography Subject Public Key Information
197 ECPoint ::= OCTET STRING
198 */
199 #define SM2_POINT_MAX_SIZE (2 + 65)
200 int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen);
201 int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen);
202 int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P);
203 
204 
205 typedef struct {
206 	SM2_POINT public_key;
207 	uint8_t private_key[32];
208 } SM2_KEY;
209 
210 
211 int sm2_key_generate(SM2_KEY *key);
212 int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); // 自动生成公钥
213 int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // 自动清空私钥,不要和set_private_key同时用
214 int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key);
215 
216 int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key);
217 //int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // 这个函数的逻辑不清楚
218 int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]);
219 int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key); // 和private_key_print参数不一致
220 
221 /*
222 from RFC 5915
223 
224 ECPrivateKey ::= SEQUENCE {
225 	version		INTEGER,	-- value MUST be (1)
226 	privateKey	OCTET STRING,	-- big endian encoding of integer 这里不是以INTEGER编码的,因此长度固定
227 	parameters	[0] EXPLICIT ECParameters OPTIONAL,
228 					-- ONLY namedCurve OID is permitted, by RFC 5480
229 					-- MUST always include this field, by RFC 5915
230 	publicKey	[1] EXPLICIT BIT STRING OPTIONAL -- compressed_point
231 					-- SHOULD always include this field, by RFC 5915 }
232 
233 ECParameters ::= CHOICE { namedCurve OBJECT IDENTIFIER }
234 */
235 #define SM2_PRIVATE_KEY_DEFAULT_SIZE 120 // generated
236 #define SM2_PRIVATE_KEY_BUF_SIZE 512 // MUST >= SM2_PRIVATE_KEY_DEFAULT_SIZE
237 
238 int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen);
239 int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen);
240 int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
241 //int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp);
242 //int sm2_private_key_from_pem(SM2_KEY *key, FILE *fp);
243 
244 /*
245 AlgorithmIdentifier ::= {
246 	algorithm	OBJECT IDENTIFIER { id-ecPublicKey },
247 	parameters	OBJECT IDENTIFIER { id-sm2 } }
248 */
249 int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen);
250 int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen);
251 
252 /*
253 X.509 SubjectPublicKeyInfo from RFC 5280
254 
255 SubjectPublicKeyInfo  ::=  SEQUENCE  {
256 	algorithm            AlgorithmIdentifier,
257 	subjectPublicKey     BIT STRING  -- uncompressed octets of ECPoint }
258 */
259 int sm2_public_key_info_to_der(const SM2_KEY *a, uint8_t **out, size_t *outlen);
260 int sm2_public_key_info_from_der(SM2_KEY *a, const uint8_t **in, size_t *inlen);
261 int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp);
262 int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp);
263 
264 /*
265 PKCS #8 PrivateKeyInfo from RFC 5208
266 
267 PrivateKeyInfo ::= SEQUENCE {
268 	version			Version { v1(0) },
269 	privateKeyAlgorithm	AlgorithmIdentifier,
270 	privateKey		OCTET STRING, -- DER-encoding of ECPrivateKey
271 	attributes		[0] IMPLICIT SET OF Attribute OPTIONAL }
272 */
273 enum {
274 	PKCS8_private_key_info_version = 0,
275 };
276 
277 int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen);
278 int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen);
279 int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
280 //int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp);
281 //int sm2_private_key_info_from_pem(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, FILE *fp);
282 
283 /*
284 EncryptedPrivateKeyInfo ::= SEQUENCE {
285 	encryptionAlgorithm	EncryptionAlgorithmIdentifier, -- id-PBES2
286 	encryptedData		OCTET STRING }
287 */
288 int sm2_private_key_info_encrypt_to_der(const SM2_KEY *key,
289 	const char *pass, uint8_t **out, size_t *outlen);
290 int sm2_private_key_info_decrypt_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrs_len,
291 	const char *pass, const uint8_t **in, size_t *inlen);
292 int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *key, const char *pass, FILE *fp);
293 int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp);
294 
295 
296 typedef struct {
297 	uint8_t r[32];
298 	uint8_t s[32];
299 } SM2_SIGNATURE;
300 
301 int sm2_do_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], SM2_SIGNATURE *sig);
302 int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig);
303 int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig);
304 
305 #define SM2_MIN_SIGNATURE_SIZE 8
306 #define SM2_MAX_SIGNATURE_SIZE 72
307 int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen);
308 int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen);
309 int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
310 int sm2_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
311 int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
312 int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen);
313 
314 
315 #define SM2_DEFAULT_ID		"1234567812345678"
316 #define SM2_DEFAULT_ID_LENGTH	(sizeof(SM2_DEFAULT_ID) - 1)  // LENGTH for string and SIZE for bytes
317 #define SM2_DEFAULT_ID_BITS	(SM2_DEFAULT_ID_LENGTH * 8)
318 #define SM2_MAX_ID_BITS		65535
319 #define SM2_MAX_ID_LENGTH	(SM2_MAX_ID_BITS/8)
320 
321 int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen);
322 
323 
324 typedef struct {
325 	SM3_CTX sm3_ctx;
326 	SM2_KEY key;
327 } SM2_SIGN_CTX;
328 
329 int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
330 int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
331 int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen);
332 
333 int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
334 int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
335 int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen);
336 
337 /*
338 SM2Cipher ::= SEQUENCE {
339 	XCoordinate	INTEGER,
340 	YCoordinate	INTEGER,
341 	HASH		OCTET STRING SIZE(32),
342 	CipherText	OCTET STRING }
343 */
344 #define SM2_MIN_PLAINTEXT_SIZE	1 // re-compute SM2_MIN_CIPHERTEXT_SIZE when modify
345 #define SM2_MAX_PLAINTEXT_SIZE	255 // re-compute SM2_MAX_CIPHERTEXT_SIZE when modify
346 
347 typedef struct {
348 	SM2_POINT point;
349 	uint8_t hash[32];
350 	uint8_t ciphertext_size;
351 	uint8_t ciphertext[SM2_MAX_PLAINTEXT_SIZE];
352 } SM2_CIPHERTEXT;
353 
354 int sm2_do_encrypt_ex(const SM2_KEY *key, int flags, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out);
355 int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out);
356 int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen);
357 
358 #define SM2_MIN_CIPHERTEXT_SIZE	45 // dependes on SM2_MIN_PLAINTEXT_SIZE
359 #define SM2_MAX_CIPHERTEXT_SIZE	366 // depends on SM2_MAX_PLAINTEXT_SIZE
360 int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen);
361 int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen);
362 int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
363 int sm2_encrypt_ex(const SM2_KEY *key, int flags, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
364 int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
365 int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
366 
367 
368 int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out);
369 
370 
371 #ifdef __cplusplus
372 }
373 #endif
374 #endif
375