# 从私钥中获取公钥算法

void gm_get_publickey_from_privatekey(gm_point_t * p, const gm_bn_t key) {
	// 从私钥中计算公钥
    gm_point_mul(p, key, GM_MONT_G);
}
1
2
3
4

# 密钥对生成

/**
 * 生成SM2密钥对
 * @param private_key 私钥输出缓冲区
 * @param public_key 公钥输出缓冲区
 */
void gm_sm2_gen_keypair(gm_bn_t private_key, gm_point_t * public_key) {
    unsigned char buf[256];
    do {
        // rand private_key in [1, n - 2]
        do {
            do {
                randombytes(buf, 256);
    #ifdef GM_RAND_SM3
                gm_sm3(buf, 256, buf);
    #endif
                gm_bn_from_bytes(private_key, buf);
            } while (gm_bn_cmp(private_key, GM_BN_N_SUB_ONE) >= 0);
        } while (gm_bn_is_zero(private_key));

        // 从私钥中计算公钥
        gm_point_mul(public_key, private_key, GM_MONT_G);

        // check public key
    } while(gm_sm2_check_public_key(public_key) != 1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

单元测试代码:

void test_sm2_gen_keypair() {
    gm_bn_t k;
    gm_point_t p;
    int i;

    gm_sm2_gen_keypair(k, &p);

    char buf[132] = {0};

    gm_bn_to_hex(k, buf);
    printf("private key: %s\n", buf);

    gm_point_encode(&p, buf, 1);
    for (i = 0; i < 33; i++) {
        sprintf(buf + 33 + i * 2, "%02X", (buf[i] & 0x0FF));
    }
    buf[99] = 0;
    printf("public key compressed: %s\n", buf + 33);

    gm_point_to_hex(&p, buf);
    buf[128] = 0;
    printf("public key: 04%s\n", buf);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

main函数增加:

if(strcmp(argv[1], "sm2_gen_keypair") == 0) {
    test_sm2_gen_keypair();
}
1
2
3

执行结果:

192:c saint$ time ./gm_test sm2_gen_keypair
private key: 79A7804B09D7E7C42D9154E1178B7DB150BDFF9BEBE827E956F6715AAB397682
public key compressed: 0219AB8F767E970A8AEBB269E9321336A2609A95A25EF9EFA4318F945158FFA259
public key: 0419AB8F767E970A8AEBB269E9321336A2609A95A25EF9EFA4318F945158FFA2598B3ED65CD88ADCE1683B9A59701E8FCCBC79303565FA134D8F676666387A3CC6

real	0m0.014s
user	0m0.009s
sys	0m0.003s
1
2
3
4
5
6
7
8