From 7cef15077601820d30f2b14788daa3f1aad75b9d Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 18:48:22 +0100 Subject: [PATCH 01/50] add win deps --- src/cc/rogue/Makefile_win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/rogue/Makefile_win b/src/cc/rogue/Makefile_win index dbc900e48..96b6e61be 100644 --- a/src/cc/rogue/Makefile_win +++ b/src/cc/rogue/Makefile_win @@ -26,7 +26,7 @@ O=o CC = x86_64-w64-mingw32-gcc #CFLAGS=-O2 -CFLAGS= -g -O2 -I./ncurses/include +CFLAGS= -g -O2 -I./ncurses/include --I../../../depends/x86_64-w64-mingw32/include #LIBS=-lcurses LIBS = -L./ncurses/lib -lncursesw From 118461e55427865e34bdbb8a873b489ca9809aab Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 18:51:12 +0100 Subject: [PATCH 02/50] fix typo --- src/cc/makerogue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/makerogue b/src/cc/makerogue index ff175c586..c67892b90 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -5,7 +5,7 @@ if [ "$HOST" = "x86_64-w64-mingw32" ]; then echo building rogue.exe... mkdir ncurses && cd ncurses wget https://invisible-island.net/datafiles/release/mingw32.zip - unzip mingw32.zip && delete mingw32.zip + unzip mingw32.zip && rm mingw32.zip cd .. if make -f Makefile_win "$@"; then echo rogue.exe build SUCCESSFUL From bf44755dadc8ba400c86018d3aed161b778cb8cf Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 18:56:25 +0100 Subject: [PATCH 03/50] pwd --- src/cc/makerogue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc/makerogue b/src/cc/makerogue index c67892b90..9135753c1 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -6,7 +6,6 @@ if [ "$HOST" = "x86_64-w64-mingw32" ]; then mkdir ncurses && cd ncurses wget https://invisible-island.net/datafiles/release/mingw32.zip unzip mingw32.zip && rm mingw32.zip - cd .. if make -f Makefile_win "$@"; then echo rogue.exe build SUCCESSFUL cd .. From 8998c66874885248c2ac53aa044fdee3c413bcfb Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 18:58:09 +0100 Subject: [PATCH 04/50] revert --- src/cc/makerogue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/makerogue b/src/cc/makerogue index 9135753c1..c67892b90 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -6,6 +6,7 @@ if [ "$HOST" = "x86_64-w64-mingw32" ]; then mkdir ncurses && cd ncurses wget https://invisible-island.net/datafiles/release/mingw32.zip unzip mingw32.zip && rm mingw32.zip + cd .. if make -f Makefile_win "$@"; then echo rogue.exe build SUCCESSFUL cd .. From 55b7035f9b0736f06607768e13e2cd5b94a8da06 Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 19:04:45 +0100 Subject: [PATCH 05/50] add include --- src/cc/rogue/Makefile_win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/rogue/Makefile_win b/src/cc/rogue/Makefile_win index 96b6e61be..17941732c 100644 --- a/src/cc/rogue/Makefile_win +++ b/src/cc/rogue/Makefile_win @@ -26,7 +26,7 @@ O=o CC = x86_64-w64-mingw32-gcc #CFLAGS=-O2 -CFLAGS= -g -O2 -I./ncurses/include --I../../../depends/x86_64-w64-mingw32/include +CFLAGS= -g -O2 -I./ncurses/include -I../../../depends/x86_64-w64-mingw32/include #LIBS=-lcurses LIBS = -L./ncurses/lib -lncursesw From 762e3582d1d1109e97c3cb81ac8fb9501236033e Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 19:09:07 +0100 Subject: [PATCH 06/50] pwd --- src/cc/makerogue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc/makerogue b/src/cc/makerogue index c67892b90..9135753c1 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -6,7 +6,6 @@ if [ "$HOST" = "x86_64-w64-mingw32" ]; then mkdir ncurses && cd ncurses wget https://invisible-island.net/datafiles/release/mingw32.zip unzip mingw32.zip && rm mingw32.zip - cd .. if make -f Makefile_win "$@"; then echo rogue.exe build SUCCESSFUL cd .. From b635717ec1219c8d3542962cfc01dc43432815b1 Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 19:40:52 +0100 Subject: [PATCH 07/50] add ncursesw --- src/cc/rogue/Makefile_win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/rogue/Makefile_win b/src/cc/rogue/Makefile_win index 17941732c..9c440349e 100644 --- a/src/cc/rogue/Makefile_win +++ b/src/cc/rogue/Makefile_win @@ -26,7 +26,7 @@ O=o CC = x86_64-w64-mingw32-gcc #CFLAGS=-O2 -CFLAGS= -g -O2 -I./ncurses/include -I../../../depends/x86_64-w64-mingw32/include +CFLAGS= -g -O2 -I./ncurses/include -I./ncurses/include/ncursesw -I../../../depends/x86_64-w64-mingw32/include #LIBS=-lcurses LIBS = -L./ncurses/lib -lncursesw From 47b99da2a3d4a7dfa6bd9ccce67446a6183dcabb Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 20:41:57 +0100 Subject: [PATCH 08/50] add debug --- src/cc/makerogue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc/makerogue b/src/cc/makerogue index 9135753c1..b690e60e7 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -4,8 +4,11 @@ cd rogue; if [ "$HOST" = "x86_64-w64-mingw32" ]; then echo building rogue.exe... mkdir ncurses && cd ncurses + echo $PWD wget https://invisible-island.net/datafiles/release/mingw32.zip unzip mingw32.zip && rm mingw32.zip + echo lib archive cleaned + echo $PWD if make -f Makefile_win "$@"; then echo rogue.exe build SUCCESSFUL cd .. From fddc7d4369b242cb3b481f0a09d6247513a7913a Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 21:28:57 +0100 Subject: [PATCH 09/50] change dir --- src/cc/makerogue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/makerogue b/src/cc/makerogue index b690e60e7..063de081e 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -8,6 +8,7 @@ if [ "$HOST" = "x86_64-w64-mingw32" ]; then wget https://invisible-island.net/datafiles/release/mingw32.zip unzip mingw32.zip && rm mingw32.zip echo lib archive cleaned + cd .. echo $PWD if make -f Makefile_win "$@"; then echo rogue.exe build SUCCESSFUL From adb32b5a5138baa53adb30e7d324cb3d28405fdd Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 22:36:25 +0100 Subject: [PATCH 10/50] add WIN ifdef --- src/cc/rogue/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index ca05226d3..bcd35da73 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -41,7 +41,11 @@ typedef union _bits256 bits256; double OS_milliseconds() { struct timeval tv; double millis; + #ifdef __MINGW32__ + mingw_gettimeofday(&tv,NULL); + #else gettimeofday(&tv,NULL); + #endif millis = ((double)tv.tv_sec * 1000. + (double)tv.tv_usec / 1000.); //printf("tv_sec.%ld usec.%d %f\n",tv.tv_sec,tv.tv_usec,millis); return(millis); From 064179cf1894a31b018cf1461074e6895e3b0677 Mon Sep 17 00:00:00 2001 From: ca333 Date: Thu, 21 Feb 2019 23:09:25 +0100 Subject: [PATCH 11/50] config WIN --- src/cc/makerogue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/makerogue b/src/cc/makerogue index 063de081e..51caef6e2 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -3,6 +3,7 @@ cd rogue; if [ "$HOST" = "x86_64-w64-mingw32" ]; then echo building rogue.exe... + ./configure --host=x86_64-w64-mingw32 mkdir ncurses && cd ncurses echo $PWD wget https://invisible-island.net/datafiles/release/mingw32.zip From 6ca1613add51ece97efb7c9bb33ab878bd76cc2a Mon Sep 17 00:00:00 2001 From: ca333 Date: Fri, 22 Feb 2019 00:31:49 +0100 Subject: [PATCH 12/50] add ifdef WIN mdport --- src/cc/rogue/mdport.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc/rogue/mdport.c b/src/cc/rogue/mdport.c index 988e1c7b7..fd53be72c 100644 --- a/src/cc/rogue/mdport.c +++ b/src/cc/rogue/mdport.c @@ -705,7 +705,9 @@ md_erasechar() #elif defined(VERASE) return(_tty.c_cc[VERASE]); /* process erase character */ #else + #ifndef __MINGW32__ return(_tty.sg_erase); /* process erase character */ + #endif #endif } @@ -717,7 +719,9 @@ md_killchar() #elif defined(VKILL) return(_tty.c_cc[VKILL]); #else + #ifndef __MINGW32__ return(_tty.sg_kill); + #endif #endif } From ff9f59279bc6bf3a4e178b99eebda54050208014 Mon Sep 17 00:00:00 2001 From: ca333 Date: Fri, 22 Feb 2019 01:21:04 +0100 Subject: [PATCH 13/50] cache deps --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3ace05cb9..a9fb7a01b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,9 +32,9 @@ build:ubuntu: variables: DOCKER_DRIVER: overlay2 cache: - key: "${CI_JOB_NAME}${CI_COMMIT_REF_NAME}" + key: ${CI_COMMIT_REF_SLUG} paths: - - depends/built + - depends/ script: - zcutil/build.sh -j$(nproc) - mkdir ${PACKAGE_DIR_LINUX} From c7b070e91ca79f220e25cfae3d65e057fae519b4 Mon Sep 17 00:00:00 2001 From: ca333 Date: Fri, 22 Feb 2019 01:48:44 +0100 Subject: [PATCH 14/50] add curl --- src/cc/rogue/Makefile_win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/rogue/Makefile_win b/src/cc/rogue/Makefile_win index 9c440349e..6e558960c 100644 --- a/src/cc/rogue/Makefile_win +++ b/src/cc/rogue/Makefile_win @@ -29,7 +29,7 @@ CC = x86_64-w64-mingw32-gcc CFLAGS= -g -O2 -I./ncurses/include -I./ncurses/include/ncursesw -I../../../depends/x86_64-w64-mingw32/include #LIBS=-lcurses -LIBS = -L./ncurses/lib -lncursesw +LIBS = -L./ncurses/lib -lncursesw -lcurl #RM=rm -f RM = rm -f From ba34a8050009e4d1bef4df01b9ec685d7db5cca1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 19:58:07 -1100 Subject: [PATCH 15/50] +print --- src/cc/faucet.cpp | 2 +- src/cc/musig.cpp | 297 +++++++++++++++++++++++++++++++--------------- 2 files changed, 204 insertions(+), 95 deletions(-) diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index b44337461..3f1ac4982 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -124,9 +124,9 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx //int height = it->first.blockHeight; if ( CCduration(numblocks,it->first.txhash) > 0 && numblocks > 3 ) { - //fprintf(stderr,"would return error %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks); return eval->Invalid("faucet is only for brand new addresses"); } + fprintf(stderr,"txid %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks); } retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); if ( retval != 0 ) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index ec7f5e788..263ed2fff 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -88,6 +88,54 @@ extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp #define MUSIG_PREVN 0 // for now, just use vout0 for the musig output #define MUSIG_TXFEE 10000 +struct musig_info +{ + secp256k1_musig_session musig_session; + secp256k1_pubkey combined_pk; + uint8_t *nonce_commitments; // 32*N_SIGNERS + secp256k1_musig_session_signer_data *signer_data; //[N_SIGNERS]; + secp256k1_pubkey *nonce; //[N_SIGNERS]; + secp256k1_musig_partial_signature *partial_sig; //[N_SIGNERS]; + int32_t myind,num; + uint8_t msg[32],pkhash[32],combpk[33]; +} *MUSIG; + +struct musig_info *musig_infocreate(int32_t myind,int32_t num) +{ + struct musig_info *mp = (struct musig_info *)calloc(1,sizeof(*mp)); + mp->myind = myind, mp->num = num; + mp->nonce_commitments = (uint8_t *)calloc(num,32); + mp->signer_data = (uint8_t *)calloc(num,sizeof(*np->signer_data)); + mp->nonce = (uint8_t *)calloc(num,sizeof(*np->nonce)); + mp->partial_sig = (uint8_t *)calloc(num,sizeof(*np->partial_sig)); + return(mp); +} + +void musig_infofree(struct musig_info *mp) +{ + if ( mp->partial_sig != 0 ) + { + random_buf(mp->partial_sig,num*sizeof(*np->partial_sig)) + free(mp->partial_sig); + } + if ( mp->nonce != 0 ) + { + random_buf(mp->nonce,num*sizeof(*np->nonce)) + free(mp->nonce); + } + if ( mp->signer_data != 0 ) + { + random_buf(mp->signer_data,num*sizeof(*np->signer_data)) + free(mp->signer_data); + } + if ( mp->nonce_commitments != 0 ) + { + random_buf(mp->nonce_commitments,num*32) + free(mp->nonce_commitments); + } + free(mp); +} + CScript musig_sendopret(uint8_t funcid,CPubKey pk) { CScript opret; uint8_t evalcode = EVAL_MUSIG; @@ -215,111 +263,158 @@ UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("result","success")); - /** Initializes a signing session for a signer - * - * Returns: 1: session is successfully initialized - * 0: session could not be initialized: secret key or secret nonce overflow - * Args: ctx: pointer to a context object, initialized for signing (cannot - * be NULL) - * Out: session: the session structure to initialize (cannot be NULL) - * signers: an array of signers' data to be initialized. Array length must - * equal to `n_signers` (cannot be NULL) - * nonce_commitment32: filled with a 32-byte commitment to the generated nonce - * (cannot be NULL) - * In: session_id32: a *unique* 32-byte ID to assign to this session (cannot be - * NULL). If a non-unique session_id32 was given then a partial - * signature will LEAK THE SECRET KEY. - * msg32: the 32-byte message to be signed. Shouldn't be NULL unless you - * require sharing public nonces before the message is known - * because it reduces nonce misuse resistance. If NULL, must be - * set with `musig_session_set_msg` before signing and verifying. - * combined_pk: the combined public key of all signers (cannot be NULL) - * pk_hash32: the 32-byte hash of the signers' individual keys (cannot be - * NULL) - * n_signers: length of signers array. Number of signers participating in - * the MuSig. Must be greater than 0 and at most 2^32 - 1. - * my_index: index of this signer in the signers array - * seckey: the signer's 32-byte secret key (cannot be NULL) - */ - //if (!secp256k1_musig_session_initialize(ctx, &musig_session[i], signer_data[i], nonce_commitment[i], session_id32, msg32, &combined_pk, pk_hash, N_SIGNERS, i, seckeys[i])) - //return 0; - // randombytes_buf(buf, num); - - //nonce_commitment_ptr[i] = &nonce_commitment[i][0]; - return(result); + static secp256k1_context *ctx; + UniValue result(UniValue::VOBJ); int32_t i,n,myind,num; char *pkstr,*pkhashstr,*msgstr; uint8_t session[32],msg[32],pkhash[32],privkey[32],pub33[33]; CPubKey pk; char str[67]; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + if ( params != 0 && (n= cJSON_GetArraySize(params)) == 5 ) + { + // set the 5 args: myind, num, pub33, pkhash32, msg32 + if ( MUSIG != 0 ) + musig_infofree(MUSIG), MUSIG = 0; + MUSIG = musig_infocreate(myind,num); + pk = buf2pk(pub33); + if ( secp256k1_ec_pubkey_parse(ctx,&MUSIG->combined_pk,pk.begin(),33) > 0 ) + { + memcpy(MUSIG->pkhash,pkhash,sizeof(pkhash)); + memcpy(MUSIG->msg,msg,sizeof(msg)); + random_buf(session,32); + Myprivkey(privkey); + /** Initializes a signing session for a signer + * + * Returns: 1: session is successfully initialized + * 0: session could not be initialized: secret key or secret nonce overflow + * Args: ctx: pointer to a context object, initialized for signing (cannot + * be NULL) + * Out: session: the session structure to initialize (cannot be NULL) + * signers: an array of signers' data to be initialized. Array length must + * equal to `n_signers` (cannot be NULL) + * nonce_commitment32: filled with a 32-byte commitment to the generated nonce + * (cannot be NULL) + * In: session_id32: a *unique* 32-byte ID to assign to this session (cannot be + * NULL). If a non-unique session_id32 was given then a partial + * signature will LEAK THE SECRET KEY. + * msg32: the 32-byte message to be signed. Shouldn't be NULL unless you + * require sharing public nonces before the message is known + * because it reduces nonce misuse resistance. If NULL, must be + * set with `musig_session_set_msg` before signing and verifying. + * combined_pk: the combined public key of all signers (cannot be NULL) + * pk_hash32: the 32-byte hash of the signers' individual keys (cannot be + * NULL) + * n_signers: length of signers array. Number of signers participating in + * the MuSig. Must be greater than 0 and at most 2^32 - 1. + * my_index: index of this signer in the signers array + * seckey: the signer's 32-byte secret key (cannot be NULL) + */ + if ( secp256k1_musig_session_initialize(ctx,&MUSIG->musig_session,MUSIG->signer_data, &MUSIG->nonce_commitment[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) + { + result.push_back(Pair("myind",(int64_t)myind)); + result.push_back(Pair("numsigners",(int64_t)num)); + for (i=0; i<32; i++) + sprintf(&str[i<<1],"%02x",MUSIG->nonce_commitment[MUSIG->myind*32 + i]); + str[64] = 0; + result.push_back(Pair("commitment",str)); + result.push_back(Pair("result","success")); + return(result) + } else return(cclib_error(result,"couldnt initialize session")); + } else return(cclib_error(result,"couldnt parse combined pubkey")); + } else return(cclib_error(result,"wrong number of params, need 5: myindex, numsigners, combined_pk, pkhash, msg32")); } UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("result","success")); - /** Gets the signer's public nonce given a list of all signers' data with commitments - * - * Returns: 1: public nonce is written in nonce - * 0: signer data is missing commitments or session isn't initialized - * for signing - * Args: ctx: pointer to a context object (cannot be NULL) - * session: the signing session to get the nonce from (cannot be NULL) - * signers: an array of signers' data initialized with - * `musig_session_initialize`. Array length must equal to - * `n_commitments` (cannot be NULL) - * Out: nonce: the nonce (cannot be NULL) - * In: commitments: array of 32-byte nonce commitments (cannot be NULL) - * n_commitments: the length of commitments and signers array. Must be the total - * number of signers participating in the MuSig. - */ - // Set nonce commitments in the signer data and get the own public nonce - //if (!secp256k1_musig_session_get_public_nonce(ctx, &musig_session[i], signer_data[i], &nonce[i], nonce_commitment_ptr, N_SIGNERS)) - // return 0; - - return(result); + static secp256k1_context *ctx; + UniValue result(UniValue::VOBJ); int32_t n; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) + { + // pkhash, ind, commitment + // if all commitments, emit nonce, else just update MUSIG-> + + /** Gets the signer's public nonce given a list of all signers' data with commitments + * + * Returns: 1: public nonce is written in nonce + * 0: signer data is missing commitments or session isn't initialized + * for signing + * Args: ctx: pointer to a context object (cannot be NULL) + * session: the signing session to get the nonce from (cannot be NULL) + * signers: an array of signers' data initialized with + * `musig_session_initialize`. Array length must equal to + * `n_commitments` (cannot be NULL) + * Out: nonce: the nonce (cannot be NULL) + * In: commitments: array of 32-byte nonce commitments (cannot be NULL) + * n_commitments: the length of commitments and signers array. Must be the total + * number of signers participating in the MuSig. + */ + // Set nonce commitments in the signer data and get the own public nonce + //if (secp256k1_musig_session_get_public_nonce(ctx, &musig_session[i], signer_data[i], &nonce[i], nonce_commitment_ptr, N_SIGNERS) > 0 ) + { + // publish nonce + result.push_back(Pair("result","success")); + } + // return 0; + } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, commitment")); } UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("result","success")); - /** Checks a signer's public nonce against a commitment to said nonce, and update - * data structure if they match - * - * Returns: 1: commitment was valid, data structure updated - * 0: commitment was invalid, nothing happened - * Args: ctx: pointer to a context object (cannot be NULL) - * signer: pointer to the signer data to update (cannot be NULL). Must have - * been used with `musig_session_get_public_nonce` or initialized - * with `musig_session_initialize_verifier`. - * In: nonce: signer's alleged public nonce (cannot be NULL) - */ - //if (!secp256k1_musig_set_nonce(ctx, &signer_data[i][j], &nonce[j])) { - - - /** Updates a session with the combined public nonce of all signers. The combined - * public nonce is the sum of every signer's public nonce. - * - * Returns: 1: nonces are successfully combined - * 0: a signer's nonce is missing - * Args: ctx: pointer to a context object (cannot be NULL) - * session: session to update with the combined public nonce (cannot be - * NULL) - * signers: an array of signers' data, which must have had public nonces - * set with `musig_set_nonce`. Array length must equal to `n_signers` - * (cannot be NULL) - * n_signers: the length of the signers array. Must be the total number of - * signers participating in the MuSig. - * Out: nonce_is_negated: a pointer to an integer that indicates if the combined - * public nonce had to be negated. - * adaptor: point to add to the combined public nonce. If NULL, nothing is - * added to the combined nonce. - */ - // after all nonces: if (!secp256k1_musig_session_combine_nonces(ctx, &musig_session[i], signer_data[i], N_SIGNERS, NULL, NULL)) { + static secp256k1_context *ctx; + UniValue result(UniValue::VOBJ); int32_t n; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + // pkhash, ind, nonce + // if all nonces, combine nonce, else just update MUSIG-> + result.push_back(Pair("result","success")); + /** Checks a signer's public nonce against a commitment to said nonce, and update + * data structure if they match + * + * Returns: 1: commitment was valid, data structure updated + * 0: commitment was invalid, nothing happened + * Args: ctx: pointer to a context object (cannot be NULL) + * signer: pointer to the signer data to update (cannot be NULL). Must have + * been used with `musig_session_get_public_nonce` or initialized + * with `musig_session_initialize_verifier`. + * In: nonce: signer's alleged public nonce (cannot be NULL) + */ + //if (!secp256k1_musig_set_nonce(ctx, &signer_data[i][j], &nonce[j])) { + + + /** Updates a session with the combined public nonce of all signers. The combined + * public nonce is the sum of every signer's public nonce. + * + * Returns: 1: nonces are successfully combined + * 0: a signer's nonce is missing + * Args: ctx: pointer to a context object (cannot be NULL) + * session: session to update with the combined public nonce (cannot be + * NULL) + * signers: an array of signers' data, which must have had public nonces + * set with `musig_set_nonce`. Array length must equal to `n_signers` + * (cannot be NULL) + * n_signers: the length of the signers array. Must be the total number of + * signers participating in the MuSig. + * Out: nonce_is_negated: a pointer to an integer that indicates if the combined + * public nonce had to be negated. + * adaptor: point to add to the combined public nonce. If NULL, nothing is + * added to the combined nonce. + */ + // after all nonces: if (!secp256k1_musig_session_combine_nonces(ctx, &musig_session[i], signer_data[i], N_SIGNERS, NULL, NULL)) { return(result); + } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, nonce")); } UniValue musig_partialsign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); + static secp256k1_context *ctx; + UniValue result(UniValue::VOBJ); int32_t n; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + // similar to commit/nonce + } result.push_back(Pair("result","success")); /** Produces a partial signature * @@ -349,7 +444,14 @@ UniValue musig_partialsign(uint64_t txfee,struct CCcontract_info *cp,cJSON *para UniValue musig_sigcombine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); + static secp256k1_context *ctx; + UniValue result(UniValue::VOBJ); int32_t n; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + // finally! + } result.push_back(Pair("result","success")); /** Checks that an individual partial signature verifies * @@ -387,7 +489,14 @@ UniValue musig_sigcombine(uint64_t txfee,struct CCcontract_info *cp,cJSON *param UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); + static secp256k1_context *ctx; + UniValue result(UniValue::VOBJ); int32_t n; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + { + // can code this out of order + } result.push_back(Pair("result","success")); /** Verify a Schnorr signature. * From cb1a6291c6e45addf50146971703be58badeff52 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 19:59:46 -1100 Subject: [PATCH 16/50] Mp --- src/cc/musig.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 263ed2fff..b54bf26d1 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -105,9 +105,9 @@ struct musig_info *musig_infocreate(int32_t myind,int32_t num) struct musig_info *mp = (struct musig_info *)calloc(1,sizeof(*mp)); mp->myind = myind, mp->num = num; mp->nonce_commitments = (uint8_t *)calloc(num,32); - mp->signer_data = (uint8_t *)calloc(num,sizeof(*np->signer_data)); - mp->nonce = (uint8_t *)calloc(num,sizeof(*np->nonce)); - mp->partial_sig = (uint8_t *)calloc(num,sizeof(*np->partial_sig)); + mp->signer_data = (uint8_t *)calloc(num,sizeof(*mp->signer_data)); + mp->nonce = (uint8_t *)calloc(num,sizeof(*mp->nonce)); + mp->partial_sig = (uint8_t *)calloc(num,sizeof(*mp->partial_sig)); return(mp); } @@ -115,22 +115,22 @@ void musig_infofree(struct musig_info *mp) { if ( mp->partial_sig != 0 ) { - random_buf(mp->partial_sig,num*sizeof(*np->partial_sig)) + random_buf(mp->partial_sig,mp->num*sizeof(*np->partial_sig)) free(mp->partial_sig); } if ( mp->nonce != 0 ) { - random_buf(mp->nonce,num*sizeof(*np->nonce)) + random_buf(mp->nonce,mp->num*sizeof(*mp->nonce)) free(mp->nonce); } if ( mp->signer_data != 0 ) { - random_buf(mp->signer_data,num*sizeof(*np->signer_data)) + random_buf(mp->signer_data,mp->num*sizeof(*mp->signer_data)) free(mp->signer_data); } if ( mp->nonce_commitments != 0 ) { - random_buf(mp->nonce_commitments,num*32) + random_buf(mp->nonce_commitments,mp->num*32) free(mp->nonce_commitments); } free(mp); From da11af7c0ff54a3071e0e3f50723d2d6610e4364 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:01:06 -1100 Subject: [PATCH 17/50] Test --- src/cc/musig.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index b54bf26d1..44ddf6ef3 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -87,6 +87,7 @@ extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp #define MUSIG_PREVN 0 // for now, just use vout0 for the musig output #define MUSIG_TXFEE 10000 +#define random_buf(a,b) struct musig_info { @@ -105,9 +106,9 @@ struct musig_info *musig_infocreate(int32_t myind,int32_t num) struct musig_info *mp = (struct musig_info *)calloc(1,sizeof(*mp)); mp->myind = myind, mp->num = num; mp->nonce_commitments = (uint8_t *)calloc(num,32); - mp->signer_data = (uint8_t *)calloc(num,sizeof(*mp->signer_data)); - mp->nonce = (uint8_t *)calloc(num,sizeof(*mp->nonce)); - mp->partial_sig = (uint8_t *)calloc(num,sizeof(*mp->partial_sig)); + mp->signer_data = (secp256k1_musig_session_signer_data *)calloc(num,sizeof(*mp->signer_data)); + mp->nonce = (secp256k1_pubkey *)calloc(num,sizeof(*mp->nonce)); + mp->partial_sig = (secp256k1_musig_partial_signature *)calloc(num,sizeof(*mp->partial_sig)); return(mp); } @@ -115,7 +116,7 @@ void musig_infofree(struct musig_info *mp) { if ( mp->partial_sig != 0 ) { - random_buf(mp->partial_sig,mp->num*sizeof(*np->partial_sig)) + random_buf(mp->partial_sig,mp->num*sizeof(*mp->partial_sig)) free(mp->partial_sig); } if ( mp->nonce != 0 ) From e1c434466734a26921d98c6e0db1cb12df3a2f08 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:02:05 -1100 Subject: [PATCH 18/50] syntax --- src/cc/musig.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 44ddf6ef3..aa821f644 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -307,16 +307,16 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * my_index: index of this signer in the signers array * seckey: the signer's 32-byte secret key (cannot be NULL) */ - if ( secp256k1_musig_session_initialize(ctx,&MUSIG->musig_session,MUSIG->signer_data, &MUSIG->nonce_commitment[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) + if ( secp256k1_musig_session_initialize(ctx,&MUSIG->musig_session,MUSIG->signer_data, &MUSIG->nonce_commitments[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) { result.push_back(Pair("myind",(int64_t)myind)); result.push_back(Pair("numsigners",(int64_t)num)); for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",MUSIG->nonce_commitment[MUSIG->myind*32 + i]); + sprintf(&str[i<<1],"%02x",MUSIG->nonce_commitments[MUSIG->myind*32 + i]); str[64] = 0; result.push_back(Pair("commitment",str)); result.push_back(Pair("result","success")); - return(result) + return(result); } else return(cclib_error(result,"couldnt initialize session")); } else return(cclib_error(result,"couldnt parse combined pubkey")); } else return(cclib_error(result,"wrong number of params, need 5: myindex, numsigners, combined_pk, pkhash, msg32")); From 40c26873ba97286ed860c8e4c742b68cc28f237c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:03:14 -1100 Subject: [PATCH 19/50] extern "C" --- src/cc/musig.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index aa821f644..68787e67b 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -78,6 +78,7 @@ extern "C" int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, s extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *msg32, const secp256k1_pubkey *pk); extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64); extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys); +extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, unsigned char *nonce_commitment32, const unsigned char *session_id32, const unsigned char *msg32, const secp256k1_pubkey *combined_pk, const unsigned char *pk_hash32, size_t n_signers, size_t my_index, const unsigned char *seckey); //#include "../secp256k1/include/secp256k1.h" From 146d452410880c1657f479c22f33d51402b667aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:03:56 -1100 Subject: [PATCH 20/50] Reorder --- src/cc/musig.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 68787e67b..8fdba80a2 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -74,18 +74,18 @@ struct secp256k1_context_struct { secp256k1_callback error_callback; }; -extern "C" int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); -extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *msg32, const secp256k1_pubkey *pk); -extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64); -extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys); -extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, unsigned char *nonce_commitment32, const unsigned char *session_id32, const unsigned char *msg32, const secp256k1_pubkey *combined_pk, const unsigned char *pk_hash32, size_t n_signers, size_t my_index, const unsigned char *seckey); - //#include "../secp256k1/include/secp256k1.h" //#include "../secp256k1/include/secp256k1_schnorrsig.h" #include "../secp256k1/include/secp256k1_musig.h" +extern "C" int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); +extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *msg32, const secp256k1_pubkey *pk); +extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64); +extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys); +extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, unsigned char *nonce_commitment32, const unsigned char *session_id32, const unsigned char *msg32, const secp256k1_pubkey *combined_pk, const unsigned char *pk_hash32, size_t n_signers, size_t my_index, const unsigned char *seckey); + #define MUSIG_PREVN 0 // for now, just use vout0 for the musig output #define MUSIG_TXFEE 10000 #define random_buf(a,b) From c76bd865230436337d54231fcaa6ca86957cb0b2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:06:25 -1100 Subject: [PATCH 21/50] #ifdef __cplusplus --- src/secp256k1/include/secp256k1_musig.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/secp256k1/include/secp256k1_musig.h b/src/secp256k1/include/secp256k1_musig.h index 7e974e36d..d58550cf8 100644 --- a/src/secp256k1/include/secp256k1_musig.h +++ b/src/secp256k1/include/secp256k1_musig.h @@ -167,7 +167,12 @@ SECP256K1_API int secp256k1_musig_pubkey_combine( * my_index: index of this signer in the signers array * seckey: the signer's 32-byte secret key (cannot be NULL) */ -SECP256K1_API int secp256k1_musig_session_initialize( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_session_initialize( const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, From db9149577974a6cda3a60ae4196c9b2d7a3eeec5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:07:50 -1100 Subject: [PATCH 22/50] Again --- src/secp256k1/include/secp256k1_musig.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/secp256k1/include/secp256k1_musig.h b/src/secp256k1/include/secp256k1_musig.h index d58550cf8..a0106e691 100644 --- a/src/secp256k1/include/secp256k1_musig.h +++ b/src/secp256k1/include/secp256k1_musig.h @@ -132,7 +132,12 @@ typedef struct { * key (cannot be NULL) * n_pubkeys: length of pubkeys array */ -SECP256K1_API int secp256k1_musig_pubkey_combine( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_pubkey_combine( const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, From f20d2860dec77fcdca16d874787a037058855cf5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:11:38 -1100 Subject: [PATCH 23/50] -print --- src/cc/faucet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index 3f1ac4982..b794d9b1c 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -126,7 +126,7 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx { return eval->Invalid("faucet is only for brand new addresses"); } - fprintf(stderr,"txid %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks); + //fprintf(stderr,"txid %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks); } retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); if ( retval != 0 ) From f448c53ac872751e8a2f3d5bd6ed562b61e28443 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:13:18 -1100 Subject: [PATCH 24/50] (uint8_t *) --- src/cc/musig.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 8fdba80a2..80da59927 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -88,7 +88,6 @@ extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, #define MUSIG_PREVN 0 // for now, just use vout0 for the musig output #define MUSIG_TXFEE 10000 -#define random_buf(a,b) struct musig_info { @@ -117,22 +116,22 @@ void musig_infofree(struct musig_info *mp) { if ( mp->partial_sig != 0 ) { - random_buf(mp->partial_sig,mp->num*sizeof(*mp->partial_sig)) + GetRandBytes((uint8_t *)mp->partial_sig,mp->num*sizeof(*mp->partial_sig)) free(mp->partial_sig); } if ( mp->nonce != 0 ) { - random_buf(mp->nonce,mp->num*sizeof(*mp->nonce)) + GetRandBytes((uint8_t *)mp->nonce,mp->num*sizeof(*mp->nonce)) free(mp->nonce); } if ( mp->signer_data != 0 ) { - random_buf(mp->signer_data,mp->num*sizeof(*mp->signer_data)) + GetRandBytes((uint8_t *)mp->signer_data,mp->num*sizeof(*mp->signer_data)) free(mp->signer_data); } if ( mp->nonce_commitments != 0 ) { - random_buf(mp->nonce_commitments,mp->num*32) + GetRandBytes((uint8_t *)mp->nonce_commitments,mp->num*32) free(mp->nonce_commitments); } free(mp); @@ -280,7 +279,7 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { memcpy(MUSIG->pkhash,pkhash,sizeof(pkhash)); memcpy(MUSIG->msg,msg,sizeof(msg)); - random_buf(session,32); + GetRandBytes(session,32); Myprivkey(privkey); /** Initializes a signing session for a signer * From 41d1eef0191a48413140f73c5d8abb30602cfceb Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:14:14 -1100 Subject: [PATCH 25/50] ; --- src/cc/musig.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 80da59927..633c95feb 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -116,24 +116,25 @@ void musig_infofree(struct musig_info *mp) { if ( mp->partial_sig != 0 ) { - GetRandBytes((uint8_t *)mp->partial_sig,mp->num*sizeof(*mp->partial_sig)) + GetRandBytes((uint8_t *)mp->partial_sig,mp->num*sizeof(*mp->partial_sig)); free(mp->partial_sig); } if ( mp->nonce != 0 ) { - GetRandBytes((uint8_t *)mp->nonce,mp->num*sizeof(*mp->nonce)) + GetRandBytes((uint8_t *)mp->nonce,mp->num*sizeof(*mp->nonce)); free(mp->nonce); } if ( mp->signer_data != 0 ) { - GetRandBytes((uint8_t *)mp->signer_data,mp->num*sizeof(*mp->signer_data)) + GetRandBytes((uint8_t *)mp->signer_data,mp->num*sizeof(*mp->signer_data)); free(mp->signer_data); } if ( mp->nonce_commitments != 0 ) { - GetRandBytes((uint8_t *)mp->nonce_commitments,mp->num*32) + GetRandBytes((uint8_t *)mp->nonce_commitments,mp->num*32); free(mp->nonce_commitments); } + GetRandBytes((uint8_t *)mp,sizeof(*mp)); free(mp); } From dc3767b68f5369114164235da1297ebb07525356 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:15:40 -1100 Subject: [PATCH 26/50] Session --- src/cc/musig.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 633c95feb..9f529a341 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -281,6 +281,10 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) memcpy(MUSIG->pkhash,pkhash,sizeof(pkhash)); memcpy(MUSIG->msg,msg,sizeof(msg)); GetRandBytes(session,32); + for (i=0; i<32; i++) + sprintf(&str[i<<1],"%02x",session[i]); + str[64] = 0; + fprintf(stderr,"session %s\n",str); Myprivkey(privkey); /** Initializes a signing session for a signer * From 3bc10962e5af83cbca4eaf7f8edf5046ce21b5d0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 20:17:28 -1100 Subject: [PATCH 27/50] Move --- src/cc/musig.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 9f529a341..fc83fe382 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -276,15 +276,15 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) musig_infofree(MUSIG), MUSIG = 0; MUSIG = musig_infocreate(myind,num); pk = buf2pk(pub33); + GetRandBytes(session,32); + for (i=0; i<32; i++) + sprintf(&str[i<<1],"%02x",session[i]); + str[64] = 0; + fprintf(stderr,"session %s\n",str); if ( secp256k1_ec_pubkey_parse(ctx,&MUSIG->combined_pk,pk.begin(),33) > 0 ) { memcpy(MUSIG->pkhash,pkhash,sizeof(pkhash)); memcpy(MUSIG->msg,msg,sizeof(msg)); - GetRandBytes(session,32); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",session[i]); - str[64] = 0; - fprintf(stderr,"session %s\n",str); Myprivkey(privkey); /** Initializes a signing session for a signer * From d84a9afe6f071c0801f1350c9acbf7a128f96c55 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 22:03:15 -1100 Subject: [PATCH 28/50] Add parsing for session --- src/cc/musig.cpp | 64 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index fc83fe382..ccb554e0f 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -223,6 +223,27 @@ UniValue musig_calcmsg(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) } else return(cclib_error(result,"couldnt parse params")); } +int32_t musig_parsepubkey(secp256k1_context *ctx,secp256k1_pubkey &spk,cJSON *item) +{ + char *hexstr; + if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == 66 ) + { + CPubKey pk(ParseHex(hexstr)); + if ( secp256k1_ec_pubkey_parse(ctx,&spk,pk.begin(),33) > 0 ) + return(1); + } else return(-1); +} + +int32_t musig_parsehash32(uint8_t *hash32,cJSON *item) +{ + char *hexstr; + if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == 64 ) + { + decode_hex(hash32,32,hexstr); + return(0); + } else return(-1); +} + UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; @@ -235,13 +256,9 @@ UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) //fprintf(stderr,"n.%d args.(%s)\n",n,jprint(params,0)); for (i=0; i 0 ) - pubkeys.push_back(spk); - else return(cclib_error(result,"error parsing pk")); - } else return(cclib_error(result,"all pubkeys must be 33 bytes hexdata")); + if ( musig_parsepubkey(ctx,spk,jitem(params,i)) < 0 ) + return(cclib_error(result,"error parsing pk")); + pubkeys.push_back(spk); } if ( secp256k1_musig_pubkey_combine(ctx,NULL,&combined_pk,pkhash,&pubkeys[0],n) > 0 ) { @@ -271,21 +288,26 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 5 ) { - // set the 5 args: myind, num, pub33, pkhash32, msg32 + myind = juint(jitem(params,0),0); + num = juint(jitem(params,1),0); + if ( myind < 0 || myind >= num || num <= 0 ) + return(cclib_error(result,"illegal myindex and numsigners")); if ( MUSIG != 0 ) musig_infofree(MUSIG), MUSIG = 0; MUSIG = musig_infocreate(myind,num); - pk = buf2pk(pub33); - GetRandBytes(session,32); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",session[i]); - str[64] = 0; - fprintf(stderr,"session %s\n",str); - if ( secp256k1_ec_pubkey_parse(ctx,&MUSIG->combined_pk,pk.begin(),33) > 0 ) + if ( musig_parsepubkey(ctx,MUSIG->combined_pk,jitem(params,2)) < 0 ) + return(cclib_error(result,"error parsing combined_pubkey")); { - memcpy(MUSIG->pkhash,pkhash,sizeof(pkhash)); - memcpy(MUSIG->msg,msg,sizeof(msg)); + if ( musig_parsehash32(MUSIG->pkhash,jitem(params,3)) < 0 ) + return(cclib_error(result,"error parsing pkhash")); + if ( musig_parsehash32(MUSIG->msg,jitem(params,4)) < 0 ) + return(cclib_error(result,"error parsing msg")); Myprivkey(privkey); + GetRandBytes(session,32); + for (i=0; i<32; i++) + sprintf(&str[i<<1],"%02x",session[i]); + str[64] = 0; + fprintf(stderr,"session %s\n",str); /** Initializes a signing session for a signer * * Returns: 1: session is successfully initialized @@ -314,6 +336,7 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) */ if ( secp256k1_musig_session_initialize(ctx,&MUSIG->musig_session,MUSIG->signer_data, &MUSIG->nonce_commitments[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) { + memset(session,0,sizeof(session)); result.push_back(Pair("myind",(int64_t)myind)); result.push_back(Pair("numsigners",(int64_t)num)); for (i=0; i<32; i++) @@ -322,7 +345,12 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) result.push_back(Pair("commitment",str)); result.push_back(Pair("result","success")); return(result); - } else return(cclib_error(result,"couldnt initialize session")); + } + else + { + memset(session,0,sizeof(session)); + return(cclib_error(result,"couldnt initialize session")); + } } else return(cclib_error(result,"couldnt parse combined pubkey")); } else return(cclib_error(result,"wrong number of params, need 5: myindex, numsigners, combined_pk, pkhash, msg32")); } From 101a4153799c06ce3efc6705286c36184c3c383b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 22:05:27 -1100 Subject: [PATCH 29/50] Fix --- src/cc/musig.cpp | 52 +++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index ccb554e0f..7b9510b2a 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -297,17 +297,12 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) MUSIG = musig_infocreate(myind,num); if ( musig_parsepubkey(ctx,MUSIG->combined_pk,jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing combined_pubkey")); - { - if ( musig_parsehash32(MUSIG->pkhash,jitem(params,3)) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - if ( musig_parsehash32(MUSIG->msg,jitem(params,4)) < 0 ) - return(cclib_error(result,"error parsing msg")); - Myprivkey(privkey); - GetRandBytes(session,32); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",session[i]); - str[64] = 0; - fprintf(stderr,"session %s\n",str); + else if ( musig_parsehash32(MUSIG->pkhash,jitem(params,3)) < 0 ) + return(cclib_error(result,"error parsing pkhash")); + else if ( musig_parsehash32(MUSIG->msg,jitem(params,4)) < 0 ) + return(cclib_error(result,"error parsing msg")); + Myprivkey(privkey); + GetRandBytes(session,32); /** Initializes a signing session for a signer * * Returns: 1: session is successfully initialized @@ -334,24 +329,23 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * my_index: index of this signer in the signers array * seckey: the signer's 32-byte secret key (cannot be NULL) */ - if ( secp256k1_musig_session_initialize(ctx,&MUSIG->musig_session,MUSIG->signer_data, &MUSIG->nonce_commitments[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) - { - memset(session,0,sizeof(session)); - result.push_back(Pair("myind",(int64_t)myind)); - result.push_back(Pair("numsigners",(int64_t)num)); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",MUSIG->nonce_commitments[MUSIG->myind*32 + i]); - str[64] = 0; - result.push_back(Pair("commitment",str)); - result.push_back(Pair("result","success")); - return(result); - } - else - { - memset(session,0,sizeof(session)); - return(cclib_error(result,"couldnt initialize session")); - } - } else return(cclib_error(result,"couldnt parse combined pubkey")); + if ( secp256k1_musig_session_initialize(ctx,&MUSIG->musig_session,MUSIG->signer_data, &MUSIG->nonce_commitments[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) + { + memset(session,0,sizeof(session)); + result.push_back(Pair("myind",(int64_t)myind)); + result.push_back(Pair("numsigners",(int64_t)num)); + for (i=0; i<32; i++) + sprintf(&str[i<<1],"%02x",MUSIG->nonce_commitments[MUSIG->myind*32 + i]); + str[64] = 0; + result.push_back(Pair("commitment",str)); + result.push_back(Pair("result","success")); + return(result); + } + else + { + memset(session,0,sizeof(session)); + return(cclib_error(result,"couldnt initialize session")); + } } else return(cclib_error(result,"wrong number of params, need 5: myindex, numsigners, combined_pk, pkhash, msg32")); } From eb09e81eaedefc639bb3ea61729066e3b33224b4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 23:29:46 -1100 Subject: [PATCH 30/50] Musig commitment, nonce and partial sig roc --- src/cc/cclib.cpp | 20 +- src/cc/musig.cpp | 231 +++++++++++-------- src/secp256k1/include/secp256k1_musig.h | 84 ++++++- src/secp256k1/include/secp256k1_schnorrsig.h | 14 +- 4 files changed, 226 insertions(+), 123 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index bfd57e61d..ec74877b6 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -72,12 +72,11 @@ CClib_methods[] = { (char *)"sudoku", (char *)"pending", (char *)"", 0, 0, 'U', EVAL_SUDOKU }, { (char *)"sudoku", (char *)"solution", (char *)"txid solution timestamps[81]", 83, 83, 'S', EVAL_SUDOKU }, { (char *)"musig", (char *)"calcmsg", (char *)"sendtxid scriptPubKey", 2, 2, 'C', EVAL_MUSIG }, - { (char *)"musig", (char *)"combine", (char *)"pubkeys ...", 2, 256, 'P', EVAL_MUSIG }, - { (char *)"musig", (char *)"session", (char *)"msg pkhash", 2, 2, 'R', EVAL_MUSIG }, - { (char *)"musig", (char *)"commit", (char *)"pubkeys ...", 2, 256, 'H', EVAL_MUSIG }, - { (char *)"musig", (char *)"nonce", (char *)"pubkeys ...", 2, 256, 'N', EVAL_MUSIG }, - { (char *)"musig", (char *)"partialsign", (char *)"pubkeys ...", 2, 256, 'S', EVAL_MUSIG }, - { (char *)"musig", (char *)"sigcombine", (char *)"pubkeys ...", 2, 256, 'M', EVAL_MUSIG }, + { (char *)"musig", (char *)"combine", (char *)"pubkeys ...", 2, 999999999, 'P', EVAL_MUSIG }, + { (char *)"musig", (char *)"session", (char *)"myindex,numsigners,combined_pk,pkhash,msg32", 5, 5, 'R', EVAL_MUSIG }, + { (char *)"musig", (char *)"commit", (char *)"pkhash,ind,commitment", 3, 3, 'H', EVAL_MUSIG }, + { (char *)"musig", (char *)"nonce", (char *)"pkhash,ind,nonce", 3, 3, 'N', EVAL_MUSIG }, + { (char *)"musig", (char *)"partialsig", (char *)"pkhash,ind,partialsig", 3, 3, 'S', EVAL_MUSIG }, { (char *)"musig", (char *)"verify", (char *)"msg sig pubkey", 3, 3, 'V', EVAL_MUSIG }, { (char *)"musig", (char *)"send", (char *)"combined_pk amount", 2, 2, 'x', EVAL_MUSIG }, { (char *)"musig", (char *)"spend", (char *)"sendtxid sig destpubkey", 3, 3, 'y', EVAL_MUSIG }, @@ -116,8 +115,7 @@ UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_partialsign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_sigcombine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue musig_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); @@ -229,10 +227,8 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr) return(musig_commit(txfee,cp,params)); else if ( strcmp(method,"nonce") == 0 ) // returns combined nonce if ready return(musig_nonce(txfee,cp,params)); - else if ( strcmp(method,"partialsign") == 0 ) - return(musig_partialsign(txfee,cp,params)); - else if ( strcmp(method,"sigcombine") == 0 ) - return(musig_sigcombine(txfee,cp,params)); + else if ( strcmp(method,"partialsig") == 0 ) + return(musig_partialsig(txfee,cp,params)); else if ( strcmp(method,"verify") == 0 ) return(musig_verify(txfee,cp,params)); else if ( strcmp(method,"send") == 0 ) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 7b9510b2a..f6a7bf7b7 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -20,6 +20,7 @@ "combined_pk": "032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b", "result": "success" } + the combined_pk and pkhash will be needed for various other rpc calls */ /* second, send 0.777 coins to the combined_pk @@ -55,6 +56,33 @@ "result": "success", "msg": "63b799913d4c9487f321b32d6ae8614f653f38e0b50d4df4bc1d36339ea18485" } +the "msg" is what needs to be signed to create a valid spend + + now on each signing node, a session needs to be created: + 5 args: ind, numsigners, combined_pk, pkhash, message to be signed + + on node with pubkey: 02aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848 + ./c cclib session 18 \"[0,2,%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,%2263b799913d4c9487f321b32d6ae8614f653f38e0b50d4df4bc1d36339ea18485%22]\" + { + "myind": 0, + "numsigners": 2, + "commitment": "053a97ba56b1b8adf174a0a28dc16b1bb4e91a33ca0b52a579ce9ba4af299973", + "result": "success" + } + + on node with pubkey: 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 + ./c cclib session 18 \"[1,2,%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,%2263b799913d4c9487f321b32d6ae8614f653f38e0b50d4df4bc1d36339ea18485%22]\" + { + "myind": 1, + "numsigners": 2, + "commitment": "8c8dc6717aaa1994d4a51d1094c0c5cbfaf033c11642dbeeab32a32de4cfbc86", + "result": "success" + } + + now we need to get the commitment from each node to the other one. the session already put the commitment for each node into the global struct. Keep in mind there is a single global struct with session unique to each cclib session call. that means no restarting any deamon in the middle of the process on any of the nodes and only call cclib session a single time. this is an artificial restriction just to simplify the initial implementation of musig + + ./c cclib commitment 18 \"[1,%228c8dc6717aaa1994d4a51d1094c0c5cbfaf033c11642dbeeab32a32de4cfbc86%22]\" + ./c cclib commitment 18 \"[0,%22053a97ba56b1b8adf174a0a28dc16b1bb4e91a33ca0b52a579ce9ba4af299973%22]\" */ @@ -91,9 +119,9 @@ extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, struct musig_info { - secp256k1_musig_session musig_session; + secp256k1_musig_session session; secp256k1_pubkey combined_pk; - uint8_t *nonce_commitments; // 32*N_SIGNERS + uint8_t *nonce_commitments,**commitment_ptrs; // 32*N_SIGNERS secp256k1_musig_session_signer_data *signer_data; //[N_SIGNERS]; secp256k1_pubkey *nonce; //[N_SIGNERS]; secp256k1_musig_partial_signature *partial_sig; //[N_SIGNERS]; @@ -103,9 +131,12 @@ struct musig_info struct musig_info *musig_infocreate(int32_t myind,int32_t num) { - struct musig_info *mp = (struct musig_info *)calloc(1,sizeof(*mp)); + int32_t i; struct musig_info *mp = (struct musig_info *)calloc(1,sizeof(*mp)); mp->myind = myind, mp->num = num; mp->nonce_commitments = (uint8_t *)calloc(num,32); + mp->commitment_ptrs = (uint8_t **)calloc(num,sizeof(*mp->commitment_ptrs)); + for (i=0; icommitment_ptrs[i] = &mp->nonce_commitments[i*32]; mp->signer_data = (secp256k1_musig_session_signer_data *)calloc(num,sizeof(*mp->signer_data)); mp->nonce = (secp256k1_pubkey *)calloc(num,sizeof(*mp->nonce)); mp->partial_sig = (secp256k1_musig_partial_signature *)calloc(num,sizeof(*mp->partial_sig)); @@ -134,6 +165,11 @@ void musig_infofree(struct musig_info *mp) GetRandBytes((uint8_t *)mp->nonce_commitments,mp->num*32); free(mp->nonce_commitments); } + if ( mp->commitment_ptrs != 0 ) + { + GetRandBytes((uint8_t *)mp->commitment_ptrs,mp->num*sizeof(*mp->commitment_ptrs)); + free(mp->commitment_ptrs); + } GetRandBytes((uint8_t *)mp,sizeof(*mp)); free(mp); } @@ -329,7 +365,7 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * my_index: index of this signer in the signers array * seckey: the signer's 32-byte secret key (cannot be NULL) */ - if ( secp256k1_musig_session_initialize(ctx,&MUSIG->musig_session,MUSIG->signer_data, &MUSIG->nonce_commitments[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) + if ( secp256k1_musig_session_initialize(ctx,&MUSIG->session,MUSIG->signer_data, &MUSIG->nonce_commitments[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) { memset(session,0,sizeof(session)); result.push_back(Pair("myind",(int64_t)myind)); @@ -352,14 +388,19 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t n; + UniValue result(UniValue::VOBJ); int32_t n,ind; uint8_t pkhash[32]; CPubKey pk; char str[67]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { - // pkhash, ind, commitment - // if all commitments, emit nonce, else just update MUSIG-> - + if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) + return(cclib_error(result,"error parsing pkhash")); + else if ( memcmp(MUSING->pkhash,pkhash,32) != 0 ) + return(cclib_error(result,"pkhash doesnt match session pkhash")); + else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) + return(cclib_error(result,"illegal ind for session")); + else if ( musig_parsehash32(&MUSIG->commitment[ind*32],jitem(params,2)) < 0 ) + return(cclib_error(result,"error parsing commitment")); /** Gets the signer's public nonce given a list of all signers' data with commitments * * Returns: 1: public nonce is written in nonce @@ -375,27 +416,44 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * n_commitments: the length of commitments and signers array. Must be the total * number of signers participating in the MuSig. */ - // Set nonce commitments in the signer data and get the own public nonce - //if (secp256k1_musig_session_get_public_nonce(ctx, &musig_session[i], signer_data[i], &nonce[i], nonce_commitment_ptr, N_SIGNERS) > 0 ) + result.push_back(Pair("added_index",ind)); + if ( secp256k1_musig_session_get_public_nonce(ctx,&MUSIG->session,MUSIG->signer_data,&MUSIG->nonces[MUSIG->myind],MUSIG->nonce_commitments,MUSIG->num) > 0 ) { - // publish nonce + if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG->nonces[MUSIG->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) + { + for (i=0; i<33; i++) + sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]); + str[66] = 0; + result.push_back(Pair("nonce",str)); + result.push_back(Pair("result","success")); + } else return(cclib_error(result,"error serializing nonce (pubkey)")); + } + else + { + result.push_back(Pair("status","not enough commitments")); result.push_back(Pair("result","success")); } - // return 0; + return(result); } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, commitment")); } UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t n; + UniValue result(UniValue::VOBJ); int32_t i,n,ind; uint8_t pkhash[32],psig[32]; CPubKey pk; char str[67]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { - // pkhash, ind, nonce - // if all nonces, combine nonce, else just update MUSIG-> - result.push_back(Pair("result","success")); + if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) + return(cclib_error(result,"error parsing pkhash")); + else if ( memcmp(MUSING->pkhash,pkhash,32) != 0 ) + return(cclib_error(result,"pkhash doesnt match session pkhash")); + else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) + return(cclib_error(result,"illegal ind for session")); + else if ( musig_parsepubkey(ctx,&MUSIG->nonces[ind],jitem(params,2)) < 0 ) + return(cclib_error(result,"error parsing nonce")); + result.push_back(Pair("added_index",ind)); /** Checks a signer's public nonce against a commitment to said nonce, and update * data structure if they match * @@ -407,9 +465,11 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * with `musig_session_initialize_verifier`. * In: nonce: signer's alleged public nonce (cannot be NULL) */ - //if (!secp256k1_musig_set_nonce(ctx, &signer_data[i][j], &nonce[j])) { - - + for (i=0; inum; i++) + { + if ( secp256k1_musig_set_nonce(ctx,&MUSIG->signer_data[i],&MUSIG->nonces[i]) == 0 ) + return(cclib_error(result,"error setting nonce")); + } /** Updates a session with the combined public nonce of all signers. The combined * public nonce is the sum of every signer's public nonce. * @@ -428,91 +488,68 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * adaptor: point to add to the combined public nonce. If NULL, nothing is * added to the combined nonce. */ - // after all nonces: if (!secp256k1_musig_session_combine_nonces(ctx, &musig_session[i], signer_data[i], N_SIGNERS, NULL, NULL)) { - return(result); + if ( secp256k1_musig_session_combine_nonces(ctx,&MUSIG->session,MUSIG->signer_data,MUSIG->num,NULL,NULL) > 0 ) + { + if ( secp256k1_musig_partial_sign(ctx,&MUSIG->session,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + { + if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + { + result.push_back(Pair("myind",ind)); + for (i=0; i<32; i++) + sprintf(&str[i<<1],"%02x",psig[i]); + str[64] = 0; + result.push_back(Pair("partialsig",str)); + result.push_back(Pair("result","success")); + return(result); + } else return(cclib_error(result,"error serializing partial sig")); + } else return(cclib_error(result,"error making partial sig")); + } else return(cclib_error(result,"error combining nonces")); } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, nonce")); } -UniValue musig_partialsign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t n; + UniValue result(UniValue::VOBJ); int32_t ind,n; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { - // similar to commit/nonce - } - result.push_back(Pair("result","success")); - /** Produces a partial signature - * - * Returns: 1: partial signature constructed - * 0: session in incorrect or inconsistent state - * Args: ctx: pointer to a context object (cannot be NULL) - * session: active signing session for which the combined nonce has been - * computed (cannot be NULL) - * Out: partial_sig: partial signature (cannot be NULL) - */ - //if (!secp256k1_musig_partial_sign(ctx, &musig_session[i], &partial_sig[i])) { - /** Parse and verify a MuSig partial signature. - * - * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: pointer to a signature object - * In: in32: pointer to the 32-byte signature to be parsed - * - * After the call, sig will always be initialized. If parsing failed or the - * encoded numbers are out of range, signature verification with it is - * guaranteed to fail for every message and public key. - */ - //SECP256K1_API int secp256k1_musig_partial_signature_parse( - - return(result); -} - -UniValue musig_sigcombine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t n; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - // finally! - } - result.push_back(Pair("result","success")); - /** Checks that an individual partial signature verifies - * - * This function is essential when using protocols with adaptor signatures. - * However, it is not essential for regular MuSig's, in the sense that if any - * partial signatures does not verify, the full signature will also not verify, so the - * problem will be caught. But this function allows determining the specific party - * who produced an invalid signature, so that signing can be restarted without them. - * - * Returns: 1: partial signature verifies - * 0: invalid signature or bad data - * Args: ctx: pointer to a context object (cannot be NULL) - * session: active session for which the combined nonce has been computed - * (cannot be NULL) - * signer: data for the signer who produced this signature (cannot be NULL) - * In: partial_sig: signature to verify (cannot be NULL) - * pubkey: public key of the signer who produced the signature (cannot be NULL) - */ - //if (!secp256k1_musig_partial_sig_verify(ctx, &musig_session[i], &signer_data[i][j], &partial_sig[j], &pubkeys[j])) { - return 0; - /** Combines partial signatures - * - * Returns: 1: all partial signatures have values in range. Does NOT mean the - * resulting signature verifies. - * 0: some partial signature had s/r out of range - * Args: ctx: pointer to a context object (cannot be NULL) - * session: initialized session for which the combined nonce has been - * computed (cannot be NULL) - * Out: sig: complete signature (cannot be NULL) - * In: partial_sigs: array of partial signatures to combine (cannot be NULL) - * n_sigs: number of signatures in the partial_sigs array - */ - // after all partials: return secp256k1_musig_partial_sig_combine(ctx, &musig_session[0], sig, partial_sig, N_SIGNERS return(result); + if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) + return(cclib_error(result,"error parsing pkhash")); + else if ( memcmp(MUSING->pkhash,pkhash,32) != 0 ) + return(cclib_error(result,"pkhash doesnt match session pkhash")); + else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) + return(cclib_error(result,"illegal ind for session")); + else if ( musig_parsepartial(ctx,&MUSIG->partial_sig[ind],jitem(params,2)) < 0 ) + return(cclib_error(result,"error parsing partialsig")); + result.push_back(Pair("added_index",ind)); + if (secp256k1_musig_partial_sig_combine(ctx,&MUSIG->session,&sig,MUSIG->partial_sig,MUSIG->num) > 0 ) + { + if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 ) + { + result.push_back(Pair("result","success")); + for (i=0; i<64; i++) + sprintf(&str[i<<1],"%02x",out64[i]); + str[128] = 0; + result.push_back(Pair("combinedsig",str)); + } else return(cclib_error(result,"error serializing combinedsig")); + } + else + { + if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + { + result.push_back(Pair("myind",ind)); + for (i=0; i<32; i++) + sprintf(&str[i<<1],"%02x",psig[i]); + str[64] = 0; + result.push_back(Pair("partialsig",str)); + result.push_back(Pair("result","success")); + result.push_back(Pair("status","need more partialsigs")); + } else return(cclib_error(result,"error generating my partialsig")); + } + return(result); + } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, partialsig")); } UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) diff --git a/src/secp256k1/include/secp256k1_musig.h b/src/secp256k1/include/secp256k1_musig.h index a0106e691..84106822a 100644 --- a/src/secp256k1/include/secp256k1_musig.h +++ b/src/secp256k1/include/secp256k1_musig.h @@ -206,7 +206,12 @@ SECP256K1_API * n_commitments: the length of commitments and signers array. Must be the total * number of signers participating in the MuSig. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_public_nonce( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_public_nonce( const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, @@ -235,7 +240,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_publi * participating in the MuSig. Must be greater than 0 and at most * 2^32 - 1. */ -SECP256K1_API int secp256k1_musig_session_initialize_verifier( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_session_initialize_verifier( const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, @@ -257,7 +267,12 @@ SECP256K1_API int secp256k1_musig_session_initialize_verifier( * with `musig_session_initialize_verifier`. * In: nonce: signer's alleged public nonce (cannot be NULL) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce( const secp256k1_context* ctx, secp256k1_musig_session_signer_data *signer, const secp256k1_pubkey *nonce @@ -281,7 +296,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce( * adaptor: point to add to the combined public nonce. If NULL, nothing is * added to the combined nonce. */ -SECP256K1_API int secp256k1_musig_session_combine_nonces( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_session_combine_nonces( const secp256k1_context* ctx, secp256k1_musig_session *session, const secp256k1_musig_session_signer_data *signers, @@ -298,7 +318,12 @@ SECP256K1_API int secp256k1_musig_session_combine_nonces( * session: the session structure to update with the message (cannot be NULL) * In: msg32: the 32-byte message to be signed (cannot be NULL) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_set_msg( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_set_msg( const secp256k1_context* ctx, secp256k1_musig_session *session, const unsigned char *msg32 @@ -311,7 +336,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_set_msg( * Out: out32: pointer to a 32-byte array to store the serialized signature * In: sig: pointer to the signature */ -SECP256K1_API int secp256k1_musig_partial_signature_serialize( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_partial_signature_serialize( const secp256k1_context* ctx, unsigned char *out32, const secp256k1_musig_partial_signature* sig @@ -328,7 +358,12 @@ SECP256K1_API int secp256k1_musig_partial_signature_serialize( * encoded numbers are out of range, signature verification with it is * guaranteed to fail for every message and public key. */ -SECP256K1_API int secp256k1_musig_partial_signature_parse( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_partial_signature_parse( const secp256k1_context* ctx, secp256k1_musig_partial_signature* sig, const unsigned char *in32 @@ -343,7 +378,12 @@ SECP256K1_API int secp256k1_musig_partial_signature_parse( * computed (cannot be NULL) * Out: partial_sig: partial signature (cannot be NULL) */ -SECP256K1_API int secp256k1_musig_partial_sign( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_partial_sign( const secp256k1_context* ctx, const secp256k1_musig_session *session, secp256k1_musig_partial_signature *partial_sig @@ -366,7 +406,12 @@ SECP256K1_API int secp256k1_musig_partial_sign( * In: partial_sig: signature to verify (cannot be NULL) * pubkey: public key of the signer who produced the signature (cannot be NULL) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify( const secp256k1_context* ctx, const secp256k1_musig_session *session, const secp256k1_musig_session_signer_data *signer, @@ -386,7 +431,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verif * In: partial_sigs: array of partial signatures to combine (cannot be NULL) * n_sigs: number of signatures in the partial_sigs array */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combine( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combine( const secp256k1_context* ctx, const secp256k1_musig_session *session, secp256k1_schnorrsig *sig, @@ -406,7 +456,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combi * be NULL) * nonce_is_negated: the `nonce_is_negated` output of `musig_session_combine_nonces` */ -SECP256K1_API int secp256k1_musig_partial_sig_adapt( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + int secp256k1_musig_partial_sig_adapt( const secp256k1_context* ctx, secp256k1_musig_partial_signature *adaptor_sig, const secp256k1_musig_partial_signature *partial_sig, @@ -429,7 +484,12 @@ SECP256K1_API int secp256k1_musig_partial_sig_adapt( * n_partial_sigs: number of elements in partial_sigs array * nonce_is_negated: the `nonce_is_negated` output of `musig_session_combine_nonces` */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_secret_adaptor( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif + SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_secret_adaptor( const secp256k1_context* ctx, unsigned char *sec_adaptor32, const secp256k1_schnorrsig *sig, diff --git a/src/secp256k1/include/secp256k1_schnorrsig.h b/src/secp256k1/include/secp256k1_schnorrsig.h index 9dea16653..e4d02f34f 100644 --- a/src/secp256k1/include/secp256k1_schnorrsig.h +++ b/src/secp256k1/include/secp256k1_schnorrsig.h @@ -28,7 +28,12 @@ typedef struct { * * See secp256k1_schnorrsig_parse for details about the encoding. */ -SECP256K1_API int secp256k1_schnorrsig_serialize( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif +int secp256k1_schnorrsig_serialize( const secp256k1_context* ctx, unsigned char *out64, const secp256k1_schnorrsig* sig @@ -50,7 +55,12 @@ SECP256K1_API int secp256k1_schnorrsig_serialize( * encoded numbers are out of range, signature validation with it is * guaranteed to fail for every message and public key. */ -SECP256K1_API int secp256k1_schnorrsig_parse( +#ifdef __cplusplus +extern "C" +#else +SECP256K1_API +#endif +int secp256k1_schnorrsig_parse( const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64 From 141790634d27cc0461329d2261859c54ec3bebfa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 23:33:13 -1100 Subject: [PATCH 31/50] Syntax --- src/cc/musig.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index f6a7bf7b7..8696809da 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -123,7 +123,7 @@ struct musig_info secp256k1_pubkey combined_pk; uint8_t *nonce_commitments,**commitment_ptrs; // 32*N_SIGNERS secp256k1_musig_session_signer_data *signer_data; //[N_SIGNERS]; - secp256k1_pubkey *nonce; //[N_SIGNERS]; + secp256k1_pubkey *nonces; //[N_SIGNERS]; secp256k1_musig_partial_signature *partial_sig; //[N_SIGNERS]; int32_t myind,num; uint8_t msg[32],pkhash[32],combpk[33]; @@ -138,7 +138,7 @@ struct musig_info *musig_infocreate(int32_t myind,int32_t num) for (i=0; icommitment_ptrs[i] = &mp->nonce_commitments[i*32]; mp->signer_data = (secp256k1_musig_session_signer_data *)calloc(num,sizeof(*mp->signer_data)); - mp->nonce = (secp256k1_pubkey *)calloc(num,sizeof(*mp->nonce)); + mp->nonces = (secp256k1_pubkey *)calloc(num,sizeof(*mp->nonces)); mp->partial_sig = (secp256k1_musig_partial_signature *)calloc(num,sizeof(*mp->partial_sig)); return(mp); } @@ -150,10 +150,10 @@ void musig_infofree(struct musig_info *mp) GetRandBytes((uint8_t *)mp->partial_sig,mp->num*sizeof(*mp->partial_sig)); free(mp->partial_sig); } - if ( mp->nonce != 0 ) + if ( mp->nonces != 0 ) { - GetRandBytes((uint8_t *)mp->nonce,mp->num*sizeof(*mp->nonce)); - free(mp->nonce); + GetRandBytes((uint8_t *)mp->nonces,mp->num*sizeof(*mp->nonces)); + free(mp->nonces); } if ( mp->signer_data != 0 ) { @@ -388,14 +388,14 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t n,ind; uint8_t pkhash[32]; CPubKey pk; char str[67]; + UniValue result(UniValue::VOBJ); int32_t i,n,ind; uint8_t pkhash[32]; CPubKey pk; char str[67]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSING->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); @@ -424,6 +424,7 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) for (i=0; i<33; i++) sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]); str[66] = 0; + result.push_back(Pair("myind",MUSIG->myind)); result.push_back(Pair("nonce",str)); result.push_back(Pair("result","success")); } else return(cclib_error(result,"error serializing nonce (pubkey)")); @@ -447,7 +448,7 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSING->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); @@ -498,6 +499,7 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) for (i=0; i<32; i++) sprintf(&str[i<<1],"%02x",psig[i]); str[64] = 0; + result.push_back(Pair("myind",MUSIG->myind)); result.push_back(Pair("partialsig",str)); result.push_back(Pair("result","success")); return(result); @@ -510,14 +512,14 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t ind,n; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; + UniValue result(UniValue::VOBJ); int32_t i,ind,n; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSING->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); From 3d99ab8a66a0de574abfd066ff6980390734f860 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 23:39:37 -1100 Subject: [PATCH 32/50] Fix --- src/cc/musig.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 8696809da..2d4002059 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -388,6 +388,7 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; + size_t clen = CPubKey::PUBLIC_KEY_SIZE; UniValue result(UniValue::VOBJ); int32_t i,n,ind; uint8_t pkhash[32]; CPubKey pk; char str[67]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); @@ -399,7 +400,7 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsehash32(&MUSIG->commitment[ind*32],jitem(params,2)) < 0 ) + else if ( musig_parsehash32(&MUSIG->nonce_commitments[ind*32],jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing commitment")); /** Gets the signer's public nonce given a list of all signers' data with commitments * @@ -417,7 +418,7 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * number of signers participating in the MuSig. */ result.push_back(Pair("added_index",ind)); - if ( secp256k1_musig_session_get_public_nonce(ctx,&MUSIG->session,MUSIG->signer_data,&MUSIG->nonces[MUSIG->myind],MUSIG->nonce_commitments,MUSIG->num) > 0 ) + if ( secp256k1_musig_session_get_public_nonce(ctx,&MUSIG->session,MUSIG->signer_data,&MUSIG->nonces[MUSIG->myind],MUSIG->commitment_ptrs,MUSIG->num) > 0 ) { if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG->nonces[MUSIG->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) { @@ -452,7 +453,7 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsepubkey(ctx,&MUSIG->nonces[ind],jitem(params,2)) < 0 ) + else if ( musig_parsepubkey(ctx,MUSIG->nonces[ind],jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing nonce")); result.push_back(Pair("added_index",ind)); /** Checks a signer's public nonce against a commitment to said nonce, and update @@ -523,7 +524,9 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsepartial(ctx,&MUSIG->partial_sig[ind],jitem(params,2)) < 0 ) + else if ( musig_parsehash32(ctx,psig,jitem(params,2)) < 0 ) + return(cclib_error(result,"error parsing psig")); + else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG->partial_sig[ind],psig) == 0 ) return(cclib_error(result,"error parsing partialsig")); result.push_back(Pair("added_index",ind)); if (secp256k1_musig_partial_sig_combine(ctx,&MUSIG->session,&sig,MUSIG->partial_sig,MUSIG->num) > 0 ) From b17065ce1762782a13ab6205c06bd20df5a644ba Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 23:41:10 -1100 Subject: [PATCH 33/50] extern "C" --- src/cc/musig.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 2d4002059..03eb01e3e 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -113,6 +113,7 @@ extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const s extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64); extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys); extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, unsigned char *nonce_commitment32, const unsigned char *session_id32, const unsigned char *msg32, const secp256k1_pubkey *combined_pk, const unsigned char *pk_hash32, size_t n_signers, size_t my_index, const unsigned char *seckey); +extern "C" int secp256k1_schnorrsig_serialize(const secp256k1_context* ctx, unsigned char *out64, const secp256k1_schnorrsig* sig); #define MUSIG_PREVN 0 // for now, just use vout0 for the musig output #define MUSIG_TXFEE 10000 @@ -524,12 +525,12 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsehash32(ctx,psig,jitem(params,2)) < 0 ) + else if ( musig_parsehash32(psig,jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing psig")); else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG->partial_sig[ind],psig) == 0 ) return(cclib_error(result,"error parsing partialsig")); result.push_back(Pair("added_index",ind)); - if (secp256k1_musig_partial_sig_combine(ctx,&MUSIG->session,&sig,MUSIG->partial_sig,MUSIG->num) > 0 ) + if ( secp256k1_musig_partial_sig_combine(ctx,&MUSIG->session,&sig,MUSIG->partial_sig,MUSIG->num) > 0 ) { if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 ) { From c07c6724b2d05dac81104b69a53f8fc23c49b845 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 23:52:20 -1100 Subject: [PATCH 34/50] Rpc examples to make a combined signature "combinedsig": "bc0062cd3233433e098fbf4f3c333946779c3dccfaefc423243e3f90edfdf9a6dbfabf4 2d26f3c668fe6e10f1ed367a46dfddbafaee82b3eb79722ae49f45320" --- src/cc/musig.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 03eb01e3e..4f08dd4cf 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -66,7 +66,7 @@ the "msg" is what needs to be signed to create a valid spend { "myind": 0, "numsigners": 2, - "commitment": "053a97ba56b1b8adf174a0a28dc16b1bb4e91a33ca0b52a579ce9ba4af299973", + "commitment": "89af8f6db69fc3d4b95480a914dceba9933039e9823151a82677c3ca4e961fcc", "result": "success" } @@ -75,15 +75,73 @@ the "msg" is what needs to be signed to create a valid spend { "myind": 1, "numsigners": 2, - "commitment": "8c8dc6717aaa1994d4a51d1094c0c5cbfaf033c11642dbeeab32a32de4cfbc86", + "commitment": "a43da5ef8322abb43b9fddadef7b6479baf7853e860f915e01521e3060e5342b", "result": "success" } now we need to get the commitment from each node to the other one. the session already put the commitment for each node into the global struct. Keep in mind there is a single global struct with session unique to each cclib session call. that means no restarting any deamon in the middle of the process on any of the nodes and only call cclib session a single time. this is an artificial restriction just to simplify the initial implementation of musig - ./c cclib commitment 18 \"[1,%228c8dc6717aaa1994d4a51d1094c0c5cbfaf033c11642dbeeab32a32de4cfbc86%22]\" - ./c cclib commitment 18 \"[0,%22053a97ba56b1b8adf174a0a28dc16b1bb4e91a33ca0b52a579ce9ba4af299973%22]\" + ./c cclib commit 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%22a43da5ef8322abb43b9fddadef7b6479baf7853e860f915e01521e3060e5342b%22]\" + { + "added_index": 1, + "myind": 0, + "nonce": "03bf28874f5e5dccf55170406d58ded84ac6ca713011d718c6048400d700cb879a", + "result": "success" + } + + ./c cclib commit 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%2289af8f6db69fc3d4b95480a914dceba9933039e9823151a82677c3ca4e961fcc%22]\" + { + "added_index": 0, + "myind": 1, + "nonce": "039ae1f542e8f0f6d03d734dc2295651973e1b7fa99508e2f36dad5d21f09889f6", + "result": "success" + } + + Now exchange the revealed nonces to each node: + + ./c cclib nonce 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%22039ae1f542e8f0f6d03d734dc2295651973e1b7fa99508e2f36dad5d21f09889f6%22]\" + { + "added_index": 1, + "myind": 0, + "partialsig": "5da4c1ec828cd1563bc6554aa74c90c29fcd38b2aea26f7fa92e0d007aa9463f", + "result": "success" + } + + ./c cclib nonce 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%2203bf28874f5e5dccf55170406d58ded84ac6ca713011d718c6048400d700cb879a%22]\" + { + "added_index": 0, + "myind": 1, + "partialsig": "7e55fd564fe26b1054208bc47786d6e1ce30a2fd0045bbbf0e6915adcf4b0ce1", + "result": "success" + } + + Almost there! final step is to exchange the partial sigs between signers + ./c cclib partialsig 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%227e55fd564fe26b1054208bc47786d6e1ce30a2fd0045bbbf0e6915adcf4b0ce1%22]\" + { + "added_index": 1, + "result": "success", + "combinedsig": "bc0062cd3233433e098fbf4f3c333946779c3dccfaefc423243e3f90edfdf9a6dbfabf42d26f3c668fe6e10f1ed367a46dfddbafaee82b3eb79722ae49f45320" + } + + ./c cclib partialsig 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%225da4c1ec828cd1563bc6554aa74c90c29fcd38b2aea26f7fa92e0d007aa9463f%22]\" + + { + "added_index": 0, + "result": "success", + "combinedsig": "bc0062cd3233433e098fbf4f3c333946779c3dccfaefc423243e3f90edfdf9a6dbfabf42d26f3c668fe6e10f1ed367a46dfddbafaee82b3eb79722ae49f45320" + } + + Notice both nodes generated the same combined signature! + + Now for a sanity test, we can use the verify call to make sure this sig will work with the msg needed for the spend: + + xxxx + + + and finally the spend: + + */ @@ -497,7 +555,6 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) { - result.push_back(Pair("myind",ind)); for (i=0; i<32; i++) sprintf(&str[i<<1],"%02x",psig[i]); str[64] = 0; From 925eaa285162afaeed9396aced6413ed38c61a62 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 23:57:30 -1100 Subject: [PATCH 35/50] Test --- src/cc/musig.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 4f08dd4cf..6b2e7abca 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -139,9 +139,9 @@ the "msg" is what needs to be signed to create a valid spend xxxx - and finally the spend: - + and finally the spend: sendtxid, scriptPubKey, musig +./c cclib spend 18 \"[%22cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be%22,%222102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac%22,%22bc0062cd3233433e098fbf4f3c333946779c3dccfaefc423243e3f90edfdf9a6dbfabf42d26f3c668fe6e10f1ed367a46dfddbafaee82b3eb79722ae49f45320%22]\" */ @@ -696,6 +696,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) prevhash = juint256(jitem(params,0)); scriptstr = jstr(jitem(params,1),0); musigstr = jstr(jitem(params,2),0); + printf("script.(%s) musig.(%s) %d\n",scriptstr,musigstr,(int32_t)strlen(musigstr)); if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) != 128 ) { if ( txfee == 0 ) @@ -723,7 +724,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) } else return(cclib_error(result,"couldnt decode send opret")); } else return(cclib_error(result,"couldnt find vin0")); } else return(cclib_error(result,"script or musig is not hex")); - } else return(cclib_error(result,"need to have exactly 3 params prevhash, scriptPubKey, musig")); + } else return(cclib_error(result,"need to have exactly 3 params sendtxid, scriptPubKey, musig")); } else return(cclib_error(result,"params parse error")); } From 748ab667e2d36b71c29d943b855d7dbbc07abd86 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 21 Feb 2019 23:59:42 -1100 Subject: [PATCH 36/50] Test --- src/cc/musig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 6b2e7abca..172958fba 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -696,7 +696,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) prevhash = juint256(jitem(params,0)); scriptstr = jstr(jitem(params,1),0); musigstr = jstr(jitem(params,2),0); - printf("script.(%s) musig.(%s) %d\n",scriptstr,musigstr,(int32_t)strlen(musigstr)); + printf("script.(%s) %d musig.(%s) %d\n",scriptstr,is_hexstr(scriptstr,0),musigstr,is_hexstr(musigstr,0)); if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) != 128 ) { if ( txfee == 0 ) From 3bea6f84e4c353df73316e8079e516a903461516 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:00:55 -1100 Subject: [PATCH 37/50] Fix --- src/cc/musig.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 172958fba..a690e4d01 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -696,8 +696,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) prevhash = juint256(jitem(params,0)); scriptstr = jstr(jitem(params,1),0); musigstr = jstr(jitem(params,2),0); - printf("script.(%s) %d musig.(%s) %d\n",scriptstr,is_hexstr(scriptstr,0),musigstr,is_hexstr(musigstr,0)); - if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) != 128 ) + if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) == 128 ) { if ( txfee == 0 ) txfee = MUSIG_TXFEE; From 33811cce5f78616998d2b7fe1a75714d028fae23 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:16:26 -1100 Subject: [PATCH 38/50] +print --- src/cc/musig.cpp | 64 ++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index a690e4d01..be4ff278e 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -26,8 +26,8 @@ /* second, send 0.777 coins to the combined_pk ./c cclib send 18 \"[%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,0.777]\" { - "hex": "0400008085202f8901bf7afcbbab7a5e1ba20c8010325e199305afa7d15b4bc86a589a512201d39924000000004847304402203e0cff8aaa831dd990afd979bbc0a648316f77407cb5e02780d18e0670f5172a0220283d5c52d0406b10c508cc2b19dd6dbe2420e7c5cf431a1d41072d0eec28edb901ffffffff03b0c2a10400000000302ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cca91e223700000000232102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac0000000000000000266a24127821032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b00000000900000000000000000000000000000", - "txid": "cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be", + "hex": "0400008085202f8908018bbc4a0acf0f896680b84cc1000ec5530042fa3cf7471ab5c11cde56f6d0e60000000048473044022041a900fa57e54f939b797d09f0cee81ab9a79d978cd473ef3fc9f09c7678ad6b02206386bd15ee7ee8224a984fdd1d2a094738d082aec06028a5846d7bc61ddf16ca01ffffffff0b969f0e1ea787f0cc4e81d128353bd1cb670ab89bd1db4b47fbb7e872cd39fb00000000494830450221008c5de4b196e57b0dd94aa415950adf274e3e6859b82cf218729af84c1f15e76c022024aeab7eda63e6a652ef488bf26a8dc4ef8d2d4aa5746726085bfe5f169a5db701ffffffff0b36b70b43457fab377f28fb22da5a3e9d8186a37daae18cf0f710a221ab26250000000048473044022004ec20ae7490e7adabf9a3f78e4a58df84a3245485bfdd40f421cafe61d19c340220456d2b6f3c6e88632027c02606a0af1c21208d05f2de0826fbf4dfe7391ec83901ffffffff0aaff3cfe4ca22b97b6179a6f7cfac91945e5440e9438b89d1ec09500167176a0000000048473044022074dcad30c8ab9ed79a3ac69169611fc9e5f4b76a561b183461d968249316997f022063b25decaa285f494d277b9c8c2bcf6445b7929a304542e89c0645828d30a1a901ffffffff090e1bb92e9bf404a0d6455701b21af3dbf6765e61a1dc28b7c0f608ec4f12da000000004847304402202f9182c532c66138a6bdfcbb85a06cf1bf1532f2bf8f63170ef20843e4a81d0202207612a4353eb9606e84621c444ec7db1b683ff29c56127bda2d5e9c0eb13dbbc001ffffffff08a57005c7a40a923b1a510820b07f7318d760fe2a233b077d918cce357ad3af00000000484730440220643d60c68634fb2e0f6656389fc70c9f84c7086fc6e35b0fa26297e844f6c5fc02201d79669e073efe738d47de0130fdcba875e284e18fd478c0e6834d46632d8b8101ffffffff068cfd0ea6c0f5d401c67ec38f92425a9e59b0d5ade55bb2971ea955675a17bd00000000484730440220747139724248da4bcc1e5e3828e0ea811756e1fad0ebc40aeb006fd8079d46e402200d8f1c229c79494b5617e4373a3e083966dcd74571323f9d334be901d53871fa01ffffffff0200382fb6984b6128bb75115346242809c6555274e0cacef822825a2b4d231700000000484730440220454fcac398f6913fb4d8ed330f110f9cf62eec6c8cdb67d5df1effd2cf8222d5022017f6323630669777573e342e870c88727a917cc06c33611ebbd9d1fccc1dcd3701ffffffff03b0c2a10400000000302ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cc40ca220000000000232102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac0000000000000000266a24127821032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b00000000460100000000000000000000000000", + "txid": "2c4159bb19212dcaa412ae37de7d72398f063194053e04a65b0facf767ebcc68", "result": "success" } @@ -46,92 +46,94 @@ } change script: 2102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac - sendtxid: cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be + sendtxid: 2c4159bb19212dcaa412ae37de7d72398f063194053e04a65b0facf767ebcc68 broadcast sendtxid and wait for it to be confirmed. then get the msg we need to sign: - ./c cclib calcmsg 18 \"[%22cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be%22,%222102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac%22]\" + ./c cclib calcmsg 18 \"[%222c4159bb19212dcaa412ae37de7d72398f063194053e04a65b0facf767ebcc68%22,%222102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac%22]\" { "result": "success", - "msg": "63b799913d4c9487f321b32d6ae8614f653f38e0b50d4df4bc1d36339ea18485" + "msg": "caa64ba398ddfe5c33d8c70a61e556caa0e69b19d93110c5a458a1b37ad44cb0" } + the "msg" is what needs to be signed to create a valid spend now on each signing node, a session needs to be created: 5 args: ind, numsigners, combined_pk, pkhash, message to be signed on node with pubkey: 02aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848 - ./c cclib session 18 \"[0,2,%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,%2263b799913d4c9487f321b32d6ae8614f653f38e0b50d4df4bc1d36339ea18485%22]\" + ./c cclib session 18 \"[0,2,%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,%22caa64ba398ddfe5c33d8c70a61e556caa0e69b19d93110c5a458a1b37ad44cb0%22]\" { "myind": 0, "numsigners": 2, - "commitment": "89af8f6db69fc3d4b95480a914dceba9933039e9823151a82677c3ca4e961fcc", + "commitment": "e82228c10d0e100477630349150dea744d3b2790dcd347511a1a98199840cda4", "result": "success" } on node with pubkey: 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 - ./c cclib session 18 \"[1,2,%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,%2263b799913d4c9487f321b32d6ae8614f653f38e0b50d4df4bc1d36339ea18485%22]\" + ./c cclib session 18 \"[1,2,%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,%22caa64ba398ddfe5c33d8c70a61e556caa0e69b19d93110c5a458a1b37ad44cb0%22]\" { "myind": 1, "numsigners": 2, - "commitment": "a43da5ef8322abb43b9fddadef7b6479baf7853e860f915e01521e3060e5342b", + "commitment": "6e426e850ddc45e7742cfb6321781c00ee69a995ab12fa1f9ded7fe43658babf", "result": "success" } now we need to get the commitment from each node to the other one. the session already put the commitment for each node into the global struct. Keep in mind there is a single global struct with session unique to each cclib session call. that means no restarting any deamon in the middle of the process on any of the nodes and only call cclib session a single time. this is an artificial restriction just to simplify the initial implementation of musig - ./c cclib commit 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%22a43da5ef8322abb43b9fddadef7b6479baf7853e860f915e01521e3060e5342b%22]\" + ./c cclib commit 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%226e426e850ddc45e7742cfb6321781c00ee69a995ab12fa1f9ded7fe43658babf%22]\" { "added_index": 1, "myind": 0, - "nonce": "03bf28874f5e5dccf55170406d58ded84ac6ca713011d718c6048400d700cb879a", + "nonce": "0261671b0a6de416938cf035c98f8af37c6ca88bbbd1bcce693d709d4919b010e1", "result": "success" } - ./c cclib commit 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%2289af8f6db69fc3d4b95480a914dceba9933039e9823151a82677c3ca4e961fcc%22]\" + ./c cclib commit 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%22e82228c10d0e100477630349150dea744d3b2790dcd347511a1a98199840cda4%22]\" { "added_index": 0, "myind": 1, - "nonce": "039ae1f542e8f0f6d03d734dc2295651973e1b7fa99508e2f36dad5d21f09889f6", + "nonce": "02570f62a625ceb19a754a053152b162810c3e403df63f3d443e85bdacc74bfdfe", "result": "success" } Now exchange the revealed nonces to each node: - ./c cclib nonce 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%22039ae1f542e8f0f6d03d734dc2295651973e1b7fa99508e2f36dad5d21f09889f6%22]\" + ./c cclib nonce 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%2202570f62a625ceb19a754a053152b162810c3e403df63f3d443e85bdacc74bfdfe%22]\" { "added_index": 1, "myind": 0, - "partialsig": "5da4c1ec828cd1563bc6554aa74c90c29fcd38b2aea26f7fa92e0d007aa9463f", + "partialsig": "3f21885e6d2d020e1473435ccd148a61cdcb1d1105867fed45913185dc0acf59", "result": "success" } - ./c cclib nonce 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%2203bf28874f5e5dccf55170406d58ded84ac6ca713011d718c6048400d700cb879a%22]\" + ./c cclib nonce 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%220261671b0a6de416938cf035c98f8af37c6ca88bbbd1bcce693d709d4919b010e1%22]\" { "added_index": 0, + "myind": 0, "myind": 1, - "partialsig": "7e55fd564fe26b1054208bc47786d6e1ce30a2fd0045bbbf0e6915adcf4b0ce1", + "partialsig": "af7f28455fb2e988d81068cd9d800879cd334036a8300118dc307b777a38c1ed", "result": "success" } Almost there! final step is to exchange the partial sigs between signers - ./c cclib partialsig 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%227e55fd564fe26b1054208bc47786d6e1ce30a2fd0045bbbf0e6915adcf4b0ce1%22]\" + ./c cclib partialsig 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,1,%22af7f28455fb2e988d81068cd9d800879cd334036a8300118dc307b777a38c1ed%22]\" { "added_index": 1, "result": "success", - "combinedsig": "bc0062cd3233433e098fbf4f3c333946779c3dccfaefc423243e3f90edfdf9a6dbfabf42d26f3c668fe6e10f1ed367a46dfddbafaee82b3eb79722ae49f45320" + "combinedsig": "5e64dc5dda93b2d3f25fe44b2aaca69b8f15d21f70e2bc1c2c53e17262d941bbeea0b0a3ccdfeb96ec83ac2a6a9492db9afe5d47adb6810621c1acfd56439146" } + - ./c cclib partialsig 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%225da4c1ec828cd1563bc6554aa74c90c29fcd38b2aea26f7fa92e0d007aa9463f%22]\" + ./c cclib partialsig 18 \"[%225be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba%22,0,%223f21885e6d2d020e1473435ccd148a61cdcb1d1105867fed45913185dc0acf59%22]\" { "added_index": 0, "result": "success", - "combinedsig": "bc0062cd3233433e098fbf4f3c333946779c3dccfaefc423243e3f90edfdf9a6dbfabf42d26f3c668fe6e10f1ed367a46dfddbafaee82b3eb79722ae49f45320" + "combinedsig": "5e64dc5dda93b2d3f25fe44b2aaca69b8f15d21f70e2bc1c2c53e17262d941bbeea0b0a3ccdfeb96ec83ac2a6a9492db9afe5d47adb6810621c1acfd56439146" } - Notice both nodes generated the same combined signature! Now for a sanity test, we can use the verify call to make sure this sig will work with the msg needed for the spend: @@ -141,7 +143,7 @@ the "msg" is what needs to be signed to create a valid spend and finally the spend: sendtxid, scriptPubKey, musig -./c cclib spend 18 \"[%22cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be%22,%222102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac%22,%22bc0062cd3233433e098fbf4f3c333946779c3dccfaefc423243e3f90edfdf9a6dbfabf42d26f3c668fe6e10f1ed367a46dfddbafaee82b3eb79722ae49f45320%22]\" +./c cclib spend 18 \"[%222c4159bb19212dcaa412ae37de7d72398f063194053e04a65b0facf767ebcc68%22,%222102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac%22,%225e64dc5dda93b2d3f25fe44b2aaca69b8f15d21f70e2bc1c2c53e17262d941bbeea0b0a3ccdfeb96ec83ac2a6a9492db9afe5d47adb6810621c1acfd56439146%22]\" */ @@ -686,7 +688,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,pk; secp256k1_pubkey combined_pk; char *scriptstr,*musigstr; uint8_t msg[32]; CTransaction vintx; uint256 prevhash,hashBlock; int32_t n,numvouts; CTxOut vout; secp256k1_schnorrsig musig; + UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,pk; secp256k1_pubkey combined_pk; char *scriptstr,*musigstr; uint8_t msg[32]; CTransaction vintx; uint256 prevhash,hashBlock; int32_t i,n,numvouts; char str[129]; CTxOut vout; secp256k1_schnorrsig musig; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) @@ -713,6 +715,20 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) secp256k1_ec_pubkey_parse(ctx,&combined_pk,pk.begin(),33) > 0 ) { musig_prevoutmsg(msg,prevhash,vout.scriptPubKey); + { + for (i=0; i<32; i++) + sprintf(&str[i*2],"%02x",msg[i]); + str[64] = 0; + result.push_back(Pair("msg",str)); + for (i=0; i<33; i++) + sprintf(&str[i*2],"%02x",((uint8_t *)pk.begin)[i]); + str[66] = 0; + result.push_back(Pair("combined_pk",str)); + for (i=0; i<64; i++) + sprintf(&str[i*2],"%02x",musig64[i]); + str[128] = 0; + result.push_back(Pair("combinedsig",str)); + } if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) ) return(cclib_error(result,"musig didnt validate")); mtx.vin.push_back(CTxIn(prevhash,MUSIG_PREVN)); From 8b8339b5b941963c6ea6331cf57af5c5edc2facc Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:17:05 -1100 Subject: [PATCH 39/50] () --- src/cc/musig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index be4ff278e..88bf62449 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -721,7 +721,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) str[64] = 0; result.push_back(Pair("msg",str)); for (i=0; i<33; i++) - sprintf(&str[i*2],"%02x",((uint8_t *)pk.begin)[i]); + sprintf(&str[i*2],"%02x",((uint8_t *)pk.begin())[i]); str[66] = 0; result.push_back(Pair("combined_pk",str)); for (i=0; i<64; i++) From 6eaac8547a3ddb506e70896e3251daf07524395c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:23:02 -1100 Subject: [PATCH 40/50] Skip test --- src/cc/musig.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 88bf62449..63d7e5291 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -730,7 +730,9 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) result.push_back(Pair("combinedsig",str)); } if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) ) - return(cclib_error(result,"musig didnt validate")); + { + //return(cclib_error(result,"musig didnt validate")); + } mtx.vin.push_back(CTxIn(prevhash,MUSIG_PREVN)); mtx.vout.push_back(vout); rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,musig_spendopret('y',pk,musig64)); From baef592f94e608d939f4bf627d1ae34e785f1187 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:26:39 -1100 Subject: [PATCH 41/50] Fix script parsing --- src/cc/musig.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 63d7e5291..28795d95c 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -704,7 +704,9 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) txfee = MUSIG_TXFEE; mypk = pubkey2pk(Mypubkey()); std::vector musig64(ParseHex(musigstr)); - CScript scriptPubKey(ParseHex(scriptstr)); + CScript scriptPubKey; + scriptPubKey.resize(strlen(scriptstr)/2); + decode_hex((uint8_t *)scriptPubKey.data(),strlen(scriptstr)/2,scriptstr); if ( myGetTransaction(prevhash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) { vout.nValue = vintx.vout[0].nValue - txfee; From 3de50a250b2d1ad2321d67c2336dfe061fb6d2da Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:29:48 -1100 Subject: [PATCH 42/50] Test --- src/cc/musig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 28795d95c..fdb24f7a0 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -706,7 +706,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) std::vector musig64(ParseHex(musigstr)); CScript scriptPubKey; scriptPubKey.resize(strlen(scriptstr)/2); - decode_hex((uint8_t *)scriptPubKey.data(),strlen(scriptstr)/2,scriptstr); + decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr); if ( myGetTransaction(prevhash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) { vout.nValue = vintx.vout[0].nValue - txfee; From a687d695af02abc60505583027971cfc2373c446 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:41:51 -1100 Subject: [PATCH 43/50] Verify roc --- src/cc/musig.cpp | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index fdb24f7a0..9eaec4404 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -620,25 +620,35 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t n; + UniValue result(UniValue::VOBJ); int32_t i,n; uint8_t msg[32],musig64[64]; secp256k1_pubkey combined_pk; secp256k1_schnorrsig musig; char str[129]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) != 3 ) { - // can code this out of order - } - result.push_back(Pair("result","success")); - /** Verify a Schnorr signature. - * - * Returns: 1: correct signature - * 0: incorrect or unparseable signature - * Args: ctx: a secp256k1 context object, initialized for verification. - * In: sig: the signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) - * pubkey: pointer to a public key to verify with (cannot be NULL) - */ - // if (!secp256k1_schnorrsig_verify(ctx, &sig, msg, &combined_pk)) { - return(result); + if ( musig_parsehash32(msg,jitem(params,0)) < 0 ) + return(cclib_error(result,"error parsing pkhash")); + else if ( musig_parsepubkey(ctx,combined_pk,jitem(params,1)) < 0 ) + return(cclib_error(result,"error parsing combined_pk")); + else if ( musig_parsehash64(musig64,jitem(params,2)) < 0 ) + return(cclib_error(result,"error parsing musig64")); + for (i=0; i<32; i++) + sprintf(&str[i*2],"%02x",msg[i]); + str[64] = 0; + result.push_back(Pair("msg",str)); + result.push_back(Pair("combined_pk",jstr(jitem(params,1),0))); + for (i=0; i<64; i++) + sprintf(&str[i*2],"%02x",musig64[i]); + str[128] = 0; + result.push_back(Pair("combinedsig",str)); + if ( secp256k1_schnorrsig_parse(ctx,&musig,&musig64[0]) > 0 ) + { + if ( secp256k1_schnorrsig_verify(ctx,&musig,msg,&combined_pk) > 0 ) + { + result.push_back(Pair("result","success")); + return(result); + } else return(cclib_error(result,"musig didnt verify")); + } else return(cclib_error(result,"couldnt parse musig64")); + } else return(cclib_error(result,"wrong number of params, need 3: msg, combined_pk, combinedsig")); } // helpers for rpc calls that generate/validate onchain tx @@ -733,7 +743,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) } if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) ) { - //return(cclib_error(result,"musig didnt validate")); + return(cclib_error(result,"musig didnt validate")); } mtx.vin.push_back(CTxIn(prevhash,MUSIG_PREVN)); mtx.vout.push_back(vout); From 317fa937b3ca5010daa59cfdb58725c7bc2b7d45 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:43:44 -1100 Subject: [PATCH 44/50] parsehash --- src/cc/musig.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 9eaec4404..c5cf5fc4e 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -331,12 +331,12 @@ int32_t musig_parsepubkey(secp256k1_context *ctx,secp256k1_pubkey &spk,cJSON *it } else return(-1); } -int32_t musig_parsehash32(uint8_t *hash32,cJSON *item) +int32_t musig_parsehash(uint8_t *hash32,cJSON *item,int32_t len) { char *hexstr; - if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == 64 ) + if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == len*2 ) { - decode_hex(hash32,32,hexstr); + decode_hex(hash32,len,hexstr); return(0); } else return(-1); } @@ -394,9 +394,9 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) MUSIG = musig_infocreate(myind,num); if ( musig_parsepubkey(ctx,MUSIG->combined_pk,jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing combined_pubkey")); - else if ( musig_parsehash32(MUSIG->pkhash,jitem(params,3)) < 0 ) + else if ( musig_parsehash(MUSIG->pkhash,jitem(params,3),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( musig_parsehash32(MUSIG->msg,jitem(params,4)) < 0 ) + else if ( musig_parsehash(MUSIG->msg,jitem(params,4),32) < 0 ) return(cclib_error(result,"error parsing msg")); Myprivkey(privkey); GetRandBytes(session,32); @@ -455,13 +455,13 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { - if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) + if ( musig_parsehash(pkhash,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsehash32(&MUSIG->nonce_commitments[ind*32],jitem(params,2)) < 0 ) + else if ( musig_parsehash(&MUSIG->nonce_commitments[ind*32],jitem(params,2),32) < 0 ) return(cclib_error(result,"error parsing commitment")); /** Gets the signer's public nonce given a list of all signers' data with commitments * @@ -508,7 +508,7 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { - if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) + if ( musig_parsehash(pkhash,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); @@ -578,13 +578,13 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { - if ( musig_parsehash32(pkhash,jitem(params,0)) < 0 ) + if ( musig_parsehash(pkhash,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsehash32(psig,jitem(params,2)) < 0 ) + else if ( musig_parsehash(psig,jitem(params,2),32) < 0 ) return(cclib_error(result,"error parsing psig")); else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG->partial_sig[ind],psig) == 0 ) return(cclib_error(result,"error parsing partialsig")); @@ -625,11 +625,11 @@ UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) != 3 ) { - if ( musig_parsehash32(msg,jitem(params,0)) < 0 ) + if ( musig_parsehash(msg,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); else if ( musig_parsepubkey(ctx,combined_pk,jitem(params,1)) < 0 ) return(cclib_error(result,"error parsing combined_pk")); - else if ( musig_parsehash64(musig64,jitem(params,2)) < 0 ) + else if ( musig_parsehash(musig64,jitem(params,2),64) < 0 ) return(cclib_error(result,"error parsing musig64")); for (i=0; i<32; i++) sprintf(&str[i*2],"%02x",msg[i]); From 6704dd969965d0b938ad2dceab6714a90daca687 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:52:37 -1100 Subject: [PATCH 45/50] Fix --- src/cc/musig.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index c5cf5fc4e..8e37a2add 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -138,7 +138,7 @@ the "msg" is what needs to be signed to create a valid spend Now for a sanity test, we can use the verify call to make sure this sig will work with the msg needed for the spend: - xxxx + ./c cclib verify 18 \"[%22caa64ba398ddfe5c33d8c70a61e556caa0e69b19d93110c5a458a1b37ad44cb0%22,%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,%225e64dc5dda93b2d3f25fe44b2aaca69b8f15d21f70e2bc1c2c53e17262d941bbeea0b0a3ccdfeb96ec83ac2a6a9492db9afe5d47adb6810621c1acfd56439146%22]\" and finally the spend: sendtxid, scriptPubKey, musig @@ -623,7 +623,7 @@ UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue result(UniValue::VOBJ); int32_t i,n; uint8_t msg[32],musig64[64]; secp256k1_pubkey combined_pk; secp256k1_schnorrsig musig; char str[129]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) != 3 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) { if ( musig_parsehash(msg,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); From 3caa4fb350c74d5af61b02770a523272ddc8324d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:59:15 -1100 Subject: [PATCH 46/50] Test check.c --- src/cc/cclib.cpp | 32 +---------------------- src/secp256k1/src/modules/musig/example.c | 6 ++--- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index ec74877b6..b070ded78 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -580,37 +580,7 @@ uint256 juint256(cJSON *obj) #else #include "sudoku.cpp" - -/* -#include "../secp256k1/src/util.h" -#include "../secp256k1/src/num_impl.h" -#include "../secp256k1/src/field_impl.h" -#include "../secp256k1/src/scalar_impl.h" -#include "../secp256k1/src/group_impl.h" -#include "../secp256k1/src/scratch_impl.h" -#include "../secp256k1/src/ecmult_impl.h" -#include "../secp256k1/src/ecmult_const_impl.h" -#include "../secp256k1/src/ecmult_gen_impl.h" -#include "../secp256k1/src/ecdsa_impl.h" -#include "../secp256k1/src/eckey_impl.h" -#include "../secp256k1/src/hash_impl.h" - - - -typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data); -extern "C" void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge); -extern "C" int secp256k1_nonce_function_bipschnorr(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter); -extern "C" int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey); -extern "C" void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2, const unsigned char *seed, uint64_t idx); - -#define ARG_CHECK(cond) do { \ -if (EXPECT(!(cond), 0)) { \ -secp256k1_callback_call(&ctx->illegal_callback, #cond); \ -return 0; \ -} \ -} while(0)*/ - -//#include "../secp256k1/src/secp256k1.c" #include "musig.cpp" +#include "../secp256k1/modules/musig/check.c" #endif diff --git a/src/secp256k1/src/modules/musig/example.c b/src/secp256k1/src/modules/musig/example.c index ceae18686..94c9fdef2 100644 --- a/src/secp256k1/src/modules/musig/example.c +++ b/src/secp256k1/src/modules/musig/example.c @@ -9,11 +9,11 @@ * Additionally, see the documentation in include/secp256k1_musig.h. */ -#include +/*#include #include #include #include -#include +#include */ /* Number of public keys involved in creating the aggregate signature */ #define N_SIGNERS 3 @@ -122,7 +122,7 @@ int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp25 return secp256k1_musig_partial_sig_combine(ctx, &musig_session[0], sig, partial_sig, N_SIGNERS); } - int main(void) { + int testmain(void) { secp256k1_context* ctx; int i; unsigned char seckeys[N_SIGNERS][32]; From fe60cfbf6eb486ac08a5b3906854ab1c82d1d1c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 00:59:44 -1100 Subject: [PATCH 47/50] Src --- src/cc/cclib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index b070ded78..9cd947efc 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -581,6 +581,6 @@ uint256 juint256(cJSON *obj) #else #include "sudoku.cpp" #include "musig.cpp" -#include "../secp256k1/modules/musig/check.c" +#include "../secp256k1/src/modules/musig/check.c" #endif From 1a34721c44c35815f90b739c30eb4d28ef3e6783 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 01:01:00 -1100 Subject: [PATCH 48/50] example.c --- src/cc/cclib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 9cd947efc..c770917ea 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -581,6 +581,6 @@ uint256 juint256(cJSON *obj) #else #include "sudoku.cpp" #include "musig.cpp" -#include "../secp256k1/src/modules/musig/check.c" +#include "../secp256k1/src/modules/musig/example.c" #endif From 93acda143f271f0e08b07393f958dc194bb352ba Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 01:03:17 -1100 Subject: [PATCH 49/50] fprintf(stderr, --- src/cc/musig.cpp | 2 ++ src/secp256k1/src/modules/musig/example.c | 26 +++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 8e37a2add..446f9333d 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -617,10 +617,12 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, partialsig")); } +int testmain(void); UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; UniValue result(UniValue::VOBJ); int32_t i,n; uint8_t msg[32],musig64[64]; secp256k1_pubkey combined_pk; secp256k1_schnorrsig musig; char str[129]; + testmain(); if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) diff --git a/src/secp256k1/src/modules/musig/example.c b/src/secp256k1/src/modules/musig/example.c index 94c9fdef2..70d183e7d 100644 --- a/src/secp256k1/src/modules/musig/example.c +++ b/src/secp256k1/src/modules/musig/example.c @@ -128,37 +128,37 @@ int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp25 unsigned char seckeys[N_SIGNERS][32]; secp256k1_pubkey pubkeys[N_SIGNERS]; secp256k1_pubkey combined_pk; - unsigned char msg[32] = "this_could_be_the_hash_of_a_msg!"; + unsigned char msg[32] = "this_could_be_the_hash_of_a_msg"; secp256k1_schnorrsig sig; /* Create a context for signing and verification */ ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - printf("Creating key pairs......"); + fprintf(stderr,"Creating key pairs......"); for (i = 0; i < N_SIGNERS; i++) { if (!create_key(ctx, seckeys[i], &pubkeys[i])) { - printf("FAILED\n"); + fprintf(stderr,"FAILED\n"); return 1; } } - printf("ok\n"); - printf("Combining public keys..."); + fprintf(stderr,"ok\n"); + fprintf(stderr,"Combining public keys..."); if (!secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk, NULL, pubkeys, N_SIGNERS)) { - printf("FAILED\n"); + fprintf(stderr,"FAILED\n"); return 1; } - printf("ok\n"); - printf("Signing message........."); + fprintf(stderr,"ok\n"); + fprintf(stderr,"Signing message........."); if (!sign(ctx, seckeys, pubkeys, msg, &sig)) { - printf("FAILED\n"); + fprintf(stderr,"FAILED\n"); return 1; } - printf("ok\n"); - printf("Verifying signature....."); + fprintf(stderr,"ok\n"); + fprintf(stderr,"Verifying signature....."); if (!secp256k1_schnorrsig_verify(ctx, &sig, msg, &combined_pk)) { - printf("FAILED\n"); + fprintf(stderr,"FAILED\n"); return 1; } - printf("ok\n"); + fprintf(stderr,"ok\n"); secp256k1_context_destroy(ctx); return 0; } From a0b7227e007bcfa96ad6e99c54a85875652eed63 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 22 Feb 2019 09:29:09 -1100 Subject: [PATCH 50/50] Dont create rogue files on validation --- src/cc/rogue_rpc.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index 57ce1e14b..213e382a1 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -833,7 +833,7 @@ UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param } else return(cclib_error(result,"couldnt reparse params")); } -char *rogue_extractgame(char *str,int32_t *numkeysp,std::vector &newdata,uint64_t &seed,uint256 &playertxid,struct CCcontract_info *cp,uint256 gametxid,char *rogueaddr) +char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vector &newdata,uint64_t &seed,uint256 &playertxid,struct CCcontract_info *cp,uint256 gametxid,char *rogueaddr) { CPubKey roguepk; int32_t i,num,maxplayers,gameheight,batonht,batonvout,numplayers,regslot,numkeys,err; std::string symbol,pname; CTransaction gametx; int64_t buyin,batonvalue; char fname[64],*keystrokes = 0; std::vector playerdata; uint256 batontxid; FILE *fp; uint8_t newplayer[10000]; struct rogue_player P,endP; roguepk = GetUnspendable(cp,0); @@ -854,19 +854,22 @@ char *rogue_extractgame(char *str,int32_t *numkeysp,std::vector &newdat } if ( keystrokes != 0 ) { - sprintf(fname,"rogue.%llu.0",(long long)seed); - if ( (fp= fopen(fname,"wb")) != 0 ) + if ( makefiles != 0 ) { - if ( fwrite(keystrokes,1,numkeys,fp) != numkeys ) - fprintf(stderr,"error writing %s\n",fname); - fclose(fp); - } - sprintf(fname,"rogue.%llu.player",(long long)seed); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(&playerdata[0],1,(int32_t)playerdata.size(),fp) != playerdata.size() ) - fprintf(stderr,"error writing %s\n",fname); - fclose(fp); + sprintf(fname,"rogue.%llu.0",(long long)seed); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(keystrokes,1,numkeys,fp) != numkeys ) + fprintf(stderr,"error writing %s\n",fname); + fclose(fp); + } + sprintf(fname,"rogue.%llu.player",(long long)seed); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(&playerdata[0],1,(int32_t)playerdata.size(),fp) != playerdata.size() ) + fprintf(stderr,"error writing %s\n",fname); + fclose(fp); + } } num = rogue_replay2(newplayer,seed,keystrokes,numkeys,playerdata.size()==0?0:&P,0); newdata.resize(num); @@ -914,7 +917,7 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) GetCCaddress1of2(cp,rogueaddr,roguepk,pk); result.push_back(Pair("rogueaddr",rogueaddr)); str[0] = 0; - if ( (keystrokes= rogue_extractgame(str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 ) + if ( (keystrokes= rogue_extractgame(1,str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 ) { result.push_back(Pair("status","success")); flag = 1; @@ -1240,7 +1243,7 @@ int32_t rogue_playerdata_validate(uint256 &playertxid,struct CCcontract_info *cp roguepk = GetUnspendable(cp,0); GetCCaddress1of2(cp,rogueaddr,roguepk,pk); //fprintf(stderr,"call extractgame\n"); - if ( (keystrokes= rogue_extractgame(str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 ) + if ( (keystrokes= rogue_extractgame(0,str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 ) { free(keystrokes); //fprintf(stderr,"extracted.(%s)\n",str);