• 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 #include <stdio.h>
12 #include <string.h>
13 #include <stdint.h>
14 #include <stdlib.h>
15 #include <assert.h>
16 #include <gmssl/hex.h>
17 #include <gmssl/mem.h>
18 #include <gmssl/sm9.h>
19 #include <gmssl/error.h>
20 #include <gmssl/endian.h>
21 
22 
23 const sm9_bn_t SM9_ZERO = {0,0,0,0,0,0,0,0};
24 const sm9_bn_t SM9_ONE = {1,0,0,0,0,0,0,0};
25 static const sm9_bn_t SM9_TWO = {2,0,0,0,0,0,0,0};
26 static const sm9_bn_t SM9_FIVE = {5,0,0,0,0,0,0,0};
27 
28 
29 // p =  b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457d
30 // n =  b640000002a3a6f1d603ab4ff58ec74449f2934b18ea8beee56ee19cd69ecf25
31 // mu_p = 2^512 // p = 167980e0beb5759a655f73aebdcd1312af2665f6d1e36081c71188f90d5c22146
32 // mu_n = 2^512 // n
33 const sm9_bn_t SM9_P = {0xe351457d, 0xe56f9b27, 0x1a7aeedb, 0x21f2934b, 0xf58ec745, 0xd603ab4f, 0x02a3a6f1, 0xb6400000};
34 const sm9_bn_t SM9_N = {0xd69ecf25, 0xe56ee19c, 0x18ea8bee, 0x49f2934b, 0xf58ec744, 0xd603ab4f, 0x02a3a6f1, 0xb6400000};
35 static const sm9_bn_t SM9_P_MINUS_ONE = {0xe351457c, 0xe56f9b27, 0x1a7aeedb, 0x21f2934b, 0xf58ec745, 0xd603ab4f, 0x02a3a6f1, 0xb6400000};
36 static const sm9_bn_t SM9_N_MINUS_ONE = {0xd69ecf24, 0xe56ee19c, 0x18ea8bee, 0x49f2934b, 0xf58ec744, 0xd603ab4f, 0x02a3a6f1, 0xb6400000};
37 static const sm9_barrett_bn_t SM9_MU_P = {0xd5c22146, 0x71188f90, 0x1e36081c, 0xf2665f6d, 0xdcd1312a, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001};
38 static const sm9_barrett_bn_t SM9_MU_N = {0xdfc97c2f, 0x74df4fd4, 0xc9c073b0, 0x9c95d85e, 0xdcd1312c, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001};
39 static const sm9_barrett_bn_t SM9_MU_N_MINUS_ONE = {0xdfc97c31, 0x74df4fd4, 0xc9c073b0, 0x9c95d85e, 0xdcd1312c, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001};
40 
41 
42 // P1.X 0x93DE051D62BF718FF5ED0704487D01D6E1E4086909DC3280E8C4E4817C66DDDD
43 // P1.Y 0x21FE8DDA4F21E607631065125C395BBC1C1C00CBFA6024350C464CD70A3EA616
44 const SM9_POINT _SM9_P1 = {
45 	{0x7c66dddd, 0xe8c4e481, 0x09dc3280, 0xe1e40869, 0x487d01d6, 0xf5ed0704, 0x62bf718f, 0x93de051d},
46 	{0x0a3ea616, 0x0c464cd7, 0xfa602435, 0x1c1c00cb, 0x5c395bbc, 0x63106512, 0x4f21e607, 0x21fe8dda},
47 	{1,0,0,0,0,0,0,0}
48 };
49 const SM9_POINT *SM9_P1 = &_SM9_P1;
50 
51 
52 /*
53 	X : [0x3722755292130b08d2aab97fd34ec120ee265948d19c17abf9b7213baf82d65bn,
54 	     0x85aef3d078640c98597b6027b441a01ff1dd2c190f5e93c454806c11d8806141n],
55 	Y : [0xa7cf28d519be3da65f3170153d278ff247efba98a71a08116215bba5c999a7c7n,
56 	     0x17509b092e845c1266ba0d262cbee6ed0736a96fa347c8bd856dc76b84ebeb96n],
57 	Z : [1n, 0n],
58 */
59 const SM9_TWIST_POINT _SM9_P2 = {
60 	{{0xAF82D65B, 0xF9B7213B, 0xD19C17AB, 0xEE265948, 0xD34EC120, 0xD2AAB97F, 0x92130B08, 0x37227552},
61 	 {0xD8806141, 0x54806C11, 0x0F5E93C4, 0xF1DD2C19, 0xB441A01F, 0x597B6027, 0x78640C98, 0x85AEF3D0}},
62 	{{0xC999A7C7, 0x6215BBA5, 0xA71A0811, 0x47EFBA98, 0x3D278FF2, 0x5F317015, 0x19BE3DA6, 0xA7CF28D5},
63 	 {0x84EBEB96, 0x856DC76B, 0xA347C8BD, 0x0736A96F, 0x2CBEE6ED, 0x66BA0D26, 0x2E845C12, 0x17509B09}},
64 	{{1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}},
65 };
66 const SM9_TWIST_POINT *SM9_P2 = &_SM9_P2;
67 
68 
69 const SM9_TWIST_POINT _SM9_Ppubs = {
70 	{{0x96EA5E32, 0x8F14D656, 0x386A92DD, 0x414D2177, 0x24A3B573, 0x6CE843ED, 0x152D1F78, 0x29DBA116},
71 	 {0x1B94C408, 0x0AB1B679, 0x5E392CFB, 0x1CE0711C, 0x41B56501, 0xE48AFF4B, 0x3084F733, 0x9F64080B}},
72 	{{0xB4E3216D, 0x0E75C05F, 0x5CDFF073, 0x1006E85F, 0xB7A46F74, 0x1A7CE027, 0xDDA532DA, 0x41E00A53},
73          {0xD0EF1C25, 0xE89E1408, 0x1A77F335, 0xAD3E2FDB, 0x47E3A0CB, 0xB57329F4, 0xABEA0112, 0x69850938}},
74 	{{1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}},
75 };
76 const SM9_TWIST_POINT *SM9_Ppubs = &_SM9_Ppubs;
77 
78 
sm9_bn_to_bytes(const sm9_bn_t a,uint8_t out[32])79 void sm9_bn_to_bytes(const sm9_bn_t a, uint8_t out[32])
80 {
81 	int i;
82 	for (i = 7; i >= 0; i--) {
83 		PUTU32(out, (uint32_t)a[i]);
84 		out += sizeof(uint32_t);
85 	}
86 }
87 
sm9_bn_from_bytes(sm9_bn_t r,const uint8_t in[32])88 void sm9_bn_from_bytes(sm9_bn_t r, const uint8_t in[32])
89 {
90 	int i;
91 	for (i = 7; i >= 0; i--) {
92 		r[i] = GETU32(in);
93 		in += sizeof(uint32_t);
94 	}
95 }
96 
sm9_bn_from_hex(sm9_bn_t r,const char hex[64])97 int sm9_bn_from_hex(sm9_bn_t r, const char hex[64])
98 {
99 	uint8_t buf[32];
100 	size_t len;
101 	if (hex_to_bytes(hex, 64, buf, &len) < 0) {
102 		return -1;
103 	}
104 	sm9_bn_from_bytes(r, buf);
105 	return 1;
106 }
107 
sm9_bn_to_hex(const sm9_bn_t a,char hex[64])108 void sm9_bn_to_hex(const sm9_bn_t a, char hex[64])
109 {
110 	int i;
111 	for (i = 7; i >= 0; i--) {
112 		(void)sprintf(hex + 8*(7-i), "%08x", (uint32_t)a[i]);
113 		//hex += 8;
114 	}
115 }
116 
sm9_print_bn(const char * prefix,const sm9_bn_t a)117 void sm9_print_bn(const char *prefix, const sm9_bn_t a)
118 {
119 	char hex[65] = {0};
120 	sm9_bn_to_hex(a, hex);
121 	printf("%s\n%s\n", prefix, hex);
122 }
123 
sm9_bn_to_bits(const sm9_bn_t a,char bits[256])124 void sm9_bn_to_bits(const sm9_bn_t a, char bits[256])
125 {
126 	int i, j;
127 	for (i = 7; i >= 0; i--) {
128 		uint32_t w = a[i];
129 		for (j = 0; j < 32; j++) {
130 			*bits++ = (w & 0x80000000) ? '1' : '0';
131 			w <<= 1;
132 		}
133 	}
134 }
135 
sm9_bn_cmp(const sm9_bn_t a,const sm9_bn_t b)136 int sm9_bn_cmp(const sm9_bn_t a, const sm9_bn_t b)
137 {
138 	int i;
139 	for (i = 7; i >= 0; i--) {
140 		if (a[i] > b[i])
141 			return 1;
142 		if (a[i] < b[i])
143 			return -1;
144 	}
145 	return 0;
146 }
147 
148 
149 
150 
sm9_bn_copy(sm9_bn_t r,const sm9_bn_t a)151 void sm9_bn_copy(sm9_bn_t r, const sm9_bn_t a)
152 {
153 	memcpy(r, a, sizeof(sm9_bn_t));
154 }
155 
sm9_bn_set_word(sm9_bn_t r,uint32_t a)156 void sm9_bn_set_word(sm9_bn_t r, uint32_t a)
157 {
158 	sm9_bn_set_zero(r);
159 	r[0] = a;
160 }
161 
sm9_bn_add(sm9_bn_t r,const sm9_bn_t a,const sm9_bn_t b)162 void sm9_bn_add(sm9_bn_t r, const sm9_bn_t a, const sm9_bn_t b)
163 {
164 	int i;
165 	r[0] = a[0] + b[0];
166 	for (i = 1; i < 8; i++) {
167 		r[i] = a[i] + b[i] + (r[i-1] >> 32);
168 	}
169 	for (i = 0; i < 7; i++) {
170 		r[i] &= 0xffffffff;
171 	}
172 }
173 
sm9_bn_sub(sm9_bn_t ret,const sm9_bn_t a,const sm9_bn_t b)174 void sm9_bn_sub(sm9_bn_t ret, const sm9_bn_t a, const sm9_bn_t b)
175 {
176 	int i;
177 	sm9_bn_t r;
178 	r[0] = ((uint64_t)1 << 32) + a[0] - b[0];
179 	for (i = 1; i < 7; i++) {
180 		r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32);
181 		r[i - 1] &= 0xffffffff;
182 	}
183 	r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1;
184 	r[i - 1] &= 0xffffffff;
185 	sm9_bn_copy(ret, r);
186 }
187 
sm9_bn_rand_range(sm9_bn_t r,const sm9_bn_t range)188 int sm9_bn_rand_range(sm9_bn_t r, const sm9_bn_t range)
189 {
190 	FILE *fp;
191 	uint8_t buf[256];
192 
193 	fp = fopen("/dev/urandom", "rb");
194 	do {
195 		fread(buf, 1, 256, fp);
196 		sm9_bn_from_bytes(r, buf);
197 	} while (sm9_bn_cmp(r, range) >= 0);
198 	fclose(fp);
199 	return 1;
200 }
201 
sm9_bn_equ(const sm9_bn_t a,const sm9_bn_t b)202 int sm9_bn_equ(const sm9_bn_t a, const sm9_bn_t b)
203 {
204 	int i;
205 	for (i = 0; i < 8; i++) {
206 		if (a[i] != b[i])
207 			return 0;
208 	}
209 	return 1;
210 }
211 
sm9_fp_add(sm9_fp_t r,const sm9_fp_t a,const sm9_fp_t b)212 void sm9_fp_add(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b)
213 {
214 	sm9_bn_add(r, a, b);
215 	if (sm9_bn_cmp(r, SM9_P) >= 0)
216 		return sm9_bn_sub(r, r, SM9_P);
217 }
218 
sm9_fp_sub(sm9_fp_t r,const sm9_fp_t a,const sm9_fp_t b)219 void sm9_fp_sub(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b)
220 {
221 	if (sm9_bn_cmp(a, b) >= 0) {
222 		sm9_bn_sub(r, a, b);
223 	} else {
224 		sm9_bn_t t;
225 		sm9_bn_sub(t, SM9_P, b);
226 		sm9_bn_add(r, t, a);
227 	}
228 }
229 
sm9_fp_dbl(sm9_fp_t r,const sm9_fp_t a)230 void sm9_fp_dbl(sm9_fp_t r, const sm9_fp_t a)
231 {
232 	sm9_fp_add(r, a, a);
233 }
234 
sm9_fp_tri(sm9_fp_t r,const sm9_fp_t a)235 void sm9_fp_tri(sm9_fp_t r, const sm9_fp_t a)
236 {
237 	sm9_fp_t t;
238 	sm9_fp_dbl(t, a);
239 	sm9_fp_add(r, t, a);
240 }
241 
sm9_fp_div2(sm9_fp_t r,const sm9_fp_t a)242 void sm9_fp_div2(sm9_fp_t r, const sm9_fp_t a)
243 {
244 	int i;
245 	sm9_bn_copy(r, a);
246 	if (r[0] & 0x01) {
247 		sm9_bn_add(r, r, SM9_P);
248 	}
249 	for (i = 0; i < 7; i++) {
250 		r[i] = (r[i] >> 1) | ((r[i + 1] & 0x01) << 31);
251 	}
252 	r[i] >>= 1;
253 }
254 
sm9_fp_neg(sm9_fp_t r,const sm9_fp_t a)255 void sm9_fp_neg(sm9_fp_t r, const sm9_fp_t a)
256 {
257 	if (sm9_bn_is_zero(a)) {
258 		sm9_bn_copy(r, a);
259 	} else {
260 		sm9_bn_sub(r, SM9_P, a);
261 	}
262 }
263 
sm9_bn_print(FILE * fp,int fmt,int ind,const char * label,const sm9_bn_t a)264 int sm9_bn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_bn_t a)
265 {
266 	uint8_t buf[32];
267 	sm9_bn_to_bytes(a, buf);
268 	format_bytes(fp, fmt, ind, label, buf, sizeof(buf));
269 	return 1;
270 }
271 
sm9_barrett_bn_cmp(const sm9_barrett_bn_t a,const sm9_barrett_bn_t b)272 int sm9_barrett_bn_cmp(const sm9_barrett_bn_t a, const sm9_barrett_bn_t b)
273 {
274 	int i;
275 	for (i = 8; i >= 0; i--) {
276 		if (a[i] > b[i])
277 			return 1;
278 		if (a[i] < b[i])
279 			return -1;
280 	}
281 	return 0;
282 }
283 
sm9_barrett_bn_add(sm9_barrett_bn_t r,const sm9_barrett_bn_t a,const sm9_barrett_bn_t b)284 void sm9_barrett_bn_add(sm9_barrett_bn_t r, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b)
285 {
286 	int i;
287 	r[0] = a[0] + b[0];
288 	for (i = 1; i < 9; i++) {
289 		r[i] = a[i] + b[i] + (r[i-1] >> 32);
290 	}
291 	for (i = 0; i < 8; i++) {
292 		r[i] &= 0xffffffff;
293 	}
294 }
295 
sm9_barrett_bn_sub(sm9_barrett_bn_t ret,const sm9_barrett_bn_t a,const sm9_barrett_bn_t b)296 void sm9_barrett_bn_sub(sm9_barrett_bn_t ret, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b)
297 {
298 	sm9_barrett_bn_t r;
299 	int i;
300 	r[0] = ((uint64_t)1 << 32) + a[0] - b[0];
301 	for (i = 1; i < 8; i++) {
302 		r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32);
303 		r[i - 1] &= 0xffffffff;
304 	}
305 	r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1;
306 	r[i - 1] &= 0xffffffff;
307 	for (i = 0; i < 9; i++) {
308 		ret[i] = r[i];
309 	}
310 }
311 
sm9_fp_mul(sm9_fp_t r,const sm9_fp_t a,const sm9_fp_t b)312 void sm9_fp_mul(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b)
313 {
314 	uint64_t s[18];
315 	sm9_barrett_bn_t zh, zl, q;
316 	uint64_t w;
317 	int i, j;
318 
319 	/* z = a * b */
320 	for (i = 0; i < 8; i++) {
321 		s[i] = 0;
322 	}
323 	for (i = 0; i < 8; i++) {
324 		w = 0;
325 		for (j = 0; j < 8; j++) {
326 			w += s[i + j] + a[i] * b[j];
327 			s[i + j] = w & 0xffffffff;
328 			w >>= 32;
329 		}
330 		s[i + 8] = w;
331 	}
332 
333 	/* zl = z mod (2^32)^9 = z[0..8]
334 	 * zh = z // (2^32)^7 = z[7..15] */
335 	for (i = 0; i < 9; i++) {
336 		zl[i] = s[i];
337 		zh[i] = s[7 + i];
338 	}
339 
340 	/* q = zh * mu // (2^32)^9 */
341 	for (i = 0; i < 18; i++) {
342 		s[i] = 0;
343 	}
344 	for (i = 0; i < 9; i++) {
345 		w = 0;
346 		for (j = 0; j < 9; j++) {
347 			w += s[i + j] + zh[i] * SM9_MU_P[j];
348 			s[i + j] = w & 0xffffffff;
349 			w >>= 32;
350 		}
351 		s[i + 9] = w;
352 	}
353 	for (i = 0; i < 9; i++) {
354 		q[i] = s[9 + i];
355 	}
356 
357 	/* q = q * p mod (2^32)^9 */
358 	for (i = 0; i < 18; i++) {
359 		s[i] = 0;
360 	}
361 	for (i = 0; i < 9; i++) {
362 		w = 0;
363 		for (j = 0; j < 8; j++) {
364 			w += s[i + j] + q[i] * SM9_P[j];
365 			s[i + j] = w & 0xffffffff;
366 			w >>= 32;
367 		}
368 		s[i + 8] = w;
369 	}
370 	for (i = 0; i < 9; i++) {
371 		q[i] = s[i];
372 	}
373 
374 	/* r = zl - q (mod (2^32)^9) */
375 
376 	if (sm9_barrett_bn_cmp(zl, q)) {
377 		sm9_barrett_bn_sub(zl, zl, q);
378 	} else {
379 		sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000};
380 		sm9_barrett_bn_sub(q, c, q);
381 		sm9_barrett_bn_add(zl, q, zl);
382 	}
383 
384 
385 	for (i = 0; i < 8; i++) {
386 		r[i] = zl[i];
387 	}
388 
389 	r[7] += (zl[8] << 32);
390 
391 	/* while r >= p do: r = r - p */
392 	while (sm9_bn_cmp(r, SM9_P) >= 0) {
393 
394 		sm9_bn_sub(r, r, SM9_P);
395 	}
396 }
397 
sm9_fp_sqr(sm9_fp_t r,const sm9_fp_t a)398 void sm9_fp_sqr(sm9_fp_t r, const sm9_fp_t a)
399 {
400 	sm9_fp_mul(r, a, a);
401 }
402 
sm9_fp_pow(sm9_fp_t r,const sm9_fp_t a,const sm9_bn_t e)403 void sm9_fp_pow(sm9_fp_t r, const sm9_fp_t a, const sm9_bn_t e)
404 {
405 	sm9_fp_t t;
406 	uint32_t w;
407 	int i, j;
408 
409 	assert(sm9_bn_cmp(e, SM9_P_MINUS_ONE) < 0);
410 
411 	sm9_bn_set_one(t);
412 	for (i = 7; i >= 0; i--) {
413 		w = (uint32_t)e[i];
414 		for (j = 0; j < 32; j++) {
415 			sm9_fp_sqr(t, t);
416 			if (w & 0x80000000)
417 				sm9_fp_mul(t, t, a);
418 			w <<= 1;
419 		}
420 	}
421 	sm9_bn_copy(r, t);
422 }
423 
sm9_fp_inv(sm9_fp_t r,const sm9_fp_t a)424 void sm9_fp_inv(sm9_fp_t r, const sm9_fp_t a)
425 {
426 	sm9_fp_t e;
427 	sm9_bn_sub(e, SM9_P, SM9_TWO);
428 	sm9_fp_pow(r, a, e);
429 }
430 
sm9_fp_from_bytes(sm9_fp_t r,const uint8_t buf[32])431 int sm9_fp_from_bytes(sm9_fp_t r, const uint8_t buf[32])
432 {
433 	sm9_bn_from_bytes(r, buf);
434 	if (sm9_bn_cmp(r, SM9_P) >= 0) {
435 		error_print();
436 		return -1;
437 	}
438 	return 1;
439 }
440 
sm9_fp_from_hex(sm9_fp_t r,const char hex[64])441 int sm9_fp_from_hex(sm9_fp_t r, const char hex[64])
442 {
443 	if (sm9_bn_from_hex(r, hex) != 1) {
444 		error_print();
445 		return -1;
446 	}
447 	if (sm9_bn_cmp(r, SM9_P) >= 0) {
448 		error_print();
449 		return -1;
450 	}
451 	return 1;
452 }
453 
454 
455 const sm9_fp2_t SM9_FP2_ZERO = {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
456 const sm9_fp2_t SM9_FP2_ONE = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
457 const sm9_fp2_t SM9_FP2_U = {{0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,0}};
458 static const sm9_fp2_t SM9_FP2_5U = {{0,0,0,0,0,0,0,0},{5,0,0,0,0,0,0,0}};
459 
sm9_fp2_equ(const sm9_fp2_t a,const sm9_fp2_t b)460 int sm9_fp2_equ(const sm9_fp2_t a, const sm9_fp2_t b)
461 {
462 	return (gmssl_secure_memcmp(a, b, sizeof(sm9_fp2_t)) == 0);
463 }
464 
sm9_fp2_copy(sm9_fp2_t r,const sm9_fp2_t a)465 void sm9_fp2_copy(sm9_fp2_t r, const sm9_fp2_t a)
466 {
467 	memcpy(r, a, sizeof(sm9_fp2_t));
468 }
469 
sm9_fp2_rand(sm9_fp2_t r)470 int sm9_fp2_rand(sm9_fp2_t r)
471 {
472 	if (sm9_fp_rand(r[0]) != 1
473 		|| sm9_fp_rand(r[1]) != 1) {
474 		error_print();
475 		return -1;
476 	}
477 	return 1;
478 }
479 
sm9_fp2_to_bytes(const sm9_fp2_t a,uint8_t buf[64])480 void sm9_fp2_to_bytes(const sm9_fp2_t a, uint8_t buf[64])
481 {
482 	sm9_fp_to_bytes(a[1], buf);
483 	sm9_fp_to_bytes(a[0], buf + 32);
484 }
485 
sm9_fp2_from_bytes(sm9_fp2_t r,const uint8_t buf[64])486 int sm9_fp2_from_bytes(sm9_fp2_t r, const uint8_t buf[64])
487 {
488 	if (sm9_fp_from_bytes(r[1], buf) != 1
489 		|| sm9_fp_from_bytes(r[0], buf + 32) != 1) {
490 		error_print();
491 		return -1;
492 	}
493 	return 1;
494 }
495 
sm9_fp2_from_hex(sm9_fp2_t r,const char hex[129])496 int sm9_fp2_from_hex(sm9_fp2_t r, const char hex[129])
497 {
498 	if (sm9_fp_from_hex(r[1], hex) != 1
499 		|| sm9_fp_from_hex(r[0], hex + 65) != 1) {
500 		error_print();
501 		return -1;
502 	}
503 	/*
504 	if (hex[64] != SM9_HEX_SEP) {
505 		error_print();
506 		return -1;
507 	}
508 	*/
509 	return 1;
510 }
511 
sm9_fp2_to_hex(const sm9_fp2_t a,char hex[129])512 void sm9_fp2_to_hex(const sm9_fp2_t a, char hex[129])
513 {
514 	sm9_fp_to_hex(a[1], hex);
515 	hex[64] = SM9_HEX_SEP;
516 	sm9_fp_to_hex(a[0], hex + 65);
517 }
518 
sm9_fp2_set_fp(sm9_fp2_t r,const sm9_fp_t a)519 void sm9_fp2_set_fp(sm9_fp2_t r, const sm9_fp_t a)
520 {
521 	sm9_fp_copy(r[0], a);
522 	sm9_fp_set_zero(r[1]);
523 }
524 
sm9_fp2_set(sm9_fp2_t r,const sm9_fp_t a0,const sm9_fp_t a1)525 void sm9_fp2_set(sm9_fp2_t r, const sm9_fp_t a0, const sm9_fp_t a1)
526 {
527 	sm9_fp_copy(r[0], a0);
528 	sm9_fp_copy(r[1], a1);
529 }
530 
sm9_fp2_add(sm9_fp2_t r,const sm9_fp2_t a,const sm9_fp2_t b)531 void sm9_fp2_add(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b)
532 {
533 	sm9_fp_add(r[0], a[0], b[0]);
534 	sm9_fp_add(r[1], a[1], b[1]);
535 }
536 
sm9_fp2_dbl(sm9_fp2_t r,const sm9_fp2_t a)537 void sm9_fp2_dbl(sm9_fp2_t r, const sm9_fp2_t a)
538 {
539 	sm9_fp_dbl(r[0], a[0]);
540 	sm9_fp_dbl(r[1], a[1]);
541 }
542 
sm9_fp2_tri(sm9_fp2_t r,const sm9_fp2_t a)543 void sm9_fp2_tri(sm9_fp2_t r, const sm9_fp2_t a)
544 {
545 	sm9_fp_tri(r[0], a[0]);
546 	sm9_fp_tri(r[1], a[1]);
547 }
548 
sm9_fp2_sub(sm9_fp2_t r,const sm9_fp2_t a,const sm9_fp2_t b)549 void sm9_fp2_sub(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b)
550 {
551 	sm9_fp_sub(r[0], a[0], b[0]);
552 	sm9_fp_sub(r[1], a[1], b[1]);
553 }
554 
sm9_fp2_neg(sm9_fp2_t r,const sm9_fp2_t a)555 void sm9_fp2_neg(sm9_fp2_t r, const sm9_fp2_t a)
556 {
557 	sm9_fp_neg(r[0], a[0]);
558 	sm9_fp_neg(r[1], a[1]);
559 }
560 
sm9_fp2_mul(sm9_fp2_t r,const sm9_fp2_t a,const sm9_fp2_t b)561 void sm9_fp2_mul(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b)
562 {
563 	sm9_fp_t r0, r1, t;
564 
565 	// r0 = a0 * b0 - 2 * a1 * b1
566 	sm9_fp_mul(r0, a[0], b[0]);
567 	sm9_fp_mul(t, a[1], b[1]);
568 	sm9_fp_dbl(t, t);
569 	sm9_fp_sub(r0, r0, t);
570 
571 	// r1 = a0 * b1 + a1 * b0
572 	sm9_fp_mul(r1, a[0], b[1]);
573 	sm9_fp_mul(t, a[1], b[0]);
574 	sm9_fp_add(r1, r1, t);
575 
576 	sm9_fp_copy(r[0], r0);
577 	sm9_fp_copy(r[1], r1);
578 }
579 
sm9_fp2_mul_u(sm9_fp2_t r,const sm9_fp2_t a,const sm9_fp2_t b)580 void sm9_fp2_mul_u(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b)
581 {
582 	sm9_fp_t r0, r1, t;
583 
584 	// r0 = -2 * (a0 * b1 + a1 * b0)
585 	sm9_fp_mul(r0, a[0], b[1]);
586 	sm9_fp_mul(t,  a[1], b[0]);
587 	sm9_fp_add(r0, r0, t);
588 	sm9_fp_dbl(r0, r0);
589 	sm9_fp_neg(r0, r0);
590 
591 	// r1 = a0 * b0 - 2 * a1 * b1
592 	sm9_fp_mul(r1, a[0], b[0]);
593 	sm9_fp_mul(t, a[1], b[1]);
594 	sm9_fp_dbl(t, t);
595 	sm9_fp_sub(r1, r1, t);
596 
597 	sm9_fp_copy(r[0], r0);
598 	sm9_fp_copy(r[1], r1);
599 }
600 
sm9_fp2_mul_fp(sm9_fp2_t r,const sm9_fp2_t a,const sm9_fp_t k)601 void sm9_fp2_mul_fp(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp_t k)
602 {
603 	sm9_fp_mul(r[0], a[0], k);
604 	sm9_fp_mul(r[1], a[1], k);
605 }
606 
sm9_fp2_sqr(sm9_fp2_t r,const sm9_fp2_t a)607 void sm9_fp2_sqr(sm9_fp2_t r, const sm9_fp2_t a)
608 {
609 	sm9_fp_t r0, r1, t;
610 
611 	// a0^2 - 2 * a1^2
612 	sm9_fp_sqr(r0, a[0]);
613 	sm9_fp_sqr(t, a[1]);
614 	sm9_fp_dbl(t, t);
615 	sm9_fp_sub(r0, r0, t);
616 
617 	// r1 = 2 * a0 * a1
618 	sm9_fp_mul(r1, a[0], a[1]);
619 	sm9_fp_dbl(r1, r1);
620 
621 	sm9_bn_copy(r[0], r0);
622 	sm9_bn_copy(r[1], r1);
623 }
624 
sm9_fp2_sqr_u(sm9_fp2_t r,const sm9_fp2_t a)625 void sm9_fp2_sqr_u(sm9_fp2_t r, const sm9_fp2_t a)
626 {
627 	sm9_fp_t r0, r1, t;
628 
629 	// r0 = -4 * a0 * a1
630 	sm9_fp_mul(r0, a[0], a[1]);
631 	sm9_fp_dbl(r0, r0);
632 	sm9_fp_dbl(r0, r0);
633 	sm9_fp_neg(r0, r0);
634 
635 	// r1 = a0^2 - 2 * a1^2
636 	sm9_fp_sqr(r1, a[0]);
637 	sm9_fp_sqr(t, a[1]);
638 	sm9_fp_dbl(t, t);
639 	sm9_fp_sub(r1, r1, t);
640 
641 	sm9_fp_copy(r[0], r0);
642 	sm9_fp_copy(r[1], r1);
643 
644 }
645 
sm9_fp2_inv(sm9_fp2_t r,const sm9_fp2_t a)646 void sm9_fp2_inv(sm9_fp2_t r, const sm9_fp2_t a)
647 {
648 	if (sm9_fp_is_zero(a[0])) {
649 		// r0 = 0
650 		sm9_fp_set_zero(r[0]);
651 		// r1 = -(2 * a1)^-1
652 		sm9_fp_dbl(r[1], a[1]);
653 		sm9_fp_inv(r[1], r[1]);
654 		sm9_fp_neg(r[1], r[1]);
655 
656 	} else if (sm9_fp_is_zero(a[1])) {
657 		/* r1 = 0 */
658 		sm9_fp_set_zero(r[1]);
659 		/* r0 = a0^-1 */
660 		sm9_fp_inv(r[0], a[0]);
661 
662 	} else {
663 		sm9_fp_t k, t;
664 
665 		// k = (a[0]^2 + 2 * a[1]^2)^-1
666 		sm9_fp_sqr(k, a[0]);
667 		sm9_fp_sqr(t, a[1]);
668 		sm9_fp_dbl(t, t);
669 		sm9_fp_add(k, k, t);
670 		sm9_fp_inv(k, k);
671 
672 		// r[0] = a[0] * k
673 		sm9_fp_mul(r[0], a[0], k);
674 
675 		// r[1] = -a[1] * k
676 		sm9_fp_mul(r[1], a[1], k);
677 		sm9_fp_neg(r[1], r[1]);
678 	}
679 }
680 
sm9_fp2_div(sm9_fp2_t r,const sm9_fp2_t a,const sm9_fp2_t b)681 void sm9_fp2_div(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b)
682 {
683 	sm9_fp2_t t;
684 	sm9_fp2_inv(t, b);
685 	sm9_fp2_mul(r, a, t);
686 }
687 
sm9_fp2_div2(sm9_fp2_t r,const sm9_fp2_t a)688 void sm9_fp2_div2(sm9_fp2_t r, const sm9_fp2_t a)
689 {
690 	sm9_fp_div2(r[0], a[0]);
691 	sm9_fp_div2(r[1], a[1]);
692 }
693 
sm9_fp2_print(FILE * fp,int fmt,int ind,const char * label,const sm9_fp2_t a)694 int sm9_fp2_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fp2_t a)
695 {
696 	return 1;
697 }
698 
699 
700 const sm9_fp4_t SM9_FP4_ZERO = {{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}};
701 const sm9_fp4_t SM9_FP4_ONE = {{{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}};
702 const sm9_fp4_t SM9_FP4_U = {{{0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}};
703 const sm9_fp4_t SM9_FP4_V = {{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}};
704 
sm9_fp4_equ(const sm9_fp4_t a,const sm9_fp4_t b)705 int sm9_fp4_equ(const sm9_fp4_t a, const sm9_fp4_t b)
706 {
707 	return (gmssl_secure_memcmp(a, b, sizeof(sm9_fp4_t)) == 0);
708 }
709 
sm9_fp4_rand(sm9_fp4_t r)710 int sm9_fp4_rand(sm9_fp4_t r)
711 {
712 	if (sm9_fp2_rand(r[1]) != 1
713 		|| sm9_fp2_rand(r[0]) != 1) {
714 		error_print();
715 		return -1;
716 	}
717 	return 1;
718 }
719 
sm9_fp4_copy(sm9_fp4_t r,const sm9_fp4_t a)720 void sm9_fp4_copy(sm9_fp4_t r, const sm9_fp4_t a)
721 {
722 	memcpy(r, a, sizeof(sm9_fp4_t));
723 }
724 
sm9_fp4_to_bytes(const sm9_fp4_t a,uint8_t buf[128])725 void sm9_fp4_to_bytes(const sm9_fp4_t a, uint8_t buf[128])
726 {
727 	sm9_fp2_to_bytes(a[1], buf);
728 	sm9_fp2_to_bytes(a[0], buf + 64);
729 }
730 
sm9_fp4_from_bytes(sm9_fp4_t r,const uint8_t buf[128])731 int sm9_fp4_from_bytes(sm9_fp4_t r, const uint8_t buf[128])
732 {
733 	if (sm9_fp2_from_bytes(r[1], buf) != 1
734 		|| sm9_fp2_from_bytes(r[0], buf + 64) != 1) {
735 		error_print();
736 		return -1;
737 	}
738 	return 1;
739 }
740 
sm9_fp4_from_hex(sm9_fp4_t r,const char hex[65* 4])741 int sm9_fp4_from_hex(sm9_fp4_t r, const char hex[65 * 4])
742 {
743 	if (sm9_fp2_from_hex(r[1], hex) != 1
744 		|| hex[129] != SM9_HEX_SEP
745 		|| sm9_fp2_from_hex(r[0], hex + 130) != 1) {
746 		error_print();
747 		return -1;
748 	}
749 	return 1;
750 }
751 
sm9_fp4_to_hex(const sm9_fp4_t a,char hex[259])752 void sm9_fp4_to_hex(const sm9_fp4_t a, char hex[259])
753 {
754 	sm9_fp2_to_hex(a[1], hex);
755 	hex[129] = SM9_HEX_SEP;
756 	sm9_fp2_to_hex(a[0], hex + 130);
757 }
758 
sm9_fp4_set_fp(sm9_fp4_t r,const sm9_fp_t a)759 void sm9_fp4_set_fp(sm9_fp4_t r, const sm9_fp_t a)
760 {
761 	sm9_fp2_set_fp(r[0], a);
762 	sm9_fp2_set_zero(r[1]);
763 }
764 
sm9_fp4_set_fp2(sm9_fp4_t r,const sm9_fp2_t a)765 void sm9_fp4_set_fp2(sm9_fp4_t r, const sm9_fp2_t a)
766 {
767 	sm9_fp2_copy(r[0], a);
768 	sm9_fp2_set_zero(r[1]);
769 }
770 
sm9_fp4_set(sm9_fp4_t r,const sm9_fp2_t a0,const sm9_fp2_t a1)771 void sm9_fp4_set(sm9_fp4_t r, const sm9_fp2_t a0, const sm9_fp2_t a1)
772 {
773 	sm9_fp2_copy(r[0], a0);
774 	sm9_fp2_copy(r[1], a1);
775 }
776 
sm9_fp4_set_u(sm9_fp4_t r)777 void sm9_fp4_set_u(sm9_fp4_t r)
778 {
779 	sm9_fp2_set_u(r[0]);
780 	sm9_fp2_set_zero(r[1]);
781 }
782 
sm9_fp4_set_v(sm9_fp4_t r)783 void sm9_fp4_set_v(sm9_fp4_t r)
784 {
785 	sm9_fp2_set_zero(r[0]);
786 	sm9_fp2_set_one(r[1]);
787 }
788 
sm9_fp4_add(sm9_fp4_t r,const sm9_fp4_t a,const sm9_fp4_t b)789 void sm9_fp4_add(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b)
790 {
791 	sm9_fp2_add(r[0], a[0], b[0]);
792 	sm9_fp2_add(r[1], a[1], b[1]);
793 }
794 
sm9_fp4_dbl(sm9_fp4_t r,const sm9_fp4_t a)795 void sm9_fp4_dbl(sm9_fp4_t r, const sm9_fp4_t a)
796 {
797 	sm9_fp2_dbl(r[0], a[0]);
798 	sm9_fp2_dbl(r[1], a[1]);
799 }
800 
sm9_fp4_sub(sm9_fp4_t r,const sm9_fp4_t a,const sm9_fp4_t b)801 void sm9_fp4_sub(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b)
802 {
803 	sm9_fp2_sub(r[0], a[0], b[0]);
804 	sm9_fp2_sub(r[1], a[1], b[1]);
805 }
806 
sm9_fp4_neg(sm9_fp4_t r,const sm9_fp4_t a)807 void sm9_fp4_neg(sm9_fp4_t r, const sm9_fp4_t a)
808 {
809 	sm9_fp2_neg(r[0], a[0]);
810 	sm9_fp2_neg(r[1], a[1]);
811 }
812 
sm9_fp4_mul(sm9_fp4_t r,const sm9_fp4_t a,const sm9_fp4_t b)813 void sm9_fp4_mul(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b)
814 {
815 	sm9_fp2_t r0, r1, t;
816 
817 	sm9_fp2_mul(r0, a[0], b[0]);
818 	sm9_fp2_mul_u(t, a[1], b[1]);
819 	sm9_fp2_add(r0, r0, t);
820 
821 	sm9_fp2_mul(r1, a[0], b[1]);
822 	sm9_fp2_mul(t, a[1], b[0]);
823 	sm9_fp2_add(r1, r1, t);
824 
825 	sm9_fp2_copy(r[0], r0);
826 	sm9_fp2_copy(r[1], r1);
827 }
828 
sm9_fp4_mul_fp(sm9_fp4_t r,const sm9_fp4_t a,const sm9_fp_t k)829 void sm9_fp4_mul_fp(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp_t k)
830 {
831 	sm9_fp2_mul_fp(r[0], a[0], k);
832 	sm9_fp2_mul_fp(r[1], a[1], k);
833 }
834 
sm9_fp4_mul_fp2(sm9_fp4_t r,const sm9_fp4_t a,const sm9_fp2_t b0)835 void sm9_fp4_mul_fp2(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp2_t b0)
836 {
837 	sm9_fp2_mul(r[0], a[0], b0);
838 	sm9_fp2_mul(r[1], a[1], b0);
839 }
840 
sm9_fp4_mul_v(sm9_fp4_t r,const sm9_fp4_t a,const sm9_fp4_t b)841 void sm9_fp4_mul_v(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b)
842 {
843 	sm9_fp2_t r0, r1, t;
844 
845 	sm9_fp2_mul_u(r0, a[0], b[1]);
846 	sm9_fp2_mul_u(t, a[1], b[0]);
847 	sm9_fp2_add(r0, r0, t);
848 
849 	sm9_fp2_mul(r1, a[0], b[0]);
850 	sm9_fp2_mul_u(t, a[1], b[1]);
851 	sm9_fp2_add(r1, r1, t);
852 
853 	sm9_fp2_copy(r[0], r0);
854 	sm9_fp2_copy(r[1], r1);
855 }
856 
sm9_fp4_sqr(sm9_fp4_t r,const sm9_fp4_t a)857 void sm9_fp4_sqr(sm9_fp4_t r, const sm9_fp4_t a)
858 {
859 	sm9_fp2_t r0, r1, t;
860 
861 	sm9_fp2_sqr(r0, a[0]);
862 	sm9_fp2_sqr_u(t, a[1]);
863 	sm9_fp2_add(r0, r0, t);
864 
865 	sm9_fp2_mul(r1, a[0], a[1]);
866 	sm9_fp2_dbl(r1, r1);
867 	sm9_fp2_copy(r[0], r0);
868 	sm9_fp2_copy(r[1], r1);
869 }
870 
sm9_fp4_sqr_v(sm9_fp4_t r,const sm9_fp4_t a)871 void sm9_fp4_sqr_v(sm9_fp4_t r, const sm9_fp4_t a)
872 {
873 	sm9_fp2_t r0, r1, t;
874 
875 	sm9_fp2_mul_u(t, a[0], a[1]);
876 	sm9_fp2_dbl(r0, t);
877 
878 	sm9_fp2_sqr(r1, a[0]);
879 	sm9_fp2_sqr_u(t, a[1]);
880 	sm9_fp2_add(r1, r1, t);
881 
882 	sm9_fp2_copy(r[0], r0);
883 	sm9_fp2_copy(r[1], r1);
884 }
885 
sm9_fp4_inv(sm9_fp4_t r,const sm9_fp4_t a)886 void sm9_fp4_inv(sm9_fp4_t r, const sm9_fp4_t a)
887 {
888 	sm9_fp2_t r0, r1, k;
889 
890 	sm9_fp2_sqr_u(k, a[1]);
891 	sm9_fp2_sqr(r0, a[0]);
892 	sm9_fp2_sub(k, k, r0);
893 	sm9_fp2_inv(k, k);
894 
895 	sm9_fp2_mul(r0, a[0], k);
896 	sm9_fp2_neg(r0, r0);
897 
898 	sm9_fp2_mul(r1, a[1], k);
899 
900 	sm9_fp2_copy(r[0], r0);
901 	sm9_fp2_copy(r[1], r1);
902 }
903 
sm9_fp12_copy(sm9_fp12_t r,const sm9_fp12_t a)904 void sm9_fp12_copy(sm9_fp12_t r, const sm9_fp12_t a)
905 {
906 	sm9_fp4_copy(r[0], a[0]);
907 	sm9_fp4_copy(r[1], a[1]);
908 	sm9_fp4_copy(r[2], a[2]);
909 }
910 
sm9_fp12_rand(sm9_fp12_t r)911 int sm9_fp12_rand(sm9_fp12_t r)
912 {
913 	if (sm9_fp4_rand(r[0]) != 1
914 		|| sm9_fp4_rand(r[1]) != 1
915 		|| sm9_fp4_rand(r[2]) != 1) {
916 		error_print();
917 		return -1;
918 	}
919 	return 1;
920 }
921 
sm9_fp12_set_zero(sm9_fp12_t r)922 void sm9_fp12_set_zero(sm9_fp12_t r)
923 {
924 	sm9_fp4_set_zero(r[0]);
925 	sm9_fp4_set_zero(r[1]);
926 	sm9_fp4_set_zero(r[2]);
927 }
928 
sm9_fp12_set_one(sm9_fp12_t r)929 void sm9_fp12_set_one(sm9_fp12_t r)
930 {
931 	sm9_fp4_set_one(r[0]);
932 	sm9_fp4_set_zero(r[1]);
933 	sm9_fp4_set_zero(r[2]);
934 }
935 
sm9_fp12_is_one(const sm9_fp12_t a)936 int sm9_fp12_is_one(const sm9_fp12_t a)
937 {
938 	return sm9_fp4_is_one(a[0])
939 		&& sm9_fp4_is_zero(a[1])
940 		&& sm9_fp4_is_zero(a[2]);
941 }
942 
sm9_fp12_is_zero(const sm9_fp12_t a)943 int sm9_fp12_is_zero(const sm9_fp12_t a)
944 {
945 	return sm9_fp4_is_zero(a[0])
946 		&& sm9_fp4_is_zero(a[1])
947 		&& sm9_fp4_is_zero(a[2]);
948 }
949 
sm9_fp12_from_hex(sm9_fp12_t r,const char hex[65* 12-1])950 int sm9_fp12_from_hex(sm9_fp12_t r, const char hex[65 * 12 - 1])
951 {
952 	if (sm9_fp4_from_hex(r[2], hex) != 1
953 		|| hex[65 * 4 - 1] != SM9_HEX_SEP
954 		|| sm9_fp4_from_hex(r[1], hex + 65 * 4) != 1
955 		|| hex[65 * 4 - 1] != SM9_HEX_SEP
956 		|| sm9_fp4_from_hex(r[0], hex + 65 * 8) != 1) {
957 		error_print();
958 		return -1;
959 	}
960 	return 1;
961 }
962 
sm9_fp12_to_hex(const sm9_fp12_t a,char hex[65* 12-1])963 void sm9_fp12_to_hex(const sm9_fp12_t a, char hex[65 * 12 - 1])
964 {
965 	sm9_fp4_to_hex(a[2], hex);
966 	hex[65 * 4 - 1] = SM9_HEX_SEP;
967 	sm9_fp4_to_hex(a[1], hex + 65 * 4);
968 	hex[65 * 8 - 1] = SM9_HEX_SEP;
969 	sm9_fp4_to_hex(a[0], hex + 65 * 8);
970 }
971 
sm9_fp12_print(const char * prefix,const sm9_fp12_t a)972 void sm9_fp12_print(const char *prefix, const sm9_fp12_t a)
973 {
974 	char hex[65 * 12];
975 	sm9_fp12_to_hex(a, hex);
976 	printf("%s\n%s\n", prefix, hex);
977 }
978 
sm9_fp12_set(sm9_fp12_t r,const sm9_fp4_t a0,const sm9_fp4_t a1,const sm9_fp4_t a2)979 void sm9_fp12_set(sm9_fp12_t r, const sm9_fp4_t a0, const sm9_fp4_t a1, const sm9_fp4_t a2)
980 {
981 	sm9_fp4_copy(r[0], a0);
982 	sm9_fp4_copy(r[1], a1);
983 	sm9_fp4_copy(r[2], a2);
984 }
985 
sm9_fp12_set_fp(sm9_fp12_t r,const sm9_fp_t a)986 void sm9_fp12_set_fp(sm9_fp12_t r, const sm9_fp_t a)
987 {
988 	sm9_fp4_set_fp(r[0], a);
989 	sm9_fp4_set_zero(r[1]);
990 	sm9_fp4_set_zero(r[2]);
991 }
992 
sm9_fp12_set_fp2(sm9_fp12_t r,const sm9_fp2_t a)993 void sm9_fp12_set_fp2(sm9_fp12_t r, const sm9_fp2_t a)
994 {
995 	sm9_fp4_set_fp2(r[0], a);
996 	sm9_fp4_set_zero(r[1]);
997 	sm9_fp4_set_zero(r[2]);
998 }
999 
sm9_fp12_set_fp4(sm9_fp12_t r,const sm9_fp4_t a)1000 void sm9_fp12_set_fp4(sm9_fp12_t r, const sm9_fp4_t a)
1001 {
1002 	sm9_fp4_copy(r[0], a);
1003 	sm9_fp4_set_zero(r[1]);
1004 	sm9_fp4_set_zero(r[2]);
1005 }
1006 
sm9_fp12_set_u(sm9_fp12_t r)1007 void sm9_fp12_set_u(sm9_fp12_t r)
1008 {
1009 	sm9_fp4_set_u(r[0]);
1010 	sm9_fp4_set_zero(r[1]);
1011 	sm9_fp4_set_zero(r[2]);
1012 }
1013 
sm9_fp12_set_v(sm9_fp12_t r)1014 void sm9_fp12_set_v(sm9_fp12_t r)
1015 {
1016 	sm9_fp4_set_v(r[0]);
1017 	sm9_fp4_set_zero(r[1]);
1018 	sm9_fp4_set_zero(r[2]);
1019 }
1020 
sm9_fp12_set_w(sm9_fp12_t r)1021 void sm9_fp12_set_w(sm9_fp12_t r)
1022 {
1023 	sm9_fp4_set_zero(r[0]);
1024 	sm9_fp4_set_one(r[1]);
1025 	sm9_fp4_set_zero(r[2]);
1026 }
1027 
sm9_fp12_set_w_sqr(sm9_fp12_t r)1028 void sm9_fp12_set_w_sqr(sm9_fp12_t r)
1029 {
1030 	sm9_fp4_set_zero(r[0]);
1031 	sm9_fp4_set_zero(r[1]);
1032 	sm9_fp4_set_one(r[2]);
1033 }
1034 
sm9_fp12_equ(const sm9_fp12_t a,const sm9_fp12_t b)1035 int sm9_fp12_equ(const sm9_fp12_t a, const sm9_fp12_t b)
1036 {
1037 	return sm9_fp4_equ(a[0], b[0])
1038 		&& sm9_fp4_equ(a[1], b[1])
1039 		&& sm9_fp4_equ(a[2], b[2]);
1040 }
1041 
sm9_fp12_add(sm9_fp12_t r,const sm9_fp12_t a,const sm9_fp12_t b)1042 void sm9_fp12_add(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b)
1043 {
1044 	sm9_fp4_add(r[0], a[0], b[0]);
1045 	sm9_fp4_add(r[1], a[1], b[1]);
1046 	sm9_fp4_add(r[2], a[2], b[2]);
1047 }
1048 
sm9_fp12_dbl(sm9_fp12_t r,const sm9_fp12_t a)1049 void sm9_fp12_dbl(sm9_fp12_t r, const sm9_fp12_t a)
1050 {
1051 	sm9_fp4_dbl(r[0], a[0]);
1052 	sm9_fp4_dbl(r[1], a[1]);
1053 	sm9_fp4_dbl(r[2], a[2]);
1054 }
1055 
sm9_fp12_tri(sm9_fp12_t r,const sm9_fp12_t a)1056 void sm9_fp12_tri(sm9_fp12_t r, const sm9_fp12_t a)
1057 {
1058 	sm9_fp12_t t;
1059 	sm9_fp12_dbl(t, a);
1060 	sm9_fp12_add(r, t, a);
1061 }
1062 
sm9_fp12_sub(sm9_fp12_t r,const sm9_fp12_t a,const sm9_fp12_t b)1063 void sm9_fp12_sub(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b)
1064 {
1065 	sm9_fp4_sub(r[0], a[0], b[0]);
1066 	sm9_fp4_sub(r[1], a[1], b[1]);
1067 	sm9_fp4_sub(r[2], a[2], b[2]);
1068 }
1069 
sm9_fp12_neg(sm9_fp12_t r,const sm9_fp12_t a)1070 void sm9_fp12_neg(sm9_fp12_t r, const sm9_fp12_t a)
1071 {
1072 	sm9_fp4_neg(r[0], a[0]);
1073 	sm9_fp4_neg(r[1], a[1]);
1074 	sm9_fp4_neg(r[2], a[2]);
1075 }
1076 
sm9_fp12_mul(sm9_fp12_t r,const sm9_fp12_t a,const sm9_fp12_t b)1077 void sm9_fp12_mul(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b)
1078 {
1079 	sm9_fp4_t r0, r1, r2, t;
1080 
1081 	sm9_fp4_mul(r0, a[0], b[0]);
1082 	sm9_fp4_mul_v(t, a[1], b[2]);
1083 	sm9_fp4_add(r0, r0, t);
1084 	sm9_fp4_mul_v(t, a[2], b[1]);
1085 	sm9_fp4_add(r0, r0, t);
1086 
1087 	sm9_fp4_mul(r1, a[0], b[1]);
1088 	sm9_fp4_mul(t, a[1], b[0]);
1089 	sm9_fp4_add(r1, r1, t);
1090 	sm9_fp4_mul_v(t, a[2], b[2]);
1091 	sm9_fp4_add(r1, r1, t);
1092 
1093 	sm9_fp4_mul(r2, a[0], b[2]);
1094 	sm9_fp4_mul(t, a[1], b[1]);
1095 	sm9_fp4_add(r2, r2, t);
1096 	sm9_fp4_mul(t, a[2], b[0]);
1097 	sm9_fp4_add(r2, r2, t);
1098 
1099 	sm9_fp4_copy(r[0], r0);
1100 	sm9_fp4_copy(r[1], r1);
1101 	sm9_fp4_copy(r[2], r2);
1102 }
1103 
sm9_fp12_sqr(sm9_fp12_t r,const sm9_fp12_t a)1104 void sm9_fp12_sqr(sm9_fp12_t r, const sm9_fp12_t a)
1105 {
1106 	sm9_fp4_t r0, r1, r2, t;
1107 
1108 	sm9_fp4_sqr(r0, a[0]);
1109 	sm9_fp4_mul_v(t, a[1], a[2]);
1110 	sm9_fp4_dbl(t, t);
1111 	sm9_fp4_add(r0, r0, t);
1112 
1113 	sm9_fp4_mul(r1, a[0], a[1]);
1114 	sm9_fp4_dbl(r1, r1);
1115 	sm9_fp4_sqr_v(t, a[2]);
1116 	sm9_fp4_add(r1, r1, t);
1117 
1118 	sm9_fp4_mul(r2, a[0], a[2]);
1119 	sm9_fp4_dbl(r2, r2);
1120 	sm9_fp4_sqr(t, a[1]);
1121 	sm9_fp4_add(r2, r2, t);
1122 
1123 	sm9_fp4_copy(r[0], r0);
1124 	sm9_fp4_copy(r[1], r1);
1125 	sm9_fp4_copy(r[2], r2);
1126 }
1127 
sm9_fp12_inv(sm9_fp12_t r,const sm9_fp12_t a)1128 void sm9_fp12_inv(sm9_fp12_t r, const sm9_fp12_t a)
1129 {
1130 	if (sm9_fp4_is_zero(a[2])) {
1131 		sm9_fp4_t k, t;
1132 
1133 		sm9_fp4_sqr(k, a[0]);
1134 		sm9_fp4_mul(k, k, a[0]);
1135 		sm9_fp4_sqr_v(t, a[1]);
1136 		sm9_fp4_mul(t, t, a[1]);
1137 		sm9_fp4_add(k, k, t);
1138 		sm9_fp4_inv(k, k);
1139 
1140 		sm9_fp4_sqr(r[2], a[1]);
1141 		sm9_fp4_mul(r[2], r[2], k);
1142 
1143 		sm9_fp4_mul(r[1], a[0], a[1]);
1144 		sm9_fp4_mul(r[1], r[1], k);
1145 		sm9_fp4_neg(r[1], r[1]);
1146 
1147 		sm9_fp4_sqr(r[0], a[0]);
1148 		sm9_fp4_mul(r[0], r[0], k);
1149 
1150 	} else {
1151 		sm9_fp4_t t0, t1, t2, t3;
1152 
1153 		sm9_fp4_sqr(t0, a[1]);
1154 		sm9_fp4_mul(t1, a[0], a[2]);
1155 		sm9_fp4_sub(t0, t0, t1);
1156 
1157 		sm9_fp4_mul(t1, a[0], a[1]);
1158 		sm9_fp4_sqr_v(t2, a[2]);
1159 		sm9_fp4_sub(t1, t1, t2);
1160 
1161 		sm9_fp4_sqr(t2, a[0]);
1162 		sm9_fp4_mul_v(t3, a[1], a[2]);
1163 		sm9_fp4_sub(t2, t2, t3);
1164 
1165 		sm9_fp4_sqr(t3, t1);
1166 		sm9_fp4_mul(r[0], t0, t2);
1167 		sm9_fp4_sub(t3, t3, r[0]);
1168 		sm9_fp4_inv(t3, t3);
1169 		sm9_fp4_mul(t3, a[2], t3);
1170 
1171 		sm9_fp4_mul(r[0], t2, t3);
1172 
1173 		sm9_fp4_mul(r[1], t1, t3);
1174 		sm9_fp4_neg(r[1], r[1]);
1175 
1176 		sm9_fp4_mul(r[2], t0, t3);
1177 	}
1178 }
1179 
sm9_fp12_pow(sm9_fp12_t r,const sm9_fp12_t a,const sm9_bn_t k)1180 void sm9_fp12_pow(sm9_fp12_t r, const sm9_fp12_t a, const sm9_bn_t k)
1181 {
1182 	char kbits[257];
1183 	sm9_fp12_t t;
1184 	int i;
1185 
1186 	assert(sm9_bn_cmp(k, SM9_P_MINUS_ONE) < 0);
1187 	sm9_fp12_set_zero(t);
1188 
1189 	sm9_bn_to_bits(k, kbits);
1190 	sm9_fp12_set_one(t);
1191 	for (i = 0; i < 256; i++) {
1192 		sm9_fp12_sqr(t, t);
1193 		if (kbits[i] == '1') {
1194 			sm9_fp12_mul(t, t, a);
1195 		}
1196 	}
1197 	sm9_fp12_copy(r, t);
1198 }
1199 
sm9_fp2_conjugate(sm9_fp2_t r,const sm9_fp2_t a)1200 void sm9_fp2_conjugate(sm9_fp2_t r, const sm9_fp2_t a)
1201 {
1202 	sm9_fp_copy(r[0], a[0]);
1203 	sm9_fp_neg (r[1], a[1]);
1204 
1205 }
1206 
sm9_fp2_frobenius(sm9_fp2_t r,const sm9_fp2_t a)1207 void sm9_fp2_frobenius(sm9_fp2_t r, const sm9_fp2_t a)
1208 {
1209 	return sm9_fp2_conjugate(r, a);
1210 }
1211 
1212 // beta   = 0x6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011
1213 // alpha1 = 0x3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698b
1214 // alpha2 = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334
1215 // alpha3 = 0x6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011
1216 // alpha4 = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65333
1217 // alpha5 = 0x2d40a38cf6983351711e5f99520347cc57d778a9f8ff4c8a4c949c7fa2a96686
1218 static const sm9_fp2_t SM9_BETA = {{0xda24d011, 0xf5b21fd3, 0x06dc5177, 0x9f9d4118, 0xee0baf15, 0xf55acc93, 0xdc0a3f2c, 0x6c648de5}, {0}};
1219 static const sm9_fp_t SM9_ALPHA1 = {0x377b698b, 0xa91d8354, 0x0ddd04ed, 0x47c5c86e, 0x9c086749, 0x843c6cfa, 0xe5720bdb, 0x3f23ea58};
1220 static const sm9_fp_t SM9_ALPHA2 = {0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235, 0x02a3a6f2, 0xf3000000, 0x0,        0x0       };
1221 static const sm9_fp_t SM9_ALPHA3 = {0xda24d011, 0xf5b21fd3, 0x06dc5177, 0x9f9d4118, 0xee0baf15, 0xf55acc93, 0xdc0a3f2c, 0x6c648de5};
1222 static const sm9_fp_t SM9_ALPHA4 = {0x7be65333, 0xd5fc1196, 0x4f8b78f4, 0x78027235, 0x02a3a6f2, 0xf3000000, 0x0,        0x0       };
1223 static const sm9_fp_t SM9_ALPHA5 = {0xa2a96686, 0x4c949c7f, 0xf8ff4c8a, 0x57d778a9, 0x520347cc, 0x711e5f99, 0xf6983351, 0x2d40a38c};
1224 
1225 
sm9_fp4_frobenius(sm9_fp4_t r,const sm9_fp4_t a)1226 void sm9_fp4_frobenius(sm9_fp4_t r, const sm9_fp4_t a)
1227 {
1228 	sm9_fp2_conjugate(r[0], a[0]);
1229 	sm9_fp2_conjugate(r[1], a[1]);
1230 	sm9_fp2_mul(r[1], r[1], SM9_BETA);
1231 }
1232 
sm9_fp4_conjugate(sm9_fp4_t r,const sm9_fp4_t a)1233 void sm9_fp4_conjugate(sm9_fp4_t r, const sm9_fp4_t a)
1234 {
1235 	sm9_fp2_copy(r[0], a[0]);
1236 	sm9_fp2_neg(r[1], a[1]);
1237 }
1238 
sm9_fp4_frobenius2(sm9_fp4_t r,const sm9_fp4_t a)1239 void sm9_fp4_frobenius2(sm9_fp4_t r, const sm9_fp4_t a)
1240 {
1241 	return sm9_fp4_conjugate(r, a);
1242 }
1243 
sm9_fp4_frobenius3(sm9_fp4_t r,const sm9_fp4_t a)1244 void sm9_fp4_frobenius3(sm9_fp4_t r, const sm9_fp4_t a)
1245 {
1246 	sm9_fp2_conjugate(r[0], a[0]);
1247 	sm9_fp2_conjugate(r[1], a[1]);
1248 	sm9_fp2_mul(r[1], r[1], SM9_BETA);
1249 	sm9_fp2_neg(r[1], r[1]);
1250 }
1251 
sm9_fp12_frobenius(sm9_fp12_t r,const sm9_fp12_t x)1252 void sm9_fp12_frobenius(sm9_fp12_t r, const sm9_fp12_t x)
1253 {
1254 	const sm9_fp2_t *xa = x[0];
1255 	const sm9_fp2_t *xb = x[1];
1256 	const sm9_fp2_t *xc = x[2];
1257 	sm9_fp4_t ra;
1258 	sm9_fp4_t rb;
1259 	sm9_fp4_t rc;
1260 
1261 	sm9_fp2_conjugate(ra[0], xa[0]);
1262 	sm9_fp2_conjugate(ra[1], xa[1]);
1263 	sm9_fp2_mul_fp(ra[1], ra[1], SM9_ALPHA3);
1264 
1265 	sm9_fp2_conjugate(rb[0], xb[0]);
1266 	sm9_fp2_mul_fp(rb[0], rb[0], SM9_ALPHA1);
1267 	sm9_fp2_conjugate(rb[1], xb[1]);
1268 	sm9_fp2_mul_fp(rb[1], rb[1], SM9_ALPHA4);
1269 
1270 	sm9_fp2_conjugate(rc[0], xc[0]);
1271 	sm9_fp2_mul_fp(rc[0], rc[0], SM9_ALPHA2);
1272 	sm9_fp2_conjugate(rc[1], xc[1]);
1273 	sm9_fp2_mul_fp(rc[1], rc[1], SM9_ALPHA5);
1274 
1275 	sm9_fp12_set(r, ra, rb, rc);
1276 }
1277 
sm9_fp12_frobenius2(sm9_fp12_t r,const sm9_fp12_t x)1278 void sm9_fp12_frobenius2(sm9_fp12_t r, const sm9_fp12_t x)
1279 {
1280 	sm9_fp4_t a;
1281 	sm9_fp4_t b;
1282 	sm9_fp4_t c;
1283 
1284 	sm9_fp4_conjugate(a, x[0]);
1285 	sm9_fp4_conjugate(b, x[1]);
1286 	sm9_fp4_mul_fp(b, b, SM9_ALPHA2);
1287 	sm9_fp4_conjugate(c, x[2]);
1288 	sm9_fp4_mul_fp(c, c, SM9_ALPHA4);
1289 
1290 	sm9_fp4_copy(r[0], a);
1291 	sm9_fp4_copy(r[1], b);
1292 	sm9_fp4_copy(r[2], c);
1293 }
1294 
sm9_fp12_frobenius3(sm9_fp12_t r,const sm9_fp12_t x)1295 void sm9_fp12_frobenius3(sm9_fp12_t r, const sm9_fp12_t x)
1296 {
1297 	const sm9_fp2_t *xa = x[0];
1298 	const sm9_fp2_t *xb = x[1];
1299 	const sm9_fp2_t *xc = x[2];
1300 	sm9_fp4_t ra;
1301 	sm9_fp4_t rb;
1302 	sm9_fp4_t rc;
1303 
1304 	sm9_fp2_conjugate(ra[0], xa[0]);
1305 	sm9_fp2_conjugate(ra[1], xa[1]);
1306 	sm9_fp2_mul(ra[1], ra[1], SM9_BETA);
1307 	sm9_fp2_neg(ra[1], ra[1]);
1308 
1309 	sm9_fp2_conjugate(rb[0], xb[0]);
1310 	sm9_fp2_mul(rb[0], rb[0], SM9_BETA);
1311 	sm9_fp2_conjugate(rb[1], xb[1]);
1312 
1313 	sm9_fp2_conjugate(rc[0], xc[0]);
1314 	sm9_fp2_neg(rc[0], rc[0]);
1315 	sm9_fp2_conjugate(rc[1], xc[1]);
1316 	sm9_fp2_mul(rc[1], rc[1], SM9_BETA);
1317 
1318 	sm9_fp4_copy(r[0], ra);
1319 	sm9_fp4_copy(r[1], rb);
1320 	sm9_fp4_copy(r[2], rc);
1321 }
1322 
sm9_fp12_frobenius6(sm9_fp12_t r,const sm9_fp12_t x)1323 void sm9_fp12_frobenius6(sm9_fp12_t r, const sm9_fp12_t x)
1324 {
1325 	sm9_fp4_t a;
1326 	sm9_fp4_t b;
1327 	sm9_fp4_t c;
1328 
1329 	sm9_fp4_copy(a, x[0]);
1330 	sm9_fp4_copy(b, x[1]);
1331 	sm9_fp4_copy(c, x[2]);
1332 
1333 	sm9_fp4_conjugate(a, a);
1334 	sm9_fp4_conjugate(b, b);
1335 	sm9_fp4_neg(b, b);
1336 	sm9_fp4_conjugate(c, c);
1337 
1338 	sm9_fp4_copy(r[0], a);
1339 	sm9_fp4_copy(r[1], b);
1340 	sm9_fp4_copy(r[2], c);
1341 }
1342 
1343 
1344 
sm9_point_from_hex(SM9_POINT * R,const char hex[65* 2])1345 void sm9_point_from_hex(SM9_POINT *R, const char hex[65 * 2])
1346 {
1347 	sm9_bn_from_hex(R->X, hex);
1348 	sm9_bn_from_hex(R->Y, hex + 65);
1349 	sm9_bn_set_one(R->Z);
1350 }
1351 
sm9_point_is_at_infinity(const SM9_POINT * P)1352 int sm9_point_is_at_infinity(const SM9_POINT *P) {
1353 	return sm9_fp_is_zero(P->Z);
1354 }
1355 
sm9_point_set_infinity(SM9_POINT * R)1356 void sm9_point_set_infinity(SM9_POINT *R) {
1357 	sm9_fp_set_one(R->X);
1358 	sm9_fp_set_one(R->Y);
1359 	sm9_fp_set_zero(R->Z);
1360 }
1361 
sm9_point_copy(SM9_POINT * R,const SM9_POINT * P)1362 void sm9_point_copy(SM9_POINT *R, const SM9_POINT *P)
1363 {
1364 	*R = *P;
1365 }
1366 
sm9_point_get_xy(const SM9_POINT * P,sm9_fp_t x,sm9_fp_t y)1367 void sm9_point_get_xy(const SM9_POINT *P, sm9_fp_t x, sm9_fp_t y)
1368 {
1369 	sm9_fp_t z_inv;
1370 
1371 	assert(!sm9_fp_is_zero(P->Z));
1372 
1373 	if (sm9_fp_is_one(P->Z)) {
1374 		sm9_fp_copy(x, P->X);
1375 		sm9_fp_copy(y, P->Y);
1376 	}
1377 
1378 	sm9_fp_inv(z_inv, P->Z);
1379 	if (y)
1380 		sm9_fp_mul(y, P->Y, z_inv);
1381 	sm9_fp_sqr(z_inv, z_inv);
1382 	sm9_fp_mul(x, P->X, z_inv);
1383 	if (y)
1384 		sm9_fp_mul(y, y, z_inv);
1385 }
1386 
sm9_point_equ(const SM9_POINT * P,const SM9_POINT * Q)1387 int sm9_point_equ(const SM9_POINT *P, const SM9_POINT *Q)
1388 {
1389 	sm9_fp_t t1, t2, t3, t4;
1390 	sm9_fp_sqr(t1, P->Z);
1391 	sm9_fp_sqr(t2, Q->Z);
1392 	sm9_fp_mul(t3, P->X, t2);
1393 	sm9_fp_mul(t4, Q->X, t1);
1394 	if (!sm9_fp_equ(t3, t4)) {
1395 		return 0;
1396 	}
1397 	sm9_fp_mul(t1, t1, P->Z);
1398 	sm9_fp_mul(t2, t2, Q->Z);
1399 	sm9_fp_mul(t3, P->Y, t2);
1400 	sm9_fp_mul(t4, Q->Y, t1);
1401 	return sm9_fp_equ(t3, t4);
1402 }
1403 
sm9_point_is_on_curve(const SM9_POINT * P)1404 int sm9_point_is_on_curve(const SM9_POINT *P)
1405 {
1406 	sm9_fp_t t0, t1, t2;
1407 	if (sm9_fp_is_one(P->Z)) {
1408 		sm9_fp_sqr(t0, P->Y);
1409 		sm9_fp_sqr(t1, P->X);
1410 		sm9_fp_mul(t1, t1, P->X);
1411 		sm9_fp_add(t1, t1, SM9_FIVE);
1412 	} else {
1413 		sm9_fp_sqr(t0, P->X);
1414 		sm9_fp_mul(t0, t0, P->X);
1415 		sm9_fp_sqr(t1, P->Z);
1416 		sm9_fp_sqr(t2, t1);
1417 		sm9_fp_mul(t1, t1, t2);
1418 		sm9_fp_mul(t1, t1, SM9_FIVE);
1419 		sm9_fp_add(t1, t0, t1);
1420 		sm9_fp_sqr(t0, P->Y);
1421 	}
1422 	if (sm9_fp_equ(t0, t1) != 1) {
1423 		error_print();
1424 		return 0;
1425 	}
1426 	return 1;
1427 }
1428 
sm9_point_dbl(SM9_POINT * R,const SM9_POINT * P)1429 void sm9_point_dbl(SM9_POINT *R, const SM9_POINT *P)
1430 {
1431 	const uint64_t *X1 = P->X;
1432 	const uint64_t *Y1 = P->Y;
1433 	const uint64_t *Z1 = P->Z;
1434 	sm9_fp_t X3, Y3, Z3, T1, T2, T3;
1435 
1436 	if (sm9_point_is_at_infinity(P)) {
1437 		sm9_point_copy(R, P);
1438 		return;
1439 	}
1440 
1441 	sm9_fp_sqr(T2, X1);
1442 	sm9_fp_tri(T2, T2);
1443 	sm9_fp_dbl(Y3, Y1);
1444 	sm9_fp_mul(Z3, Y3, Z1);
1445 	sm9_fp_sqr(Y3, Y3);
1446 	sm9_fp_mul(T3, Y3, X1);
1447 	sm9_fp_sqr(Y3, Y3);
1448 	sm9_fp_div2(Y3, Y3);
1449 	sm9_fp_sqr(X3, T2);
1450 	sm9_fp_dbl(T1, T3);
1451 	sm9_fp_sub(X3, X3, T1);
1452 	sm9_fp_sub(T1, T3, X3);
1453 	sm9_fp_mul(T1, T1, T2);
1454 	sm9_fp_sub(Y3, T1, Y3);
1455 
1456 	sm9_fp_copy(R->X, X3);
1457 	sm9_fp_copy(R->Y, Y3);
1458 	sm9_fp_copy(R->Z, Z3);
1459 }
1460 
sm9_point_add(SM9_POINT * R,const SM9_POINT * P,const SM9_POINT * Q)1461 void sm9_point_add(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q)
1462 {
1463 	sm9_fp_t x;
1464 	sm9_fp_t y;
1465 	sm9_point_get_xy(Q, x, y);
1466 
1467 	const uint64_t *X1 = P->X;
1468 	const uint64_t *Y1 = P->Y;
1469 	const uint64_t *Z1 = P->Z;
1470 	const uint64_t *x2 = x;
1471 	const uint64_t *y2 = y;
1472 	sm9_fp_t X3, Y3, Z3, T1, T2, T3, T4;
1473 
1474 	if (sm9_point_is_at_infinity(Q)) {
1475 		sm9_point_copy(R, P);
1476 		return;
1477 	}
1478 	if (sm9_point_is_at_infinity(P)) {
1479 		sm9_point_copy(R, Q);
1480 		return;
1481 	}
1482 
1483 	sm9_fp_sqr(T1, Z1);
1484 	sm9_fp_mul(T2, T1, Z1);
1485 	sm9_fp_mul(T1, T1, x2);
1486 	sm9_fp_mul(T2, T2, y2);
1487 	sm9_fp_sub(T1, T1, X1);
1488 	sm9_fp_sub(T2, T2, Y1);
1489 
1490 	if (sm9_fp_is_zero(T1)) {
1491 		if (sm9_fp_is_zero(T2)) {
1492 			sm9_point_dbl(R, Q);
1493 			return;
1494 		} else {
1495 			sm9_point_set_infinity(R);
1496 			return;
1497 		}
1498 	}
1499 
1500 	sm9_fp_mul(Z3, Z1, T1);
1501 	sm9_fp_sqr(T3, T1);
1502 	sm9_fp_mul(T4, T3, T1);
1503 	sm9_fp_mul(T3, T3, X1);
1504 	sm9_fp_dbl(T1, T3);
1505 	sm9_fp_sqr(X3, T2);
1506 	sm9_fp_sub(X3, X3, T1);
1507 	sm9_fp_sub(X3, X3, T4);
1508 	sm9_fp_sub(T3, T3, X3);
1509 	sm9_fp_mul(T3, T3, T2);
1510 	sm9_fp_mul(T4, T4, Y1);
1511 	sm9_fp_sub(Y3, T3, T4);
1512 
1513 	sm9_fp_copy(R->X, X3);
1514 	sm9_fp_copy(R->Y, Y3);
1515 	sm9_fp_copy(R->Z, Z3);
1516 }
1517 
sm9_point_neg(SM9_POINT * R,const SM9_POINT * P)1518 void sm9_point_neg(SM9_POINT *R, const SM9_POINT *P)
1519 {
1520 	sm9_fp_copy(R->X, P->X);
1521 	sm9_fp_neg(R->Y, P->Y);
1522 	sm9_fp_copy(R->Z, P->Z);
1523 }
1524 
sm9_point_sub(SM9_POINT * R,const SM9_POINT * P,const SM9_POINT * Q)1525 void sm9_point_sub(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q)
1526 {
1527 	SM9_POINT _T, *T = &_T;
1528 	sm9_point_neg(T, Q);
1529 	sm9_point_add(R, P, T);
1530 }
1531 
sm9_point_mul(SM9_POINT * R,const sm9_bn_t k,const SM9_POINT * P)1532 void sm9_point_mul(SM9_POINT *R, const sm9_bn_t k, const SM9_POINT *P)
1533 {
1534 	char kbits[257];
1535 	SM9_POINT _Q, *Q = &_Q;
1536 	int i;
1537 
1538 	sm9_bn_to_bits(k, kbits);
1539 	sm9_point_set_infinity(Q);
1540 	for (i = 0; i < 256; i++) {
1541 		sm9_point_dbl(Q, Q);
1542 		if (kbits[i] == '1') {
1543 			sm9_point_add(Q, Q, P);
1544 		}
1545 	}
1546 	sm9_point_copy(R, Q);
1547 }
1548 
sm9_point_mul_generator(SM9_POINT * R,const sm9_bn_t k)1549 void sm9_point_mul_generator(SM9_POINT *R, const sm9_bn_t k)
1550 {
1551 	sm9_point_mul(R, k, SM9_P1);
1552 }
1553 
1554 
sm9_point_print(FILE * fp,int fmt,int ind,const char * label,const SM9_POINT * P)1555 int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_POINT *P)
1556 {
1557 	uint8_t buf[65];
1558 	sm9_point_to_uncompressed_octets(P, buf);
1559 	format_bytes(fp, fmt, ind, label, buf, sizeof(buf));
1560 	return 1;
1561 }
1562 
sm9_twist_point_print(FILE * fp,int fmt,int ind,const char * label,const SM9_TWIST_POINT * P)1563 int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_TWIST_POINT *P)
1564 {
1565 	uint8_t buf[129];
1566 	sm9_twist_point_to_uncompressed_octets(P, buf);
1567 	format_bytes(fp, fmt, ind, label, buf, sizeof(buf));
1568 	return 1;
1569 }
1570 
sm9_twist_point_from_hex(SM9_TWIST_POINT * R,const char hex[65* 4])1571 void sm9_twist_point_from_hex(SM9_TWIST_POINT *R, const char hex[65 * 4])
1572 {
1573 	sm9_fp2_from_hex(R->X, hex);
1574 	sm9_fp2_from_hex(R->Y, hex + 65 * 2);
1575 	sm9_fp2_set_one(R->Z);
1576 }
1577 
sm9_twist_point_is_at_infinity(const SM9_TWIST_POINT * P)1578 int sm9_twist_point_is_at_infinity(const SM9_TWIST_POINT *P)
1579 {
1580 	return sm9_fp2_is_zero(P->Z);
1581 }
1582 
sm9_twist_point_set_infinity(SM9_TWIST_POINT * R)1583 void sm9_twist_point_set_infinity(SM9_TWIST_POINT *R)
1584 {
1585 	sm9_fp2_set_one(R->X);
1586 	sm9_fp2_set_one(R->Y);
1587 	sm9_fp2_set_zero(R->Z);
1588 }
1589 
sm9_twist_point_get_xy(const SM9_TWIST_POINT * P,sm9_fp2_t x,sm9_fp2_t y)1590 void sm9_twist_point_get_xy(const SM9_TWIST_POINT *P, sm9_fp2_t x, sm9_fp2_t y)
1591 {
1592 	sm9_fp2_t z_inv;
1593 
1594 	assert(!sm9_fp2_is_zero(P->Z));
1595 
1596 	if (sm9_fp2_is_one(P->Z)) {
1597 		sm9_fp2_copy(x, P->X);
1598 		sm9_fp2_copy(y, P->Y);
1599 	}
1600 
1601 	sm9_fp2_inv(z_inv, P->Z);
1602 	if (y)
1603 		sm9_fp2_mul(y, P->Y, z_inv);
1604 	sm9_fp2_sqr(z_inv, z_inv);
1605 	sm9_fp2_mul(x, P->X, z_inv);
1606 	if (y)
1607 		sm9_fp2_mul(y, y, z_inv);
1608 }
1609 
1610 
sm9_twist_point_equ(const SM9_TWIST_POINT * P,const SM9_TWIST_POINT * Q)1611 int sm9_twist_point_equ(const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q)
1612 {
1613 	sm9_fp2_t t1, t2, t3, t4;
1614 
1615 	sm9_fp2_sqr(t1, P->Z);
1616 	sm9_fp2_sqr(t2, Q->Z);
1617 	sm9_fp2_mul(t3, P->X, t2);
1618 	sm9_fp2_mul(t4, Q->X, t1);
1619 	if (!sm9_fp2_equ(t3, t4)) {
1620 		return 0;
1621 	}
1622 	sm9_fp2_mul(t1, t1, P->Z);
1623 	sm9_fp2_mul(t2, t2, Q->Z);
1624 	sm9_fp2_mul(t3, P->Y, t2);
1625 	sm9_fp2_mul(t4, Q->Y, t1);
1626 	return sm9_fp2_equ(t3, t4);
1627 }
1628 
sm9_twist_point_is_on_curve(const SM9_TWIST_POINT * P)1629 int sm9_twist_point_is_on_curve(const SM9_TWIST_POINT *P)
1630 {
1631 	sm9_fp2_t t0, t1, t2;
1632 
1633 	if (sm9_fp2_is_one(P->Z)) {
1634 		sm9_fp2_sqr(t0, P->Y);
1635 		sm9_fp2_sqr(t1, P->X);
1636 		sm9_fp2_mul(t1, t1, P->X);
1637 		sm9_fp2_add(t1, t1, SM9_FP2_5U);
1638 
1639 	} else {
1640 		sm9_fp2_sqr(t0, P->X);
1641 		sm9_fp2_mul(t0, t0, P->X);
1642 		sm9_fp2_sqr(t1, P->Z);
1643 		sm9_fp2_sqr(t2, t1);
1644 		sm9_fp2_mul(t1, t1, t2);
1645 		sm9_fp2_mul(t1, t1, SM9_FP2_5U);
1646 		sm9_fp2_add(t1, t0, t1);
1647 		sm9_fp2_sqr(t0, P->Y);
1648 	}
1649 
1650 	return sm9_fp2_equ(t0, t1);
1651 }
1652 
sm9_twist_point_neg(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P)1653 void sm9_twist_point_neg(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P)
1654 {
1655 	sm9_fp2_copy(R->X, P->X);
1656 	sm9_fp2_neg(R->Y, P->Y);
1657 	sm9_fp2_copy(R->Z, P->Z);
1658 }
1659 
sm9_twist_point_dbl(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P)1660 void sm9_twist_point_dbl(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P)
1661 {
1662 	const sm9_fp_t *X1 = P->X;
1663 	const sm9_fp_t *Y1 = P->Y;
1664 	const sm9_fp_t *Z1 = P->Z;
1665 	sm9_fp2_t X3, Y3, Z3, T1, T2, T3;
1666 
1667 	if (sm9_twist_point_is_at_infinity(P)) {
1668 		sm9_twist_point_copy(R, P);
1669 		return;
1670 	}
1671 	sm9_fp2_sqr(T2, X1);
1672 	sm9_fp2_tri(T2, T2);
1673 	sm9_fp2_dbl(Y3, Y1);
1674 	sm9_fp2_mul(Z3, Y3, Z1);
1675 	sm9_fp2_sqr(Y3, Y3);
1676 	sm9_fp2_mul(T3, Y3, X1);
1677 	sm9_fp2_sqr(Y3, Y3);
1678 	sm9_fp2_div2(Y3, Y3);
1679 	sm9_fp2_sqr(X3, T2);
1680 	sm9_fp2_dbl(T1, T3);
1681 	sm9_fp2_sub(X3, X3, T1);
1682 	sm9_fp2_sub(T1, T3, X3);
1683 	sm9_fp2_mul(T1, T1, T2);
1684 	sm9_fp2_sub(Y3, T1, Y3);
1685 
1686 	sm9_fp2_copy(R->X, X3);
1687 	sm9_fp2_copy(R->Y, Y3);
1688 	sm9_fp2_copy(R->Z, Z3);
1689 }
1690 
sm9_twist_point_add(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P,const SM9_TWIST_POINT * Q)1691 void sm9_twist_point_add(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q)
1692 {
1693 	const sm9_fp_t *X1 = P->X;
1694 	const sm9_fp_t *Y1 = P->Y;
1695 	const sm9_fp_t *Z1 = P->Z;
1696 	const sm9_fp_t *x2 = Q->X;
1697 	const sm9_fp_t *y2 = Q->Y;
1698 	sm9_fp2_t X3, Y3, Z3, T1, T2, T3, T4;
1699 
1700 	if (sm9_twist_point_is_at_infinity(Q)) {
1701 		sm9_twist_point_copy(R, P);
1702 		return;
1703 	}
1704 	if (sm9_twist_point_is_at_infinity(P)) {
1705 		sm9_twist_point_copy(R, Q);
1706 		return;
1707 	}
1708 
1709 	sm9_fp2_sqr(T1, Z1);
1710 	sm9_fp2_mul(T2, T1, Z1);
1711 	sm9_fp2_mul(T1, T1, x2);
1712 	sm9_fp2_mul(T2, T2, y2);
1713 	sm9_fp2_sub(T1, T1, X1);
1714 	sm9_fp2_sub(T2, T2, Y1);
1715 	if (sm9_fp2_is_zero(T1)) {
1716 		if (sm9_fp2_is_zero(T2)) {
1717 			sm9_twist_point_dbl(R, Q);
1718 			return;
1719 		} else {
1720 			sm9_twist_point_set_infinity(R);
1721 			return;
1722 		}
1723 	}
1724 	sm9_fp2_mul(Z3, Z1, T1);
1725 	sm9_fp2_sqr(T3, T1);
1726 	sm9_fp2_mul(T4, T3, T1);
1727 	sm9_fp2_mul(T3, T3, X1);
1728 	sm9_fp2_dbl(T1, T3);
1729 	sm9_fp2_sqr(X3, T2);
1730 	sm9_fp2_sub(X3, X3, T1);
1731 	sm9_fp2_sub(X3, X3, T4);
1732 	sm9_fp2_sub(T3, T3, X3);
1733 	sm9_fp2_mul(T3, T3, T2);
1734 	sm9_fp2_mul(T4, T4, Y1);
1735 	sm9_fp2_sub(Y3, T3, T4);
1736 
1737 	sm9_fp2_copy(R->X, X3);
1738 	sm9_fp2_copy(R->Y, Y3);
1739 	sm9_fp2_copy(R->Z, Z3);
1740 }
1741 
sm9_twist_point_sub(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P,const SM9_TWIST_POINT * Q)1742 void sm9_twist_point_sub(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q)
1743 {
1744 	SM9_TWIST_POINT _T, *T = &_T;
1745 	sm9_twist_point_neg(T, Q);
1746 	sm9_twist_point_add_full(R, P, T);
1747 }
1748 
sm9_twist_point_add_full(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P,const SM9_TWIST_POINT * Q)1749 void sm9_twist_point_add_full(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q)
1750 {
1751 	const sm9_fp_t *X1 = P->X;
1752 	const sm9_fp_t *Y1 = P->Y;
1753 	const sm9_fp_t *Z1 = P->Z;
1754 	const sm9_fp_t *X2 = Q->X;
1755 	const sm9_fp_t *Y2 = Q->Y;
1756 	const sm9_fp_t *Z2 = Q->Z;
1757 	sm9_fp2_t T1, T2, T3, T4, T5, T6, T7, T8;
1758 
1759 	if (sm9_twist_point_is_at_infinity(Q)) {
1760 		sm9_twist_point_copy(R, P);
1761 		return;
1762 	}
1763 	if (sm9_twist_point_is_at_infinity(P)) {
1764 		sm9_twist_point_copy(R, Q);
1765 		return;
1766 	}
1767 
1768 	sm9_fp2_sqr(T1, Z1);
1769 	sm9_fp2_sqr(T2, Z2);
1770 	sm9_fp2_mul(T3, X2, T1);
1771 	sm9_fp2_mul(T4, X1, T2);
1772 	sm9_fp2_add(T5, T3, T4);
1773 	sm9_fp2_sub(T3, T3, T4);
1774 	sm9_fp2_mul(T1, T1, Z1);
1775 	sm9_fp2_mul(T1, T1, Y2);
1776 	sm9_fp2_mul(T2, T2, Z2);
1777 	sm9_fp2_mul(T2, T2, Y1);
1778 	sm9_fp2_add(T6, T1, T2);
1779 	sm9_fp2_sub(T1, T1, T2);
1780 
1781 	if (sm9_fp2_is_zero(T1) && sm9_fp2_is_zero(T3)) {
1782 		return sm9_twist_point_dbl(R, P);
1783 	}
1784 	if (sm9_fp2_is_zero(T1) && sm9_fp2_is_zero(T6)) {
1785 		return sm9_twist_point_set_infinity(R);
1786 	}
1787 
1788 	sm9_fp2_sqr(T6, T1);
1789 	sm9_fp2_mul(T7, T3, Z1);
1790 	sm9_fp2_mul(T7, T7, Z2);
1791 	sm9_fp2_sqr(T8, T3);
1792 	sm9_fp2_mul(T5, T5, T8);
1793 	sm9_fp2_mul(T3, T3, T8);
1794 	sm9_fp2_mul(T4, T4, T8);
1795 	sm9_fp2_sub(T6, T6, T5);
1796 	sm9_fp2_sub(T4, T4, T6);
1797 	sm9_fp2_mul(T1, T1, T4);
1798 	sm9_fp2_mul(T2, T2, T3);
1799 	sm9_fp2_sub(T1, T1, T2);
1800 
1801 	sm9_fp2_copy(R->X, T6);
1802 	sm9_fp2_copy(R->Y, T1);
1803 	sm9_fp2_copy(R->Z, T7);
1804 }
1805 
sm9_twist_point_mul(SM9_TWIST_POINT * R,const sm9_bn_t k,const SM9_TWIST_POINT * P)1806 void sm9_twist_point_mul(SM9_TWIST_POINT *R, const sm9_bn_t k, const SM9_TWIST_POINT *P)
1807 {
1808 	SM9_TWIST_POINT _Q, *Q = &_Q;
1809 	char kbits[256];
1810 	int i;
1811 
1812 	sm9_bn_to_bits(k, kbits);
1813 	sm9_twist_point_set_infinity(Q);
1814 	for (i = 0; i < 256; i++) {
1815 		sm9_twist_point_dbl(Q, Q);
1816 		if (kbits[i] == '1') {
1817 			sm9_twist_point_add_full(Q, Q, P);
1818 		}
1819 	}
1820 	sm9_twist_point_copy(R, Q);
1821 }
1822 
sm9_twist_point_mul_generator(SM9_TWIST_POINT * R,const sm9_bn_t k)1823 void sm9_twist_point_mul_generator(SM9_TWIST_POINT *R, const sm9_bn_t k)
1824 {
1825 	sm9_twist_point_mul(R, k, SM9_P2);
1826 }
1827 
sm9_eval_g_tangent(sm9_fp12_t num,sm9_fp12_t den,const SM9_TWIST_POINT * P,const SM9_POINT * Q)1828 void sm9_eval_g_tangent(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *P, const SM9_POINT *Q)
1829 {
1830 	sm9_fp_t x;
1831 	sm9_fp_t y;
1832 	sm9_point_get_xy(Q, x, y);
1833 
1834 	const sm9_fp_t *XP = P->X;
1835 	const sm9_fp_t *YP = P->Y;
1836 	const sm9_fp_t *ZP = P->Z;
1837 	const uint64_t *xQ = x;
1838 	const uint64_t *yQ = y;
1839 
1840 	sm9_fp_t *a0 = num[0][0];
1841 	sm9_fp_t *a1 = num[0][1];
1842 	sm9_fp_t *a4 = num[2][0];
1843 	sm9_fp_t *b1 = den[0][1];
1844 
1845 	sm9_fp2_t t0;
1846 	sm9_fp2_t t1;
1847 	sm9_fp2_t t2;
1848 
1849 
1850 	sm9_fp12_set_zero(num);
1851 	sm9_fp12_set_zero(den);
1852 
1853 	sm9_fp2_sqr(t0, ZP);
1854 	sm9_fp2_mul(t1, t0, ZP);
1855 	sm9_fp2_mul(b1, t1, YP);
1856 
1857 	sm9_fp2_mul_fp(t2, b1, yQ);
1858 	sm9_fp2_neg(a1, t2);
1859 
1860 	sm9_fp2_sqr(t1, XP);
1861 	sm9_fp2_mul(t0, t0, t1);
1862 	sm9_fp2_mul_fp(t0, t0, xQ);
1863 	sm9_fp2_tri(t0, t0);
1864 	sm9_fp2_div2(a4, t0);
1865 
1866 	sm9_fp2_mul(t1, t1, XP);
1867 	sm9_fp2_tri(t1, t1);
1868 	sm9_fp2_div2(t1, t1);
1869 	sm9_fp2_sqr(t0, YP);
1870 	sm9_fp2_sub(a0, t0, t1);
1871 }
1872 
sm9_eval_g_line(sm9_fp12_t num,sm9_fp12_t den,const SM9_TWIST_POINT * T,const SM9_TWIST_POINT * P,const SM9_POINT * Q)1873 void sm9_eval_g_line(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *T, const SM9_TWIST_POINT *P, const SM9_POINT *Q)
1874 {
1875 	sm9_fp_t x;
1876 	sm9_fp_t y;
1877 	sm9_point_get_xy(Q, x, y);
1878 
1879 	const sm9_fp_t *XT = T->X;
1880 	const sm9_fp_t *YT = T->Y;
1881 	const sm9_fp_t *ZT = T->Z;
1882 	const sm9_fp_t *XP = P->X;
1883 	const sm9_fp_t *YP = P->Y;
1884 	const sm9_fp_t *ZP = P->Z;
1885 	const uint64_t *xQ = x;
1886 	const uint64_t *yQ = y;
1887 
1888 	sm9_fp_t *a0 = num[0][0];
1889 	sm9_fp_t *a1 = num[0][1];
1890 	sm9_fp_t *a4 = num[2][0];
1891 	sm9_fp_t *b1 = den[0][1];
1892 
1893 	sm9_fp2_t T0, T1, T2, T3, T4;
1894 
1895 
1896 	sm9_fp12_set_zero(num);
1897 	sm9_fp12_set_zero(den);
1898 
1899 	sm9_fp2_sqr(T0, ZP);
1900 	sm9_fp2_mul(T1, T0, XT);
1901 	sm9_fp2_mul(T0, T0, ZP);
1902 	sm9_fp2_sqr(T2, ZT);
1903 	sm9_fp2_mul(T3, T2, XP);
1904 	sm9_fp2_mul(T2, T2, ZT);
1905 	sm9_fp2_mul(T2, T2, YP);
1906 	sm9_fp2_sub(T1, T1, T3);
1907 	sm9_fp2_mul(T1, T1, ZT);
1908 	sm9_fp2_mul(T1, T1, ZP);
1909 	sm9_fp2_mul(T4, T1, T0);
1910 	sm9_fp2_copy(b1, T4);
1911 	sm9_fp2_mul(T1, T1, YP);
1912 	sm9_fp2_mul(T3, T0, YT);
1913 	sm9_fp2_sub(T3, T3, T2);
1914 	sm9_fp2_mul(T0, T0, T3);
1915 	sm9_fp2_mul_fp(T0, T0, xQ);
1916 	sm9_fp2_copy(a4, T0);
1917 	sm9_fp2_mul(T3, T3, XP);
1918 	sm9_fp2_mul(T3, T3, ZP);
1919 	sm9_fp2_sub(T1, T1, T3);
1920 	sm9_fp2_copy(a0, T1);
1921 	sm9_fp2_mul_fp(T2, T4, yQ);
1922 	sm9_fp2_neg(T2, T2);
1923 	sm9_fp2_copy(a1, T2);
1924 }
1925 
sm9_twist_point_pi1(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P)1926 void sm9_twist_point_pi1(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P)
1927 {
1928 	//const c = 0x3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698bn;
1929 	const sm9_fp_t c = {
1930 		0x377b698b, 0xa91d8354, 0x0ddd04ed, 0x47c5c86e,
1931 		0x9c086749, 0x843c6cfa, 0xe5720bdb, 0x3f23ea58,
1932 	};
1933 	sm9_fp2_conjugate(R->X, P->X);
1934 	sm9_fp2_conjugate(R->Y, P->Y);
1935 	sm9_fp2_conjugate(R->Z, P->Z);
1936 	sm9_fp2_mul_fp(R->Z, R->Z, c);
1937 
1938 }
1939 
sm9_twist_point_pi2(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P)1940 void sm9_twist_point_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P)
1941 {
1942 	//c = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334
1943 	const sm9_fp_t c = {
1944 		0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235,
1945 		0x02a3a6f2, 0xf3000000, 0, 0,
1946 	};
1947 	sm9_fp2_copy(R->X, P->X);
1948 	sm9_fp2_copy(R->Y, P->Y);
1949 	sm9_fp2_mul_fp(R->Z, P->Z, c);
1950 }
1951 
sm9_twist_point_neg_pi2(SM9_TWIST_POINT * R,const SM9_TWIST_POINT * P)1952 void sm9_twist_point_neg_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P)
1953 {
1954 	// c = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334
1955 	const sm9_fp_t c = {
1956 		0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235,
1957 		0x02a3a6f2, 0xf3000000, 0, 0,
1958 	};
1959 	sm9_fp2_copy(R->X, P->X);
1960 	sm9_fp2_neg(R->Y, P->Y);
1961 	sm9_fp2_mul_fp(R->Z, P->Z, c);
1962 }
1963 
1964 
sm9_final_exponent_hard_part(sm9_fp12_t r,const sm9_fp12_t f)1965 void sm9_final_exponent_hard_part(sm9_fp12_t r, const sm9_fp12_t f)
1966 {
1967 	// a2 = 0xd8000000019062ed0000b98b0cb27659
1968 	// a3 = 0x2400000000215d941
1969 	const sm9_bn_t a2 = {0xcb27659, 0x0000b98b, 0x019062ed, 0xd8000000, 0, 0, 0, 0};
1970 	const sm9_bn_t a3 = {0x215d941, 0x40000000, 0x2, 0, 0, 0, 0, 0};
1971 	const sm9_bn_t nine = {9,0,0,0,0,0,0,0};
1972 	sm9_fp12_t t0, t1, t2, t3;
1973 
1974 	sm9_fp12_pow(t0, f, a3);
1975 	sm9_fp12_inv(t0, t0);
1976 	sm9_fp12_frobenius(t1, t0);
1977 	sm9_fp12_mul(t1, t0, t1);
1978 
1979 	sm9_fp12_mul(t0, t0, t1);
1980 	sm9_fp12_frobenius(t2, f);
1981 	sm9_fp12_mul(t3, t2, f);
1982 	sm9_fp12_pow(t3, t3, nine);
1983 
1984 	sm9_fp12_mul(t0, t0, t3);
1985 	sm9_fp12_sqr(t3, f);
1986 	sm9_fp12_sqr(t3, t3);
1987 	sm9_fp12_mul(t0, t0, t3);
1988 	sm9_fp12_sqr(t2, t2);
1989 	sm9_fp12_mul(t2, t2, t1);
1990 	sm9_fp12_frobenius2(t1, f);
1991 	sm9_fp12_mul(t1, t1, t2);
1992 
1993 	sm9_fp12_pow(t2, t1, a2);
1994 	sm9_fp12_mul(t0, t2, t0);
1995 	sm9_fp12_frobenius3(t1, f);
1996 	sm9_fp12_mul(t1, t1, t0);
1997 
1998 	sm9_fp12_copy(r, t1);
1999 }
2000 
sm9_final_exponent(sm9_fp12_t r,const sm9_fp12_t f)2001 void sm9_final_exponent(sm9_fp12_t r, const sm9_fp12_t f)
2002 {
2003 	sm9_fp12_t t0;
2004 	sm9_fp12_t t1;
2005 
2006 	sm9_fp12_frobenius6(t0, f);
2007 	sm9_fp12_inv(t1, f);
2008 	sm9_fp12_mul(t0, t0, t1);
2009 	sm9_fp12_frobenius2(t1, t0);
2010 	sm9_fp12_mul(t0, t0, t1);
2011 	sm9_final_exponent_hard_part(t0, t0);
2012 
2013 	sm9_fp12_copy(r, t0);
2014 }
2015 
sm9_pairing(sm9_fp12_t r,const SM9_TWIST_POINT * Q,const SM9_POINT * P)2016 void sm9_pairing(sm9_fp12_t r, const SM9_TWIST_POINT *Q, const SM9_POINT *P) {
2017 	const char *abits = "00100000000000000000000000000000000000010000101011101100100111110";
2018 
2019 	SM9_TWIST_POINT _T, *T = &_T;
2020 	SM9_TWIST_POINT _Q1, *Q1 = &_Q1;
2021 	SM9_TWIST_POINT _Q2, *Q2 = &_Q2;
2022 
2023 	sm9_fp12_t f_num;
2024 	sm9_fp12_t f_den;
2025 	sm9_fp12_t g_num;
2026 	sm9_fp12_t g_den;
2027 	int i;
2028 
2029 	sm9_twist_point_copy(T, Q);
2030 
2031 	sm9_fp12_set_one(f_num);
2032 	sm9_fp12_set_one(f_den);
2033 
2034 	for (i = 0; i < strlen(abits); i++) {
2035 
2036 		sm9_fp12_sqr(f_num, f_num);
2037 		sm9_fp12_sqr(f_den, f_den);
2038 		sm9_eval_g_tangent(g_num, g_den, T, P);
2039 		sm9_fp12_mul(f_num, f_num, g_num);
2040 		sm9_fp12_mul(f_den, f_den, g_den);
2041 
2042 		sm9_twist_point_dbl(T, T);
2043 
2044 		if (abits[i] == '1') {
2045 			sm9_eval_g_line(g_num, g_den, T, Q, P);
2046 			sm9_fp12_mul(f_num, f_num, g_num);
2047 			sm9_fp12_mul(f_den, f_den, g_den);
2048 			sm9_twist_point_add_full(T, T, Q);
2049 		}
2050 	}
2051 
2052 	sm9_twist_point_pi1(Q1, Q);
2053 	sm9_twist_point_neg_pi2(Q2, Q);
2054 
2055 	sm9_eval_g_line(g_num, g_den, T, Q1, P);
2056 	sm9_fp12_mul(f_num, f_num, g_num);
2057 	sm9_fp12_mul(f_den, f_den, g_den);
2058 	sm9_twist_point_add_full(T, T, Q1);
2059 
2060 	sm9_eval_g_line(g_num, g_den, T, Q2, P);
2061 	sm9_fp12_mul(f_num, f_num, g_num);
2062 	sm9_fp12_mul(f_den, f_den, g_den);
2063 	sm9_twist_point_add_full(T, T, Q2);
2064 
2065 	sm9_fp12_inv(f_den, f_den);
2066 	sm9_fp12_mul(r, f_num, f_den);
2067 
2068 	sm9_final_exponent(r, r);
2069 }
2070 
sm9_fn_add(sm9_fn_t r,const sm9_fn_t a,const sm9_fn_t b)2071 void sm9_fn_add(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b)
2072 {
2073 	sm9_bn_add(r, a, b);
2074 	if (sm9_bn_cmp(r, SM9_N) >= 0)
2075 		return sm9_bn_sub(r, r, SM9_N);
2076 }
2077 
sm9_fn_sub(sm9_fn_t r,const sm9_fn_t a,const sm9_fn_t b)2078 void sm9_fn_sub(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b)
2079 {
2080 	if (sm9_bn_cmp(a, b) >= 0) {
2081 		sm9_bn_sub(r, a, b);
2082 	} else {
2083 		sm9_bn_t t;
2084 		sm9_bn_sub(t, SM9_N, b);
2085 		sm9_bn_add(r, t, a);
2086 	}
2087 }
2088 
sm9_fn_mul(sm9_fn_t r,const sm9_fn_t a,const sm9_fn_t b)2089 void sm9_fn_mul(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b)
2090 {
2091 	uint64_t s[18];
2092 	sm9_barrett_bn_t zh, zl, q;
2093 	uint64_t w;
2094 	int i, j;
2095 
2096 	/* z = a * b */
2097 	for (i = 0; i < 8; i++) {
2098 		s[i] = 0;
2099 	}
2100 	for (i = 0; i < 8; i++) {
2101 		w = 0;
2102 		for (j = 0; j < 8; j++) {
2103 			w += s[i + j] + a[i] * b[j];
2104 			s[i + j] = w & 0xffffffff;
2105 			w >>= 32;
2106 		}
2107 		s[i + 8] = w;
2108 	}
2109 
2110 	/* zl = z mod (2^32)^9 = z[0..8]
2111 	 * zh = z // (2^32)^7 = z[7..15] */
2112 	for (i = 0; i < 9; i++) {
2113 		zl[i] = s[i];
2114 		zh[i] = s[7 + i];
2115 	}
2116 
2117 	/* q = zh * mu // (2^32)^9 */
2118 	for (i = 0; i < 18; i++) {
2119 		s[i] = 0;
2120 	}
2121 	for (i = 0; i < 9; i++) {
2122 		w = 0;
2123 		for (j = 0; j < 9; j++) {
2124 			w += s[i + j] + zh[i] * SM9_MU_N[j];
2125 			s[i + j] = w & 0xffffffff;
2126 			w >>= 32;
2127 		}
2128 		s[i + 9] = w;
2129 	}
2130 	for (i = 0; i < 9; i++) {
2131 		q[i] = s[9 + i];
2132 	}
2133 
2134 	/* q = q * n mod (2^32)^9 */
2135 	for (i = 0; i < 18; i++) {
2136 		s[i] = 0;
2137 	}
2138 	for (i = 0; i < 9; i++) {
2139 		w = 0;
2140 		for (j = 0; j < 8; j++) {
2141 			w += s[i + j] + q[i] * SM9_N[j];
2142 			s[i + j] = w & 0xffffffff;
2143 			w >>= 32;
2144 		}
2145 		s[i + 8] = w;
2146 	}
2147 	for (i = 0; i < 9; i++) {
2148 		q[i] = s[i];
2149 	}
2150 
2151 	/* r = zl - q (mod (2^32)^9) */
2152 
2153 	if (sm9_barrett_bn_cmp(zl, q)) {
2154 		sm9_barrett_bn_sub(zl, zl, q);
2155 	} else {
2156 		sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000};
2157 		sm9_barrett_bn_sub(q, c, q);
2158 		sm9_barrett_bn_add(zl, q, zl);
2159 	}
2160 
2161 
2162 	for (i = 0; i < 8; i++) {
2163 		r[i] = zl[i];
2164 	}
2165 
2166 	r[7] += (zl[8] << 32);
2167 
2168 	/* while r >= n do: r = r - n */
2169 	while (sm9_bn_cmp(r, SM9_N) >= 0) {
2170 		sm9_bn_sub(r, r, SM9_N);
2171 	}
2172 }
2173 
sm9_fn_pow(sm9_fn_t r,const sm9_fn_t a,const sm9_bn_t e)2174 void sm9_fn_pow(sm9_fn_t r, const sm9_fn_t a, const sm9_bn_t e)
2175 {
2176 	sm9_fn_t t;
2177 	uint32_t w;
2178 	int i, j;
2179 
2180 	assert(sm9_bn_cmp(e, SM9_N_MINUS_ONE) < 0);
2181 
2182 	sm9_bn_set_one(t);
2183 	for (i = 7; i >= 0; i--) {
2184 		w = (uint32_t)e[i];
2185 		for (j = 0; j < 32; j++) {
2186 			sm9_fn_mul(t, t, t);
2187 			if (w & 0x80000000)
2188 				sm9_fn_mul(t, t, a);
2189 			w <<= 1;
2190 		}
2191 	}
2192 	sm9_bn_copy(r, t);
2193 }
2194 
sm9_fn_inv(sm9_fn_t r,const sm9_fn_t a)2195 void sm9_fn_inv(sm9_fn_t r, const sm9_fn_t a)
2196 {
2197 	sm9_fn_t e;
2198 	sm9_bn_sub(e, SM9_N, SM9_TWO);
2199 	sm9_fn_pow(r, a, e);
2200 }
2201 
2202 
2203 // for H1() and H2()
2204 // h = (Ha mod (n-1)) + 1;  h in [1, n-1], n is the curve order, Ha is 40 bytes from hash
sm9_fn_from_hash(sm9_fn_t h,const uint8_t Ha[40])2205 void sm9_fn_from_hash(sm9_fn_t h, const uint8_t Ha[40])
2206 {
2207 	uint64_t s[18] = {0};
2208 	sm9_barrett_bn_t zh, zl, q;
2209 	uint64_t w;
2210 	int i, j;
2211 
2212 	/* s = Ha -> int */
2213 	for (int i = 0; i < 10; i++) {
2214 		for (int j = 0; j < 4; j++) {
2215 			s[i] <<= 8;
2216 			s[i] += Ha[4 * (9-i) + j];
2217 		}
2218 	}
2219 
2220 	/* zl = z mod (2^32)^9 = z[0..8]
2221 	 * zh = z // (2^32)^7 = z[7..15] */
2222 	for (i = 0; i < 9; i++) {
2223 		zl[i] = s[i];
2224 		zh[i] = s[7 + i];
2225 	}
2226 
2227 	/* q = zh * mu // (2^32)^9 */
2228 	for (i = 0; i < 18; i++) {
2229 		s[i] = 0;
2230 	}
2231 	for (i = 0; i < 9; i++) {
2232 		w = 0;
2233 		for (j = 0; j < 9; j++) {
2234 			w += s[i + j] + zh[i] * SM9_MU_N_MINUS_ONE[j]; //
2235 			s[i + j] = w & 0xffffffff;
2236 			w >>= 32;
2237 		}
2238 		s[i + 9] = w;
2239 	}
2240 	for (i = 0; i < 9; i++) {
2241 		q[i] = s[9 + i];
2242 	}
2243 
2244 	/* q = q * p mod (2^32)^9 */
2245 	for (i = 0; i < 18; i++) {
2246 		s[i] = 0;
2247 	}
2248 	for (i = 0; i < 9; i++) {
2249 		w = 0;
2250 		for (j = 0; j < 8; j++) {
2251 			w += s[i + j] + q[i] * SM9_N_MINUS_ONE[j];
2252 			s[i + j] = w & 0xffffffff;
2253 			w >>= 32;
2254 		}
2255 		s[i + 8] = w;
2256 	}
2257 	for (i = 0; i < 9; i++) {
2258 		q[i] = s[i];
2259 	}
2260 
2261 	/* h = zl - q (mod (2^32)^9) */
2262 
2263 	if (sm9_barrett_bn_cmp(zl, q)) {
2264 		sm9_barrett_bn_sub(zl, zl, q);
2265 	} else {
2266 		sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000};
2267 		sm9_barrett_bn_sub(q, c, q);
2268 		sm9_barrett_bn_add(zl, q, zl);
2269 	}
2270 
2271 	for (i = 0; i < 8; i++) {
2272 		h[i] = zl[i];
2273 	}
2274 
2275 	h[7] += (zl[8] << 32);
2276 
2277 	/* while h >= (n-1) do: h = h - (n-1) */
2278 	while (sm9_bn_cmp(h, SM9_N_MINUS_ONE) >= 0) {
2279 		sm9_bn_sub(h, h, SM9_N_MINUS_ONE);
2280 	}
2281 
2282 	sm9_fn_add(h, h, SM9_ONE);
2283 }
2284 
sm9_fp12_to_bytes(const sm9_fp12_t a,uint8_t buf[32* 12])2285 void sm9_fp12_to_bytes(const sm9_fp12_t a, uint8_t buf[32 * 12])
2286 {
2287 	sm9_fp4_to_bytes(a[2], buf);
2288 	sm9_fp4_to_bytes(a[1], buf + 32 * 4);
2289 	sm9_fp4_to_bytes(a[0], buf + 32 * 8);
2290 }
2291 
sm9_fn_from_bytes(sm9_fn_t a,const uint8_t in[32])2292 int sm9_fn_from_bytes(sm9_fn_t a, const uint8_t in[32])
2293 {
2294 	sm9_bn_from_bytes(a, in);
2295 	return 1;
2296 }
2297 
sm9_point_to_uncompressed_octets(const SM9_POINT * P,uint8_t octets[65])2298 int sm9_point_to_uncompressed_octets(const SM9_POINT *P, uint8_t octets[65])
2299 {
2300 	sm9_fp_t x;
2301 	sm9_fp_t y;
2302 	sm9_point_get_xy(P, x, y);
2303 	octets[0] = 0x04;
2304 	sm9_bn_to_bytes(x, octets + 1);
2305 	sm9_bn_to_bytes(y, octets + 32 + 1);
2306 	return 1;
2307 }
2308 
sm9_point_from_uncompressed_octets(SM9_POINT * P,const uint8_t octets[65])2309 int sm9_point_from_uncompressed_octets(SM9_POINT *P, const uint8_t octets[65])
2310 {
2311 	if (octets[0] != 0x04) {
2312 		error_print();
2313 		return -1;
2314 	}
2315 	memset(P, 0, sizeof(*P));
2316 	sm9_bn_from_bytes(P->X, octets + 1);
2317 	sm9_bn_from_bytes(P->Y, octets + 32 + 1);
2318 	sm9_fp_set_one(P->Z);
2319 	if (!sm9_point_is_on_curve(P)) {
2320 		error_print();
2321 		return -1;
2322 	}
2323 	return 1;
2324 }
2325 
sm9_twist_point_to_uncompressed_octets(const SM9_TWIST_POINT * P,uint8_t octets[129])2326 int sm9_twist_point_to_uncompressed_octets(const SM9_TWIST_POINT *P, uint8_t octets[129])
2327 {
2328 	octets[0] = 0x04;
2329 	sm9_fp2_t x;
2330 	sm9_fp2_t y;
2331 	sm9_twist_point_get_xy(P, x, y);
2332 	sm9_fp2_to_bytes(x, octets + 1);
2333 	sm9_fp2_to_bytes(y, octets + 32 * 2 + 1);
2334 	return 1;
2335 }
2336 
sm9_twist_point_from_uncompressed_octets(SM9_TWIST_POINT * P,const uint8_t octets[129])2337 int sm9_twist_point_from_uncompressed_octets(SM9_TWIST_POINT *P, const uint8_t octets[129])
2338 {
2339 	assert(octets[0] == 0x04);
2340 	sm9_fp2_from_bytes(P->X, octets + 1);
2341 	sm9_fp2_from_bytes(P->Y, octets + 32 * 2 + 1);
2342 	sm9_fp2_set_one(P->Z);
2343 	if (!sm9_twist_point_is_on_curve(P)) return -1;
2344 	return 1;
2345 }
2346