in src/cg21/cg21_keygen.c [494:540]
int CG21_KEY_GENERATE_OUTPUT_3(CG21_KEYGEN_OUTPUT *out, int n){
ECP_SECP256K1 accum;
ECP_SECP256K1 s;
char x[EFS_SECP256K1 + 1];
octet Xoct = {0, sizeof(x), x};
// checked the length of X_packed
if (out->X_set_packed->len != n * (EFS_SECP256K1 + 1))
{
return CG21_WRONG_PACKED_X_SIZE;
}
OCT_clear(&Xoct);
// extract the last Xi from X_packed
OCT_chop(out->X_set_packed, &Xoct, out->X_set_packed->len - (EFS_SECP256K1 + 1));
// convert Xi from octet to point
if (!ECP_SECP256K1_fromOctet(&accum, &Xoct))
{
return CG21_INVALID_ECP;
}
for (int i = n - 2; i >= 0; i--)
{
OCT_clear(&Xoct);
OCT_chop(out->X_set_packed, &Xoct, out->X_set_packed->len - (EFS_SECP256K1 + 1));
if (!ECP_SECP256K1_fromOctet(&s, &Xoct))
{
return CG21_INVALID_ECP;
}
ECP_SECP256K1_add(&accum, &s);
}
// restore length of the packed X
out->X_set_packed->len = n * (EFS_SECP256K1 + 1);
// convert X from point to octet
ECP_SECP256K1_toOctet(out->X, &accum, true);
return CG21_OK;
}