#include "ecurve.h"

// 使用的椭圆曲线(SECP256K1)公开参数
char Q[] = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F";     // 有限域的模q
char A[] = "0000000000000000000000000000000000000000000000000000000000000000";     // 曲线方程系数a
char B[] = "0000000000000000000000000000000000000000000000000000000000000007";     // 曲线方程系数b
char X[] = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";     // 基点P的x坐标
char Y[] = "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8";     // 基点P的y坐标
char P_N[] = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141";   // 基点P的阶：令nP=O的最小整数

bool setupEcurve(ECC_PARAMS *params)
{
    // 初始化变量
    (*params).a = mirvar(0);
    (*params).b = mirvar(0);
    (*params).q = mirvar(0);
    (*params).p = mirvar(0);
    (*params).P_x = mirvar(0);
    (*params).P_y = mirvar(0);
    (*params).P = epoint_init();

    // 赋值
    cinstr((*params).a, A);
    cinstr((*params).b, B);
    cinstr((*params).q, Q);
    cinstr((*params).p, P_N);

    cinstr((*params).P_x, X);
    cinstr((*params).P_y, Y);

    // 椭圆曲线方程初始化
    ecurve_init((*params).a, (*params).b, (*params).q, MR_PROJECTIVE);

    // 设置点坐标(P_x,P_y)为点P，此函数同时能判断P是否在上面初始化成功的椭圆曲线上
    if (!epoint_set((*params).P_x, (*params).P_y, 0, (*params).P))
    {
        freeEcurve(params);
        return false;
    }

    // 判断P是否是阶为p的基点，判断依据：基点乘以阶为无穷远点
    bool bRv = false;
    epoint *P_test = epoint_init();
    ecurve_mult((*params).p, (*params).P, P_test);
    if (point_at_infinity(P_test))
    {
        bRv = true;
    }
    else
    {
        freeEcurve(params);
        bRv = false;
    }
    epoint_free(P_test);

    return bRv;
}

void freeEcurve(ECC_PARAMS *params)
{
    mirkill((*params).a);
    mirkill((*params).b);
    mirkill((*params).q);
    mirkill((*params).p);
    mirkill((*params).P_x);
    mirkill((*params).P_y);

    epoint_free((*params).P);
}