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