int CG21_KEY_GENERATE_ROUND3_2_3()

in src/cg21/cg21_keygen.c [293:364]


int CG21_KEY_GENERATE_ROUND3_2_3(const CG21_KEYGEN_ROUND1_STORE_PRIV *myPriv,
                                  const CG21_KEYGEN_ROUND1_STORE_PUB *pub,
                                  CG21_KEYGEN_ROUND3_STORE *r3,
                                  const CG21_KEYGEN_SID *sid,
                                  CG21_KEYGEN_ROUND3_OUTPUT *r3Output){

    BIG_256_56 accum;
    BIG_256_56 s;
    BIG_256_56 q;
    ECP_SECP256K1 G;

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

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

    // Curve order
    BIG_256_56_rcopy(q, CURVE_Order_SECP256K1);

    // Curve generator
    ECP_SECP256K1_generator(&G);

    char y[myPriv->n-1][EGS_SECP256K1];
    octet Y[myPriv->n-1];
    init_octets((char *)y,   Y,   EGS_SECP256K1, myPriv->n-1);

    // unpack Y component of the received SSS points
    int rc = CG21_unpack(r3->packed_share_Y, myPriv->n-1, Y, EGS_SECP256K1);
    if (rc!=CG21_OK){
        return rc;
    }

    int t =  myPriv->i - 1;
    BIG_256_56_fromBytesLen(accum, (myPriv->shares.Y + t)->val, (myPriv->shares.Y + t)->len);

    // compute sum-of-the-shares
    for (int i=0; i<myPriv->n-1; i++){
        BIG_256_56_fromBytesLen(s, Y[i].val, Y[i].len);
        BIG_256_56_add(accum, accum, s);
        BIG_256_56_mod(accum, q);
    }

    // convert sum-of-the-shares to octet
    r3->xi.Y->len = EGS_SECP256K1;
    BIG_256_56_toBytes(r3->xi.Y->val, accum);

    OCT_copy(r3->xi.X,myPriv->shares.X + t);

    // computes (sum-of-the-shares)*G
    ECP_SECP256K1_mul(&G, accum);

    // convert (sum-of-the-shares)*G to octet
    ECP_SECP256K1_toOctet(&X, &G, true);

    // generate challenge e for Schnorr proof
    CG21_GENERATE_CHALLENGE(&X, myPriv->i, *r3->xor_rid, sid, &E);

    // Schnorr proof for the knowledge of sum-of-the-shares
    SCHNORR_prove(myPriv->tau2, &E, r3->xi.Y, r3Output->xi_proof.psi);
    OCT_copy(r3Output->xi_proof.A, pub->A2);

    // clean up
    BIG_256_56_zero(accum);
    BIG_256_56_zero(s);

    for (int i=0; i<myPriv->n-1; i++){
        OCT_clear(&Y[i]);
    }

    return CG21_OK;
}