Key Generation takes place one time. At the end of that interactive protocol both parties have computed their secret shards which will be used during the signature computation later on. There is no further need to put shards on the network again other than using them during sign phase. The protocol for key generation is described in section 3.2 https://eprint.iacr.org/2017/552.pdf.
Messages between parties are sent within a secure authenticated channel already established between the parties. The messages per se do not expose private information during key generation
In addition, the two parties must agree on who is party 1, and who is party 2 before beginning the key generation steps.
// Generate a random session id.let session_id =SessionId::random();// Generate two random secret values for participants. let x1 =BigInt::sample(256);let x2 =BigInt::sample(256);// Create keygen instances for each participant.let p1 =P1Keygen::new(session_id);let p2 =P2Keygen::new(session_id);// Round 1let (p1, msg1) = p1.process(())?;let (p2, msg2) = p2.process(msg1)?;// Round 2let (keyshare1, msg3) = p1.process(msg2)?;let keyshare2 = p2.process(msg3)?;// Distributed key generation is complete. Generated (keyshare1, keyshare2)assert!(keyshare1.public_key == keyshare2.public_key);
import { P1Keygen, P2Keygen, generateSessionId } from'@com.silencelaboratories/two-party-ecdsa-js';// Generate random session idconstsession_id=awaitgenerateSessionId();// Initialize keygen for each partyconstp1Keygen=awaitP1Keygen.init(session_id);constp2Keygen=awaitP2Keygen.init(session_id);// Round 1constmsg=awaitp1Keygen.genMsg1();constmsg2=awaitp2Keygen.processMsg1(msg);// Round 2const [p1keyshare,msg3] =awaitp1Keygen.processMsg2(msg2);constp2keyshare=awaitp2Keygen.processMsg3(msg3);// p1keyshare and p2keyshare are the secret keyshares of each party // with same public key
// The create_keyshares function returns the two keyshares that are generatedvoidcreate_keyshares(Handle*p1_share,Handle*p2_share, tss_buffer *public_key) {// InitializeHandle p1_sess;Handle p2_sess;Handle keys =p1_partykeys_new(); tss_buffer sess_buf; tss_buffer msg1, msg2, msg3, p1_share_buf, p2_share_buf;// Random Session id generation. Must be 32 bytes.srand((unsignedint) time(NULL));uint8_t session_id_data[32];for (size_t i =0; i <sizeof(session_id_data); i++) { session_id_data[i] =rand()%256; }sess_buf.ptr = session_id_data;sess_buf.len =sizeof(session_id_data);// P1 keygen initif (p1_keygen_init(&sess_buf, keys,&p1_sess)!= TSS_OK) {printf("Error during p1_keygen_init\n");// We hit an error, so panicperror("Error during p1_keygen_init"); exit(1); }// P2 keygen initif (p2_keygen_init(&sess_buf,&p2_sess)!= TSS_OK) {perror("Error during p2_keygen_init\n"); exit(1); }// P1 keygen gen_msg1if (p1_keygen_gen_msg1(p1_sess,&msg1)!= TSS_OK) {perror("Error during p1_keygen_gen_msg1\n"); exit(1); }// P2 keygen process_msg1if (p2_keygen_process_msg1(p2_sess,&msg1,&msg2)!= TSS_OK) {perror("Error during p2_keygen_process_msg1\n"); exit(1); }// P1 keygen process_msg2if (p1_keygen_process_msg2(p1_sess,&msg2,&msg3)!= TSS_OK) {perror("Error during p1_keygen_process_msg2\n"); exit(1); }// P2 keygen process_msg3if (p2_keygen_process_msg3(p2_sess,&msg3)!= TSS_OK) {perror("Error during p2_keygen_process_msg3\n"); exit(1); }// P1 keygen finishif (p1_keygen_fini(p1_sess, p1_share)!= TSS_OK) {perror("Error during p1_keygen_fini\n"); exit(1); }// P1 keyshare public keyif (p1_keyshare_public_key(*p1_share,&p1_share_buf)!= TSS_OK) {perror("Error during p1_keyshare_public_key\n"); exit(1); }// P2 keygen finishif (p2_keygen_fini(p2_sess, p2_share)!= TSS_OK) {perror("Error during p2_keygen_fini\n"); exit(1); }// P2 keyshare public keyif (p2_keyshare_public_key(*p2_share,&p2_share_buf)!= TSS_OK) {perror("Error during p2_keyshare_public_key\n"); exit(1); }// Verifying keys matchif (p1_share_buf.len !=p2_share_buf.len ||memcmp(p1_share_buf.ptr,p2_share_buf.ptr,p1_share_buf.len)!=0) {perror("Public keys do not match\n"); exit(1); }// Copying public key to outputpublic_key->ptr =malloc(p1_share_buf.len);memcpy((void*)public_key->ptr, (void*)p1_share_buf.ptr,p1_share_buf.len);public_key->len =p1_share_buf.len;// Freeing bufferstss_buffer_free(&msg1);tss_buffer_free(&msg2);tss_buffer_free(&msg3);return;}