in src/cg21/cg21_keygen.c [107:193]
int CG21_KEY_GENERATE_ROUND1(csprng *RNG,
CG21_KEYGEN_ROUND1_STORE_PRIV *priv,
CG21_KEYGEN_ROUND1_STORE_PUB *pub,
CG21_KEYGEN_ROUND1_output *output,
CG21_KEYGEN_SID *sid,
int myID, int n, int t, octet *P)
{
BIG_256_56 s;
BIG_256_56 q;
ECP_SECP256K1 G;
char v[SHA256];
octet V = {0, sizeof(v), v};
// get curve generator
ECP_SECP256K1_generator(&G);
// get curve order
BIG_256_56_rcopy(q, CURVE_Order_SECP256K1);
// choose a random x_i (partial secret)
BIG_256_56_randomnum(s, q, RNG);
priv->x->len=EGS_SECP256K1;
BIG_256_56_toBytes(priv->x->val, s);
char cc[t][EFS_SECP256K1 + 1];
octet CC[t];
init_octets((char *)cc, CC, EFS_SECP256K1 + 1, t);
// run VSS on partial secret to get shares(priv->shares) and checks(CC)
VSS_make_shares(t, n, RNG, &priv->shares, CC, priv->x);
// pack VSS checks(CC) into one octet(pub->packed_checks)
CG21_pack_vss_checks(CC, t, pub->packed_checks);
// compute partial ECDSA PK(G)
ECP_SECP256K1_mul(&G, s);
BIG_256_56_zero(s);
// convert partial ECDSA PK from ECP to octet
ECP_SECP256K1_toOctet(pub->X, &G, true);
// validate the correctness of the partial ECDSA PK
int rc = ECP_SECP256K1_PUBLIC_KEY_VALIDATE(pub->X);
if (rc != 0)
{
return CG21_KEY_ERROR;
}
// commit to random tau and tau2
SCHNORR_commit(RNG, priv->tau, pub->A);
SCHNORR_commit(RNG, priv->tau2, pub->A2);
// choose random rid
BIG_256_56_randomnum(s, q, RNG);
pub->rid->len=EGS_SECP256K1;
BIG_256_56_toBytes(pub->rid->val, s);
// choose random u
BIG_256_56_zero(s);
BIG_256_56_randomnum(s, q, RNG);
pub->u->len=EGS_SECP256K1;
BIG_256_56_toBytes(pub->u->val, s);
// get SID
CG21_KEY_GENERATE_GET_SID(sid,P);
// store ID
priv->i= myID;
output->i = myID;
pub->i = myID;
// store threshold setting
priv->t = t;
priv->n = n;
// compute V
CG21_KEYGEN_ROUND1_GEN_V(pub, sid, &V);
OCT_copy(output->V, &V);
// clean up
BIG_256_56_zero(s);
return CG21_OK;
}