#include <string.h>
#include "kgc.h"
#include "hash.h"

void genKGCkey(ECC_PARAMS *params, big msk, epoint *PK_pub)
{
    bigrand((*params).p, msk); // 产生小于p的随机数
    ecurve_mult(msk, (*params).P, PK_pub);
}

bool genPPK_std(
    ECC_PARAMS *params,
    big msk,        // KGC私钥
    epoint *PK_pub, // KGC公钥
    char ID[],      // 输入用户ID
    big d,          // 输出部分私钥
    epoint *Q,      // 产生的用户公钥
    epoint *X)      // 输入用户秘密值
{
    // 产生随机数r,计算R=rP
    epoint *R_A = epoint_init();
    big r = mirvar(0);
    bigrand((*params).p, r);
    ecurve_mult(r, (*params).P, R_A);

    //计算h_2 = H_2(ID,X)
    big h_2_big = mirvar(0);
    hash2(ID, X, (*params).p, h_2_big);

    //计算h_2 * X
    epoint *h2X = epoint_init();
    ecurve_mult(h_2_big, X, h2X);

    //计算Q = R + h_2 * X
    ecurve_add(R_A, Q);
    ecurve_add(h2X, Q);

    //计算h_1 = H_1(ID,Q,PK_pub)
    big h_1_big = mirvar(0);
    hash1(ID, Q, PK_pub, (*params).p, h_1_big);

    // 计算d = r + msk * h_1 mod p
    big tmp = mirvar(0);
    multiply(msk, h_1_big, tmp);
    add(r, tmp, d);
    power(d, 1, (*params).p, d); // mod p

    //计算h_1 * PK_pub
    epoint *h1PK = epoint_init();
    ecurve_mult(h_1_big, PK_pub, h1PK);

    // 用d * P = Q - h2 * X + h1 * PK_pub验证一下(d,Q)是否正确
    // 点的减法 pa = pa - a Function: void ecurve_sub(p,pa)
    epoint *left = epoint_init();
    ecurve_mult(d, (*params).P, left);
    epoint *right = epoint_init();
    ecurve_add(Q, right);
    ecurve_sub(h2X, right);
    ecurve_add(h1PK, right);

    bool bRv = false;
    if (epoint_comp(left, right))
    {
        bRv = true;

    }
    else
    {
        bRv = false;
    }

    mirkill(r);
    mirkill(h_1_big);
    mirkill(h_2_big);
    mirkill(tmp);
 
    epoint_free(R_A);
    epoint_free(left);
    epoint_free(right);
    epoint_free(h1PK);
    epoint_free(h2X);

    return bRv;
}