From 1b5d9b5032f41422113868eca35d182c07529f7e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 23 Feb 2019 23:24:17 +0800 Subject: [PATCH 1/5] show --- src/cc/musig.cpp | 106 +++++++++++++--------- src/musigtest.py | 189 +++++++++++++++++++++++++++++++++++++++ src/wallet/rpcwallet.cpp | 8 +- 3 files changed, 255 insertions(+), 48 deletions(-) create mode 100755 src/musigtest.py diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index bd3d74a95..cdf53be09 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -89,7 +89,7 @@ the "msg" is what needs to be signed to create a valid spend "numsigners": 2, "commitment": "bbea1f2562eca01b9a1393c5dc188bdd44551aebf684f4459930f59dde01f7ae", "result": "success" - } +} on node with pubkey: 0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4 ./komodo-cli -ac_name=MUSIG cclib session 18 '[1,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' @@ -221,7 +221,9 @@ struct musig_info secp256k1_musig_partial_signature *partial_sig; //[N_SIGNERS]; int32_t myind,num; uint8_t msg[32],pkhash[32],combpk[33]; -} *MUSIG; +}; + +std::vector MUSIG; struct musig_info *musig_infocreate(int32_t myind,int32_t num) { @@ -431,14 +433,15 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) 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); - if ( musig_parsepubkey(ctx,MUSIG->combined_pk,jitem(params,2)) < 0 ) + //if ( MUSIG[myind] != 0 ) + // musig_infofree(MUSIG[myind]), MUSIG[myind] = 0; + struct musig_info *temp_musig = musig_infocreate(myind,num); + MUSIG.push_back(temp_musig); + if ( musig_parsepubkey(ctx,MUSIG[myind]->combined_pk,jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing combined_pubkey")); - else if ( musig_parsehash(MUSIG->pkhash,jitem(params,3),32) < 0 ) + else if ( musig_parsehash(MUSIG[myind]->pkhash,jitem(params,3),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( musig_parsehash(MUSIG->msg,jitem(params,4),32) < 0 ) + else if ( musig_parsehash(MUSIG[myind]->msg,jitem(params,4),32) < 0 ) return(cclib_error(result,"error parsing msg")); Myprivkey(privkey); GetRandBytes(session,32); @@ -468,13 +471,13 @@ 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->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[myind]->session,MUSIG[myind]->signer_data, &MUSIG[myind]->nonce_commitments[MUSIG[myind]->myind * 32],session,MUSIG[myind]->msg,&MUSIG[myind]->combined_pk,MUSIG[myind]->pkhash,MUSIG[myind]->num,MUSIG[myind]->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]); + sprintf(&str[i<<1],"%02x",MUSIG[myind]->nonce_commitments[MUSIG[myind]->myind*32 + i]); str[64] = 0; result.push_back(Pair("commitment",str)); result.push_back(Pair("result","success")); @@ -492,18 +495,20 @@ 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]; + UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; 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 ( params != 0 && (n= cJSON_GetArraySize(params)) == 4 ) { - if ( musig_parsehash(pkhash,jitem(params,0),32) < 0 ) + if ( (myind= juint(jitem(params,0),0)) < 0 ) + return(cclib_error(result,"myind is wrong")); + if ( musig_parsehash(pkhash,jitem(params,1),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG[myind]->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 ) + else if ( (ind= juint(jitem(params,2),0)) < 0 || ind >= MUSIG[myind]->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsehash(&MUSIG->nonce_commitments[ind*32],jitem(params,2),32) < 0 ) + else if ( musig_parsehash(&MUSIG[myind]->nonce_commitments[ind*32],jitem(params,3),32) < 0 ) return(cclib_error(result,"error parsing commitment")); /** Gets the signer's public nonce given a list of all signers' data with commitments * @@ -521,14 +526,15 @@ 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->commitment_ptrs,MUSIG->num) > 0 ) + fprintf(stderr, "COMMIT: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); + if ( secp256k1_musig_session_get_public_nonce(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,&MUSIG[myind]->nonces[MUSIG[myind]->myind],MUSIG[myind]->commitment_ptrs,MUSIG[myind]->num) > 0 ) { - if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG->nonces[MUSIG->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) + if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG[myind]->nonces[MUSIG[myind]->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("myind",MUSIG->myind)); + result.push_back(Pair("myind",MUSIG[myind]->myind)); result.push_back(Pair("nonce",str)); result.push_back(Pair("result","success")); } else return(cclib_error(result,"error serializing nonce (pubkey)")); @@ -539,26 +545,29 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) result.push_back(Pair("result","success")); } return(result); - } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, commitment")); + } else return(cclib_error(result,"wrong number of params, need 4: myind, 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 i,n,ind; uint8_t pkhash[32],psig[32]; CPubKey pk; char str[67]; + UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; 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)) == 3 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) == 4 ) { - if ( musig_parsehash(pkhash,jitem(params,0),32) < 0 ) + if ( (myind= juint(jitem(params,0),0)) < 0 ) + return(cclib_error(result,"myind is wrong")); + if ( musig_parsehash(pkhash,jitem(params,1),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG[myind]->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 ) + else if ( (ind= juint(jitem(params,2),0)) < 0 || ind >= MUSIG[myind]->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[myind]->nonces[ind],jitem(params,3)) < 0 ) return(cclib_error(result,"error parsing nonce")); result.push_back(Pair("added_index",ind)); + fprintf(stderr, "NONCE: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); /** Checks a signer's public nonce against a commitment to said nonce, and update * data structure if they match * @@ -569,10 +578,16 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * 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) - */ - for (i=0; inum; i++) + * + if ( ind != MUSIG[myind]->num-1 ) { - if ( secp256k1_musig_set_nonce(ctx,&MUSIG->signer_data[i],&MUSIG->nonces[i]) == 0 ) + fprintf(stderr, "ind.%i MUSIG[myind]->num.%i\n", ind, MUSIG[myind]->num); + return(cclib_error(result,"need rest of nonce's to continue")); + }*/ + for (i=0; inum; i++) + { + fprintf(stderr, "setting nonce for index.%i\n",i); + if ( secp256k1_musig_set_nonce(ctx,&MUSIG[myind]->signer_data[i],&MUSIG[myind]->nonces[i]) == 0 ) return(cclib_error(result,"error setting nonce")); } /** Updates a session with the combined public nonce of all signers. The combined @@ -593,45 +608,48 @@ 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. */ - if ( secp256k1_musig_session_combine_nonces(ctx,&MUSIG->session,MUSIG->signer_data,MUSIG->num,NULL,NULL) > 0 ) + if ( secp256k1_musig_session_combine_nonces(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,MUSIG[myind]->num,NULL,NULL) > 0 ) { - if ( secp256k1_musig_partial_sign(ctx,&MUSIG->session,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + if ( secp256k1_musig_partial_sign(ctx,&MUSIG[myind]->session,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) { 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("myind",MUSIG[myind]->myind)); 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")); + } else return(cclib_error(result,"wrong number of params, need 4: myind, pkhash, ind, nonce")); } UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,ind,n; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; + UniValue result(UniValue::VOBJ); int32_t i,ind,myind,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 ( params != 0 && (n= cJSON_GetArraySize(params)) == 4 ) { - if ( musig_parsehash(pkhash,jitem(params,0),32) < 0 ) + if ( (myind= juint(jitem(params,0),0)) < 0 ) + return(cclib_error(result,"myind is wrong")); + if ( musig_parsehash(pkhash,jitem(params,1),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG[myind]->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 ) + else if ( (ind= juint(jitem(params,2),0)) < 0 || ind >= MUSIG[myind]->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsehash(psig,jitem(params,2),32) < 0 ) + else if ( musig_parsehash(psig,jitem(params,3),32) < 0 ) return(cclib_error(result,"error parsing psig")); - else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG->partial_sig[ind],psig) == 0 ) + else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG[myind]->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 ) + fprintf(stderr, "PARTIALSIG: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); + if ( secp256k1_musig_partial_sig_combine(ctx,&MUSIG[myind]->session,&sig,MUSIG[myind]->partial_sig,MUSIG[myind]->num) > 0 ) { if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 ) { @@ -644,7 +662,7 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param } else { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) { result.push_back(Pair("myind",ind)); for (i=0; i<32; i++) @@ -656,7 +674,7 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param } 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")); + } else return(cclib_error(result,"wrong number of params, need 4: myind, pkhash, ind, partialsig")); } int testmain(void); diff --git a/src/musigtest.py b/src/musigtest.py new file mode 100755 index 000000000..26f09d588 --- /dev/null +++ b/src/musigtest.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 +import platform +import os +import re +import json +import random +import base58 +import binascii +import hashlib +import sys +import time +from slickrpc import Proxy + +# fucntion to define rpc_connection +def def_credentials(chain): + rpcport = ''; + operating_system = platform.system() + if operating_system == 'Darwin': + ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo' + elif operating_system == 'Linux': + ac_dir = os.environ['HOME'] + '/.komodo' + elif operating_system == 'Windows': + ac_dir = '%s/komodo/' % os.environ['APPDATA'] + if chain == 'KMD': + coin_config_file = str(ac_dir + '/komodo.conf') + else: + coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf') + with open(coin_config_file, 'r') as f: + for line in f: + l = line.rstrip() + if re.search('rpcuser', l): + rpcuser = l.replace('rpcuser=', '') + elif re.search('rpcpassword', l): + rpcpassword = l.replace('rpcpassword=', '') + elif re.search('rpcport', l): + rpcport = l.replace('rpcport=', '') + if len(rpcport) == 0: + if chain == 'KMD': + rpcport = 7771 + else: + print("rpcport not in conf file, exiting") + print("check " + coin_config_file) + exit(1) + return (Proxy("http://%s:%s@127.0.0.1:%d" % (rpcuser, rpcpassword, int(rpcport)))) + + +# generate address, validate address, dump private key +def genvaldump(rpc_connection): + # get new address + address = rpc_connection.getnewaddress() + # validate address + validateaddress_result = rpc_connection.validateaddress(address) + pubkey = validateaddress_result['pubkey'] + address = validateaddress_result['address'] + # dump private key for the address + privkey = rpc_connection.dumpprivkey(address) + # function output + output = [pubkey, privkey, address] + return(output) + +CHAIN = 'MUSIG' #sys.argv[1] + +rpc = def_credentials(CHAIN) + +pubkeys = [] +address_info = [] +ret = input('Do you want to generate new pubkeys? ').lower() + +if ret.startswith('y'): + numpks = int(input('Enter number of pubkeys to combine: ')) + if os.path.isfile("list.json"): + print('Already have list.json, move it if you would like to generate a new set.') + sys.exit(0) + while len(address_info) < numpks: + addressinfo = genvaldump(rpc) + address_info.append(addressinfo) + f = open("list.json", "w+") + f.write(json.dumps(address_info)) +else: + if os.path.isfile("list.json"): + with open('list.json') as list: + address_info = json.load(list) + else: + sys.exit('No list.json you need to create new pubkeys!') + +for addressinfo in address_info: + pubkeys.append(addressinfo[0]) + +ret = rpc.setpubkey(pubkeys[0]) +ret = rpc.cclib("combine", "18", str(pubkeys)) +pkhash = str(ret['pkhash']) +combinedpk = str(ret['combined_pk']) +print('Your combined pubkey is: ' + combinedpk) +print('Your pkhash is: ' + pkhash) +amount = int(input('Enter amount to send: ')) +tmp = str([combinedpk, amount]) +hex = rpc.cclib("send", "18", tmp)['hex'] +senttxid = rpc.sendrawtransaction(hex) +print('Your senttxid is: ' + senttxid) + +print("Waiting for tx to be confirmed") +while True: + confirmed = int(rpc.gettransaction(senttxid)["confirmations"]) + if not confirmed: + time.sleep(10) + else: + print('SentTX confirmed') + break + +scriptPubKey = rpc.getrawtransaction(senttxid,1)['vout'][1]['scriptPubKey']['hex'] +print('Your scriptPubKey is: ' + scriptPubKey) +tmp = str([senttxid, scriptPubKey]) +msg = rpc.cclib("calcmsg", "18", tmp)['msg'] +print('Your msg is: ' + msg) + +i = 0; +commitments = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + tmp = str([i, len(pubkeys), combinedpk, pkhash, msg]) + commitments.append(rpc.cclib("session", "18", tmp)['commitment']) + i = i + 1 + +print(commitments) + +i = 0 +nonces = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + n = 0 + for commitment in commitments: + if n == i: + n = n + 1 + continue; + tmp = str([i, pkhash, n, commitment]) + ret = rpc.cclib("commit", "18", tmp) + if len(ret) == 4: + nonces.append(ret['nonce']) + n = n + 1 + i = i + 1 + +print(nonces) + +i = 0 +partialsigs = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + n = 0 + for nonce in nonces: + #if n == i: + # n = n + 1 + # continue; + tmp = str([i, pkhash, n, nonce]) + ret = rpc.cclib("nonce", "18", tmp) + print(ret) + if len(ret) == 4: + partialsigs.append(ret['partialsig']) + n = n + 1 + i = i + 1 + +print(partialsigs) + +i = 0 +combinedsigs = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + n = 0 + for partialsig in partialsigs: + if n == i: + n = n + 1 + continue; + tmp = str([i, pkhash, n, partialsig]) + ret = rpc.cclib("partialsig", "18", tmp) + if len(ret) == 4: + combinedsigs.append(ret['combinedsig']) + n = n + 1 + i = i + 1 + +print(combinedsigs) + +tmp = str([msg, combinedpk, combinedsigs[0]]) +ret = rpc.cclib("verify", "18", tmp) + +print(ret) + +tmp = str([sendtxid, scriptPubKey, combinedsigs[0]]) +ret = rpc.cclib("spend", "18", tmp) + +print(ret) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0ed2f866c..8cffd78f7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5308,8 +5308,8 @@ UniValue setpubkey(const UniValue& params, bool fHelp) char Raddress[64]; uint8_t pubkey33[33]; - if ( NOTARY_PUBKEY33[0] == 0 ) - { + //if ( NOTARY_PUBKEY33[0] == 0 ) + //{ if (strlen(params[0].get_str().c_str()) == 66) { decode_hex(pubkey33,33,(char *)params[0].get_str().c_str()); @@ -5337,14 +5337,14 @@ UniValue setpubkey(const UniValue& params, bool fHelp) USE_EXTERNAL_PUBKEY = 1; } } else result.push_back(Pair("error", "pubkey is wrong length, must be 66 char hex string.")); - } + /*} else { result.push_back(Pair("error", "Can only set pubkey once, to change it you need to restart your daemon, pubkey in use is below.")); pubkey2addr((char *)Raddress,(uint8_t *)NOTARY_PUBKEY33); std::string address_ret; address_ret.assign(Raddress); result.push_back(Pair("address",address_ret)); - } + }*/ result.push_back(Pair("pubkey", NOTARY_PUBKEY)); return result; } From b6990f5f5ef7fc5a40251583873c9cda76620bb4 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 24 Feb 2019 01:05:18 +0800 Subject: [PATCH 2/5] working single node multi sign --- src/cc/musig.cpp | 24 +++++++++++++++++------- src/musigtest.py | 38 ++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index cdf53be09..d50ee92d8 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -525,8 +525,13 @@ 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. */ + if ( ind != MUSIG[myind]->num-1 ) + { + //fprintf(stderr, "ind.%i MUSIG[myind]->num.%i\n", ind, MUSIG[myind]->num); + return(cclib_error(result,"need rest of nonce's to continue")); + } result.push_back(Pair("added_index",ind)); - fprintf(stderr, "COMMIT: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); + //fprintf(stderr, "COMMIT: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); if ( secp256k1_musig_session_get_public_nonce(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,&MUSIG[myind]->nonces[MUSIG[myind]->myind],MUSIG[myind]->commitment_ptrs,MUSIG[myind]->num) > 0 ) { if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG[myind]->nonces[MUSIG[myind]->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) @@ -567,7 +572,7 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) else if ( musig_parsepubkey(ctx,MUSIG[myind]->nonces[ind],jitem(params,3)) < 0 ) return(cclib_error(result,"error parsing nonce")); result.push_back(Pair("added_index",ind)); - fprintf(stderr, "NONCE: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); + //fprintf(stderr, "NONCE: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); /** Checks a signer's public nonce against a commitment to said nonce, and update * data structure if they match * @@ -578,15 +583,15 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * 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 ( ind != MUSIG[myind]->num-1 ) { - fprintf(stderr, "ind.%i MUSIG[myind]->num.%i\n", ind, MUSIG[myind]->num); + //fprintf(stderr, "ind.%i MUSIG[myind]->num.%i\n", ind, MUSIG[myind]->num); return(cclib_error(result,"need rest of nonce's to continue")); - }*/ + } for (i=0; inum; i++) { - fprintf(stderr, "setting nonce for index.%i\n",i); + //fprintf(stderr, "setting nonce for index.%i\n",i); if ( secp256k1_musig_set_nonce(ctx,&MUSIG[myind]->signer_data[i],&MUSIG[myind]->nonces[i]) == 0 ) return(cclib_error(result,"error setting nonce")); } @@ -648,7 +653,12 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG[myind]->partial_sig[ind],psig) == 0 ) return(cclib_error(result,"error parsing partialsig")); result.push_back(Pair("added_index",ind)); - fprintf(stderr, "PARTIALSIG: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); + //fprintf(stderr, "PARTIALSIG: number of MUSIG structs.%li using struct.%i addedindex.%i\n",MUSIG.size(),myind,ind); + if ( ind != MUSIG[myind]->num-1 ) + { + //fprintf(stderr, "ind.%i MUSIG[myind]->num.%i\n", ind, MUSIG[myind]->num); + return(cclib_error(result,"need rest of nonce's to continue")); + } if ( secp256k1_musig_partial_sig_combine(ctx,&MUSIG[myind]->session,&sig,MUSIG[myind]->partial_sig,MUSIG[myind]->num) > 0 ) { if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 ) diff --git a/src/musigtest.py b/src/musigtest.py index 26f09d588..9a28bb2d4 100755 --- a/src/musigtest.py +++ b/src/musigtest.py @@ -121,7 +121,7 @@ for pubkey in pubkeys: commitments.append(rpc.cclib("session", "18", tmp)['commitment']) i = i + 1 -print(commitments) +#print(commitments) i = 0 nonces = [] @@ -129,17 +129,16 @@ for pubkey in pubkeys: ret = rpc.setpubkey(pubkey) n = 0 for commitment in commitments: - if n == i: - n = n + 1 - continue; tmp = str([i, pkhash, n, commitment]) ret = rpc.cclib("commit", "18", tmp) - if len(ret) == 4: + try: nonces.append(ret['nonce']) + except: + x = 1 n = n + 1 i = i + 1 -print(nonces) +#print(nonces) i = 0 partialsigs = [] @@ -147,18 +146,17 @@ for pubkey in pubkeys: ret = rpc.setpubkey(pubkey) n = 0 for nonce in nonces: - #if n == i: - # n = n + 1 - # continue; tmp = str([i, pkhash, n, nonce]) ret = rpc.cclib("nonce", "18", tmp) print(ret) - if len(ret) == 4: + try: partialsigs.append(ret['partialsig']) + except: + x = 1 n = n + 1 i = i + 1 -print(partialsigs) +#print(partialsigs) i = 0 combinedsigs = [] @@ -166,24 +164,28 @@ for pubkey in pubkeys: ret = rpc.setpubkey(pubkey) n = 0 for partialsig in partialsigs: - if n == i: - n = n + 1 - continue; tmp = str([i, pkhash, n, partialsig]) ret = rpc.cclib("partialsig", "18", tmp) - if len(ret) == 4: + print(ret) + try: combinedsigs.append(ret['combinedsig']) + except: + x = 1 n = n + 1 i = i + 1 -print(combinedsigs) +#print(combinedsigs) tmp = str([msg, combinedpk, combinedsigs[0]]) ret = rpc.cclib("verify", "18", tmp) -print(ret) +#print(ret) -tmp = str([sendtxid, scriptPubKey, combinedsigs[0]]) +tmp = str([senttxid, scriptPubKey, combinedsigs[0]]) ret = rpc.cclib("spend", "18", tmp) print(ret) + +ret = rpc.sendrawtransaction(ret['hex']) + +print(ret) From 41c82bee96a9fc6f30f82e0e9d604d80d98d09c3 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 24 Feb 2019 11:53:17 +0800 Subject: [PATCH 3/5] stop print flood --- src/musigtest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/musigtest.py b/src/musigtest.py index 9a28bb2d4..0880f1494 100755 --- a/src/musigtest.py +++ b/src/musigtest.py @@ -148,7 +148,6 @@ for pubkey in pubkeys: for nonce in nonces: tmp = str([i, pkhash, n, nonce]) ret = rpc.cclib("nonce", "18", tmp) - print(ret) try: partialsigs.append(ret['partialsig']) except: @@ -166,7 +165,6 @@ for pubkey in pubkeys: for partialsig in partialsigs: tmp = str([i, pkhash, n, partialsig]) ret = rpc.cclib("partialsig", "18", tmp) - print(ret) try: combinedsigs.append(ret['combinedsig']) except: From 8c5ba39d22f91af50e0bf93d1e7cd2f1dce5828f Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 25 Feb 2019 13:18:14 +0800 Subject: [PATCH 4/5] fix ipaddress --- src/cc/rogue/main.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index 5de27317e..02690a482 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -587,9 +587,9 @@ char *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char * return(chunk.memory); } -uint16_t _komodo_userpass(char *username, char *password, char *ipaddress, FILE *fp) +uint16_t _komodo_userpass(char *username, char *password, FILE *fp) { - char *rpcuser,*rpcpassword,*str,line[8192]; uint16_t port = 0; + char *rpcuser,*rpcpassword,*str,*ipaddress,line[8192]; uint16_t port = 0; rpcuser = rpcpassword = 0; username[0] = password[0] = 0; while ( fgets(line,sizeof(line),fp) != 0 ) @@ -609,6 +609,7 @@ uint16_t _komodo_userpass(char *username, char *password, char *ipaddress, FILE else if ( (str= strstr(line,(char *)"ipaddress")) != 0 ) { ipaddress = parse_conf_line(str,(char *)"ipaddress"); + strcpy(IPADDRESS,ipaddress); } } if ( rpcuser != 0 && rpcpassword != 0 ) @@ -616,7 +617,7 @@ uint16_t _komodo_userpass(char *username, char *password, char *ipaddress, FILE strcpy(username,rpcuser); strcpy(password,rpcpassword); } - //printf("rpcuser.(%s) rpcpassword.(%s) KMDUSERPASS.(%s) %u\n",rpcuser,rpcpassword,KMDUSERPASS,port); + //printf("rpcuser.(%s) rpcpassword.(%s) %u ipaddress.%s\n",rpcuser,rpcpassword,port,ipaddress); if ( rpcuser != 0 ) free(rpcuser); if ( rpcpassword != 0 ) @@ -661,7 +662,7 @@ uint16_t _komodo_userpass(char *username, char *password, char *ipaddress, FILE //printf("test.(%s) -> [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname); }*/ -uint16_t komodo_userpass(char *userpass,char *symbol,char *ipaddress) +uint16_t komodo_userpass(char *userpass,char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[KOMODO_ASSETCHAIN_MAXLEN]; userpass[0] = 0; @@ -677,7 +678,7 @@ uint16_t komodo_userpass(char *userpass,char *symbol,char *ipaddress) //komodo_statefname(fname,symbol,confname); if ( (fp= fopen(confname,"rb")) != 0 ) { - port = _komodo_userpass(username,password,ipaddress,fp); + port = _komodo_userpass(username,password,fp); sprintf(userpass,"%s:%s",username,password); if ( strcmp(symbol,ASSETCHAINS_SYMBOL) == 0 ) strcpy(USERPASS,userpass); @@ -809,10 +810,10 @@ int main(int argc, char **argv, char **envp) ASSETCHAINS_SYMBOL[j++] = toupper(c); } ASSETCHAINS_SYMBOL[j++] = 0; - ROGUE_PORT = komodo_userpass(userpass,ASSETCHAINS_SYMBOL,IPADDRESS); + ROGUE_PORT = komodo_userpass(userpass,ASSETCHAINS_SYMBOL); if ( IPADDRESS[0] == 0 ) strcpy(IPADDRESS,"127.0.0.1"); - printf("ASSETCHAINS_SYMBOL.(%s) port.%u (%s)\n",ASSETCHAINS_SYMBOL,ROGUE_PORT,USERPASS); sleep(1); + printf("ASSETCHAINS_SYMBOL.(%s) port.%u (%s) IPADDRESS.%s \n",ASSETCHAINS_SYMBOL,ROGUE_PORT,USERPASS,IPADDRESS); sleep(1); if ( argc == 2 && (fp=fopen(argv[1],"rb")) == 0 ) { seed = atol(argv[1]); From 6f5d9655c903ae265eb0f0cb72da4cf9af4b0b9d Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 25 Feb 2019 13:20:48 +0800 Subject: [PATCH 5/5] fix --- src/musigtest.py | 189 --------------------------------------- src/wallet/rpcwallet.cpp | 8 +- 2 files changed, 4 insertions(+), 193 deletions(-) delete mode 100755 src/musigtest.py diff --git a/src/musigtest.py b/src/musigtest.py deleted file mode 100755 index 0880f1494..000000000 --- a/src/musigtest.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env python3 -import platform -import os -import re -import json -import random -import base58 -import binascii -import hashlib -import sys -import time -from slickrpc import Proxy - -# fucntion to define rpc_connection -def def_credentials(chain): - rpcport = ''; - operating_system = platform.system() - if operating_system == 'Darwin': - ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo' - elif operating_system == 'Linux': - ac_dir = os.environ['HOME'] + '/.komodo' - elif operating_system == 'Windows': - ac_dir = '%s/komodo/' % os.environ['APPDATA'] - if chain == 'KMD': - coin_config_file = str(ac_dir + '/komodo.conf') - else: - coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf') - with open(coin_config_file, 'r') as f: - for line in f: - l = line.rstrip() - if re.search('rpcuser', l): - rpcuser = l.replace('rpcuser=', '') - elif re.search('rpcpassword', l): - rpcpassword = l.replace('rpcpassword=', '') - elif re.search('rpcport', l): - rpcport = l.replace('rpcport=', '') - if len(rpcport) == 0: - if chain == 'KMD': - rpcport = 7771 - else: - print("rpcport not in conf file, exiting") - print("check " + coin_config_file) - exit(1) - return (Proxy("http://%s:%s@127.0.0.1:%d" % (rpcuser, rpcpassword, int(rpcport)))) - - -# generate address, validate address, dump private key -def genvaldump(rpc_connection): - # get new address - address = rpc_connection.getnewaddress() - # validate address - validateaddress_result = rpc_connection.validateaddress(address) - pubkey = validateaddress_result['pubkey'] - address = validateaddress_result['address'] - # dump private key for the address - privkey = rpc_connection.dumpprivkey(address) - # function output - output = [pubkey, privkey, address] - return(output) - -CHAIN = 'MUSIG' #sys.argv[1] - -rpc = def_credentials(CHAIN) - -pubkeys = [] -address_info = [] -ret = input('Do you want to generate new pubkeys? ').lower() - -if ret.startswith('y'): - numpks = int(input('Enter number of pubkeys to combine: ')) - if os.path.isfile("list.json"): - print('Already have list.json, move it if you would like to generate a new set.') - sys.exit(0) - while len(address_info) < numpks: - addressinfo = genvaldump(rpc) - address_info.append(addressinfo) - f = open("list.json", "w+") - f.write(json.dumps(address_info)) -else: - if os.path.isfile("list.json"): - with open('list.json') as list: - address_info = json.load(list) - else: - sys.exit('No list.json you need to create new pubkeys!') - -for addressinfo in address_info: - pubkeys.append(addressinfo[0]) - -ret = rpc.setpubkey(pubkeys[0]) -ret = rpc.cclib("combine", "18", str(pubkeys)) -pkhash = str(ret['pkhash']) -combinedpk = str(ret['combined_pk']) -print('Your combined pubkey is: ' + combinedpk) -print('Your pkhash is: ' + pkhash) -amount = int(input('Enter amount to send: ')) -tmp = str([combinedpk, amount]) -hex = rpc.cclib("send", "18", tmp)['hex'] -senttxid = rpc.sendrawtransaction(hex) -print('Your senttxid is: ' + senttxid) - -print("Waiting for tx to be confirmed") -while True: - confirmed = int(rpc.gettransaction(senttxid)["confirmations"]) - if not confirmed: - time.sleep(10) - else: - print('SentTX confirmed') - break - -scriptPubKey = rpc.getrawtransaction(senttxid,1)['vout'][1]['scriptPubKey']['hex'] -print('Your scriptPubKey is: ' + scriptPubKey) -tmp = str([senttxid, scriptPubKey]) -msg = rpc.cclib("calcmsg", "18", tmp)['msg'] -print('Your msg is: ' + msg) - -i = 0; -commitments = [] -for pubkey in pubkeys: - ret = rpc.setpubkey(pubkey) - tmp = str([i, len(pubkeys), combinedpk, pkhash, msg]) - commitments.append(rpc.cclib("session", "18", tmp)['commitment']) - i = i + 1 - -#print(commitments) - -i = 0 -nonces = [] -for pubkey in pubkeys: - ret = rpc.setpubkey(pubkey) - n = 0 - for commitment in commitments: - tmp = str([i, pkhash, n, commitment]) - ret = rpc.cclib("commit", "18", tmp) - try: - nonces.append(ret['nonce']) - except: - x = 1 - n = n + 1 - i = i + 1 - -#print(nonces) - -i = 0 -partialsigs = [] -for pubkey in pubkeys: - ret = rpc.setpubkey(pubkey) - n = 0 - for nonce in nonces: - tmp = str([i, pkhash, n, nonce]) - ret = rpc.cclib("nonce", "18", tmp) - try: - partialsigs.append(ret['partialsig']) - except: - x = 1 - n = n + 1 - i = i + 1 - -#print(partialsigs) - -i = 0 -combinedsigs = [] -for pubkey in pubkeys: - ret = rpc.setpubkey(pubkey) - n = 0 - for partialsig in partialsigs: - tmp = str([i, pkhash, n, partialsig]) - ret = rpc.cclib("partialsig", "18", tmp) - try: - combinedsigs.append(ret['combinedsig']) - except: - x = 1 - n = n + 1 - i = i + 1 - -#print(combinedsigs) - -tmp = str([msg, combinedpk, combinedsigs[0]]) -ret = rpc.cclib("verify", "18", tmp) - -#print(ret) - -tmp = str([senttxid, scriptPubKey, combinedsigs[0]]) -ret = rpc.cclib("spend", "18", tmp) - -print(ret) - -ret = rpc.sendrawtransaction(ret['hex']) - -print(ret) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8cffd78f7..0ed2f866c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5308,8 +5308,8 @@ UniValue setpubkey(const UniValue& params, bool fHelp) char Raddress[64]; uint8_t pubkey33[33]; - //if ( NOTARY_PUBKEY33[0] == 0 ) - //{ + if ( NOTARY_PUBKEY33[0] == 0 ) + { if (strlen(params[0].get_str().c_str()) == 66) { decode_hex(pubkey33,33,(char *)params[0].get_str().c_str()); @@ -5337,14 +5337,14 @@ UniValue setpubkey(const UniValue& params, bool fHelp) USE_EXTERNAL_PUBKEY = 1; } } else result.push_back(Pair("error", "pubkey is wrong length, must be 66 char hex string.")); - /*} + } else { result.push_back(Pair("error", "Can only set pubkey once, to change it you need to restart your daemon, pubkey in use is below.")); pubkey2addr((char *)Raddress,(uint8_t *)NOTARY_PUBKEY33); std::string address_ret; address_ret.assign(Raddress); result.push_back(Pair("address",address_ret)); - }*/ + } result.push_back(Pair("pubkey", NOTARY_PUBKEY)); return result; }