int CG21_KEY_GENERATE_OUTPUT_1_2()

in src/cg21/cg21_keygen.c [392:460]


int CG21_KEY_GENERATE_OUTPUT_1_2(CG21_KEYGEN_OUTPUT *output,
                                 const CG21_KEYGEN_ROUND3_OUTPUT *r3Out,
                                 CG21_KEYGEN_ROUND3_STORE *r3Store,
                                 CG21_KEYGEN_ROUND1_STORE_PRIV *myPriv,
                                 const CG21_KEYGEN_SID *sid,
                                 const CG21_KEYGEN_ROUND1_STORE_PUB *r1Pub){

    ECP_SECP256K1 V;
    ECP_SECP256K1 Xi;
    BIG_256_56 T;

    char e[SGS_SECP256K1];
    octet E = {0, sizeof(e), e};

    char xi[SFS_SECP256K1 + 1];
    octet Xi_ = {0, sizeof(xi), xi};

    // converts party ID to array index
    int ind = r3Out->i - 1;

    int n = r3Store->n;
    int t = r3Store->t;

    // we only retrieve n-1 packed_checks that belong to other parties
    char round1_checks[n-1][t][EFS_SECP256K1 + 1];    // VSS: checks
    octet CC[(n-1)*t];
    init_octets((char *) round1_checks, CC, EFS_SECP256K1 + 1, (n-1)*t);

    // all players' vss checked are packed into one single octet
    // the following function first split each players' packed VSS checks from the main octet
    // then unpack each packed VSS checks
    // at the end, we will have (n-1)*t VSS checks
    int rc = CG21_double_unpack(r3Store->packed_all_checks, n-1, t, CC);
    if (rc!=CG21_OK){
        return rc;
    }

    // initialize Xi with (myPriv->shares.Y + ind)*G
    BIG_256_56_fromBytesLen(T, (myPriv->shares.Y + ind)->val, (myPriv->shares.Y + ind)->len);
    ECP_SECP256K1_generator(&Xi);
    ECP_SECP256K1_mul(&Xi, T);

    for (int j=0; j<n-1; j++) {
        // this functions calculates g^{x_i}, same x_i used in GG20 section 3.1 (phase 2), based on the VSS checks
        // CC+j*t refers to the beginning of each parties' octet and +t means we don't want to include the first checks
        // that belongs to the verifier in calculation of XI
        CG21_CALC_XI(t, myPriv->shares.X + ind, CC + j * t, &V);
        ECP_SECP256K1_add(&Xi, &V);
    }
    ECP_SECP256K1_toOctet(&Xi_, &Xi, true);

    // store all the other players (sum_of_share)*G to be used in key re-sharing protocol
    OCT_joctet(output->pk_ss_sum_pack, &Xi_);

    CG21_GENERATE_CHALLENGE(&Xi_, r3Out->i, *r3Store->xor_rid, sid, &E);

    int rc2 = SCHNORR_verify(&Xi_, r1Pub->A2, &E, r3Out->xi_proof.psi);

    // clean up
    BIG_256_56_zero(T);
    ECP_SECP256K1_inf(&Xi);

    if (rc2)
    {
        return CG21_SCHNORR_VERIFY_FAILED;
    }

    return CG21_OK;
}