From 82da011f7cd7149abc022fba7deff245e330a80e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 28 Feb 2016 04:44:24 -0300 Subject: [PATCH] experiments --- iguana/SuperNET.c | 6 +- iguana/SuperNET.h | 40 +++-- iguana/SuperNET_category.c | 168 ++------------------- iguana/SuperNET_hexmsg.c | 276 +++++++++++++++++++++++++++++++++- iguana/iguana_exchanges.c | 9 +- iguana/iguana_instantdex.c | 12 +- iguana/iguana_pubkeys.c | 8 + iguana/iguana_ramchain.c | 19 +-- iguana/main.c | 8 +- iguana/pangea_api.c | 8 +- iguana/swaps/iguana_PAXswap.c | 213 +++++++++++++++++++++++++- 11 files changed, 561 insertions(+), 206 deletions(-) diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c index 454d1eb55..f45209195 100755 --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -694,7 +694,7 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) } if ( (destflag & SUPERNET_ISMINE) != 0 && agent != 0 && method != 0 ) { - if ( hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) + if ( newflag == 0 && hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr)) != 0 ) { @@ -1203,11 +1203,11 @@ TWO_STRINGS(SuperNET,subscribe,category,subcategory) TWO_STRINGS(SuperNET,gethexmsg,category,subcategory) { - bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; + bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; struct category_info *cat; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); categoryhash = calc_categoryhashes(&subhash,category,subcategory); - if ( (m= category_gethexmsg(myinfo,categoryhash,subhash)) != 0 ) + if ( (m= category_gethexmsg(myinfo,&cat,categoryhash,subhash)) != 0 ) { hexstr = calloc(1,m->len*2+1); init_hexbytes_noT(hexstr,m->msg,m->len); diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index d9dc58563..1d517d891 100755 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -78,7 +78,7 @@ struct supernet_info char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; - bits256 privkey,persistent_priv; char secret[2048],NXTAPIURL[512]; + bits256 privkey,persistent_priv,BTCmarkerhash; char secret[2048],NXTAPIURL[512]; uint8_t *recvbuf[6]; struct supernet_address myaddr; int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; @@ -100,21 +100,31 @@ struct supernet_info struct category_chain { - bits256 *weights,*blocks,category_hwm,cchainhash; + bits256 *weights,*blocks,category_hwm,genesishash,hwmhash; int32_t hashlen,addrlen,maxblocknum; struct supernet_info *myinfo; void *categoryinfo,*subinfo; - int32_t (*blockhash_func)(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen); - bits256 (*stake_func)(struct category_chain *cchain,void *addr,int32_t addrlen); - bits256 (*hit_func)(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); - bits256 (*default_func)(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); + int32_t (*blockhash_func)(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen); + int32_t (*payment_func)(struct category_chain *catchain,void *src,void *dest,uint64_t amount); + bits256 (*stake_func)(struct category_chain *catchain,void *addr,int32_t addrlen); + bits256 (*hit_func)(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); + bits256 (*default_func)(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); + int32_t (*ishwm_func)(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr); }; +struct crypto777_msghdr +{ + struct acct777_sig sig __attribute__((packed)); + bits256 prevhash,btchash; + uint8_t cmd[8]; + uint8_t serialized[]; +} __attribute__((packed)); + struct category_info { UT_hash_handle hh; queue_t Q; - char *(*processfunc)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr); - struct category_chain *cchain; + char *(*processfunc)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr); + struct category_chain *catchain; bits256 hash; void *info; struct category_info *sub; }; extern struct category_info *Categories; @@ -158,8 +168,8 @@ void *category_info(bits256 categoryhash,bits256 subhash); void *category_infoset(bits256 categoryhash,bits256 subhash,void *info); struct category_info *category_find(bits256 categoryhash,bits256 subhash); void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr); -struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)); -char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr); +struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)); +char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); void pangea_queues(struct supernet_info *myinfo); int32_t SuperNET_str2hex(uint8_t *hex,char *str); @@ -168,19 +178,19 @@ void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits25 int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits256 subhash,char *hexmsg,int32_t addflag); void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr); void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 subhash); -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash); +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash); char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); -queue_t *category_Q(bits256 categoryhash,bits256 subhash); +queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash); char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr); bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); -struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func); -#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero) +struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func); +#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) void category_init(struct supernet_info *myinfo); char *SuperNET_keysinit(struct supernet_info *myinfo,char *jsonstr); double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double volume,cJSON *argjson); void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256); -char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr); +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); bits256 bitcoin_pubkey33(uint8_t data[33],bits256 privkey); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len); diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c index 1f7c4f231..7ae12630b 100755 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -47,11 +47,15 @@ struct category_info *category_find(bits256 categoryhash,bits256 subhash) return(0); } -queue_t *category_Q(bits256 categoryhash,bits256 subhash) +queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash) { struct category_info *cat; + *catptrp = 0; if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + *catptrp = cat; return(&cat->Q); + } else return(0); } @@ -74,7 +78,7 @@ void *category_infoset(bits256 categoryhash,bits256 subhash,void *info) return(0); } -struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)) +struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)) { struct category_info *cat; if ( (cat= category_find(categoryhash,subhash)) != 0 ) @@ -85,169 +89,19 @@ struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash, return(0); } -int32_t category_default_blockhash(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen) -{ - bits256 hash; - vcalc_sha256(0,hash.bytes,data,datalen); - vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); - return(sizeof(*blockhashp)); -} - -bits256 category_default_stake(struct category_chain *cchain,void *addr,int32_t addrlen) -{ - bits256 stake; - memset(stake.bytes,0,sizeof(stake)); - stake.txid = ((uint64_t)1 << 63); - return(stake); -} - -bits256 catgory_default_hit(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp) -{ - bits256 hash; bits256 rawhit,hit; - memset(rawhit.bytes,0,sizeof(rawhit)); - memset(hit.bytes,0,sizeof(hit)); - vcalc_sha256cat(hash.bytes,prevgenerator,cchain->addrlen,addr,cchain->addrlen); - hit = (*cchain->stake_func)(cchain,addr,cchain->addrlen); - rawhit.txid = hash.txid % ((uint64_t)1 << 42); - if ( rawhit.txid != 0 ) - hit.txid /= rawhit.txid; - return(hit); -} - -#define category_default_heaviest() (*cchain->default_func)(cchain,'H',0,0,0,0,zero) -#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero) -#define category_default_setheaviest(height,blockhashp,heaviest) (*cchain->default_func)(cchain,'S',height,0,0,blockhashp,zero) -#define category_default_weight(height) (*cchain->default_func)(cchain,'W',height,0,0,0,zero) -#define category_default_blockfind(height) (*cchain->default_func)(cchain,'B',height,0,0,0,zero) - -bits256 category_default_func(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) -{ - static bits256 zero; - if ( cchain->hashlen != sizeof(bits256) || cchain->addrlen != sizeof(bits256) ) - { - printf("unsupported hashlen.%d or addrlen.%d\n",cchain->hashlen,cchain->addrlen); - return(zero); - } - if ( height > cchain->maxblocknum + (func == 'S') ) - { - printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,cchain->maxblocknum,height); - return(cchain->category_hwm); - } - if ( func == 'H' ) - return(cchain->category_hwm); - else if ( func == 'L' ) - { - if ( cchain->maxblocknum < 0 ) - return(cchain->cchainhash); - else return(cchain->blocks[cchain->maxblocknum]); - } - else if ( func == 'S' ) - { - cchain->category_hwm = heaviest; - if ( height > cchain->maxblocknum ) - { - cchain->weights = realloc(cchain->weights,(cchain->maxblocknum+1) * sizeof(*cchain->weights)); - cchain->blocks = realloc(cchain->blocks,(cchain->maxblocknum+1) * sizeof(*cchain->blocks)); - } - cchain->maxblocknum = height; - cchain->weights[height] = heaviest; - if ( blockhashp != 0 ) - memcpy(&cchain->blocks[height],blockhashp,sizeof(cchain->blocks[height])); - } - else if ( func == 'B' ) - { - if ( height <= cchain->maxblocknum ) - return(cchain->blocks[height]); - else - { - printf("error: illegal height.%d vs max.%d\n",height,cchain->maxblocknum); - return(zero); - } - } - else if ( func == 'W' ) - { - if ( height >= 0 && height < cchain->maxblocknum ) - return(cchain->weights[height]); - else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,cchain->maxblocknum); - } - return(cchain->category_hwm); -} - -int32_t category_default_ishwm(struct category_chain *cchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) -{ - bits256 checkhash,prevwt,oldhit,hit,heaviest; static bits256 zero; - checkhash = category_default_blockfind(prevheight); - if ( memcmp(checkhash.bytes,prevblockhashp,cchain->hashlen) == 0 ) - { - heaviest = category_default_heaviest(); - prevwt = category_default_weight(prevheight); - oldhit = category_default_weight(prevheight+1); - hit = (*cchain->hit_func)(cchain,prevheight+1,prevgenerator,addr,blockhashp); - if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid ) - { - heaviest.txid = (prevwt.txid + hit.txid); - category_default_setheaviest(prevheight+1,blockhashp,heaviest); - return(prevheight+1); - } - - } else return(-2); - return(-1); -} - -struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func) -{ - struct category_info *cat; struct category_chain *cchain = calloc(1,sizeof(*cchain)); - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - cchain->maxblocknum = -1; - cchain->myinfo = myinfo, cchain->subinfo = cat->info; - if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) - cchain->categoryinfo = cat->info, cchain->cchainhash = categoryhash; - else cchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), cchain->cchainhash = subhash; - if ( cchain->myinfo == 0 || cchain->categoryinfo || cchain->subinfo ) - { - printf("error with cchain pointers\n"); - return(0); - } - if ( (cchain->addrlen= addrlen) <= 0 || (cchain->hashlen= hashlen) <= 0 ) - { - printf("error with cchain lens.%d %d\n",addrlen,hashlen); - return(0); - } - if ( (cchain->blockhash_func= hash_func) == 0 || (cchain->stake_func= stake_func) == 0 || (cchain->hit_func= hit_func) == 0 || (cchain->default_func= default_func) == 0 ) - { - if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) - { - cchain->blockhash_func = category_default_blockhash; - cchain->stake_func = category_default_stake; - cchain->hit_func = catgory_default_hit; - cchain->default_func = category_default_func; - } - else - { - printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); - return(0); - } - } - cat->cchain = cchain; - return(cchain); - } - return(0); -} - -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash) +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash) { queue_t *Q; //char str[65]; printf("getmsg.(%s) %llx\n",bits256_str(str,categoryhash),(long long)subhash.txid); - if ( (Q= category_Q(categoryhash,subhash)) != 0 ) + if ( (Q= category_Q(catptrp,categoryhash,subhash)) != 0 ) return(queue_dequeue(Q,0)); else return(0); } void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr) { - int32_t len; struct category_msg *m; queue_t *Q = 0; - if ( (Q= category_Q(categoryhash,subhash)) != 0 ) + int32_t len; struct category_msg *m; queue_t *Q = 0; struct category_info *cat; + if ( (Q= category_Q(&cat,categoryhash,subhash)) != 0 ) { len = (int32_t)strlen(hexmsg) >> 1; m = calloc(1,sizeof(*m) + len); @@ -345,6 +199,6 @@ void category_init(struct supernet_info *myinfo) pangeahash = calc_categoryhashes(0,"pangea",0); category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); category_processfunc(pangeahash,GENESIS_PUBKEY,pangea_hexmsg); - category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0); + category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0,0,0); exchanges777_init(myinfo,0,0); } diff --git a/iguana/SuperNET_hexmsg.c b/iguana/SuperNET_hexmsg.c index 564beadf4..2c88eebab 100755 --- a/iguana/SuperNET_hexmsg.c +++ b/iguana/SuperNET_hexmsg.c @@ -93,7 +93,7 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *j { if ( cat->processfunc != 0 ) { - if ( (str= (*cat->processfunc)(myinfo,buf,len,remoteaddr)) != 0 ) + if ( (str= (*cat->processfunc)(myinfo,cat,buf,len,remoteaddr)) != 0 ) { if ( retjson != 0 ) jaddstr(retjson,"processfunc",str); @@ -114,3 +114,277 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *j } } } + +int32_t category_default_blockhash(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,data,datalen); + vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); + return(sizeof(*blockhashp)); +} + +bits256 category_default_stake(struct category_chain *catchain,void *addr,int32_t addrlen) +{ + bits256 stake; + memset(stake.bytes,0,sizeof(stake)); + stake.txid = ((uint64_t)1 << 63); + return(stake); +} + +bits256 catgory_default_hit(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp) +{ + bits256 hash; bits256 rawhit,hit; + memset(rawhit.bytes,0,sizeof(rawhit)); + memset(hit.bytes,0,sizeof(hit)); + vcalc_sha256cat(hash.bytes,prevgenerator,catchain->addrlen,addr,catchain->addrlen); + hit = (*catchain->stake_func)(catchain,addr,catchain->addrlen); + rawhit.txid = hash.txid % ((uint64_t)1 << 42); + if ( rawhit.txid != 0 ) + hit.txid /= rawhit.txid; + return(hit); +} + +#define category_default_heaviest() (*catchain->default_func)(catchain,'H',0,0,0,0,zero) +#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) +#define category_default_setheaviest(height,blockhashp,heaviest) (*catchain->default_func)(catchain,'S',height,0,0,blockhashp,zero) +#define category_default_weight(height) (*catchain->default_func)(catchain,'W',height,0,0,0,zero) +#define category_default_blockfind(height) (*catchain->default_func)(catchain,'B',height,0,0,0,zero) + +bits256 category_default_func(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) +{ + static bits256 zero; + if ( catchain->hashlen != sizeof(bits256) || catchain->addrlen != sizeof(bits256) ) + { + printf("unsupported hashlen.%d or addrlen.%d\n",catchain->hashlen,catchain->addrlen); + return(zero); + } + if ( height > catchain->maxblocknum + (func == 'S') ) + { + printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,catchain->maxblocknum,height); + return(catchain->category_hwm); + } + if ( func == 'H' ) + return(catchain->category_hwm); + else if ( func == 'L' ) + { + if ( catchain->maxblocknum < 0 ) + return(catchain->genesishash); + else return(catchain->blocks[catchain->maxblocknum]); + } + else if ( func == 'S' ) + { + catchain->category_hwm = heaviest; + if ( height > catchain->maxblocknum ) + { + catchain->weights = realloc(catchain->weights,(catchain->maxblocknum+1) * sizeof(*catchain->weights)); + catchain->blocks = realloc(catchain->blocks,(catchain->maxblocknum+1) * sizeof(*catchain->blocks)); + } + catchain->maxblocknum = height; + catchain->weights[height] = heaviest; + if ( blockhashp != 0 ) + memcpy(&catchain->blocks[height],blockhashp,sizeof(catchain->blocks[height])); + } + else if ( func == 'B' ) + { + if ( height <= catchain->maxblocknum ) + return(catchain->blocks[height]); + else + { + printf("error: illegal height.%d vs max.%d\n",height,catchain->maxblocknum); + return(zero); + } + } + else if ( func == 'W' ) + { + if ( height >= 0 && height < catchain->maxblocknum ) + return(catchain->weights[height]); + else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,catchain->maxblocknum); + } + return(catchain->category_hwm); +} + +int32_t category_default_ishwm(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) +{ + bits256 checkhash,prevwt,oldhit,hit,heaviest; static bits256 zero; + checkhash = category_default_blockfind(prevheight); + if ( memcmp(checkhash.bytes,prevblockhashp,catchain->hashlen) == 0 ) + { + heaviest = category_default_heaviest(); + prevwt = category_default_weight(prevheight); + oldhit = category_default_weight(prevheight+1); + hit = (*catchain->hit_func)(catchain,prevheight+1,prevgenerator,addr,blockhashp); + if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid ) + { + heaviest.txid = (prevwt.txid + hit.txid); + category_default_setheaviest(prevheight+1,blockhashp,heaviest); + return(prevheight+1); + } + + } else return(-2); + return(-1); +} + +int32_t category_default_payment(struct category_chain *catchain,void *src,void *dest,uint64_t amount) +{ + uint32_t srcind=0,destind=0; + // catchain->balances[destind] += amount; + // catchain->balances[srcind] -= amount; + return(0); +} + +struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func) +{ + struct category_info *cat; struct category_chain *catchain = calloc(1,sizeof(*catchain)); + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + catchain->maxblocknum = -1; + catchain->myinfo = myinfo, catchain->subinfo = cat->info; + if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) + catchain->categoryinfo = cat->info, catchain->genesishash = categoryhash; + else catchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), catchain->genesishash = subhash; + if ( catchain->myinfo == 0 || catchain->categoryinfo || catchain->subinfo ) + { + printf("error with catchain pointers\n"); + return(0); + } + if ( (catchain->addrlen= addrlen) <= 0 || (catchain->hashlen= hashlen) <= 0 ) + { + printf("error with catchain lens.%d %d\n",addrlen,hashlen); + return(0); + } + if ( (catchain->blockhash_func= hash_func) == 0 || (catchain->stake_func= stake_func) == 0 || (catchain->hit_func= hit_func) == 0 || (catchain->default_func= default_func) == 0 || (catchain->ishwm_func= ishwm_func) == 0 || (catchain->payment_func= payment_func) == 0 ) + { + if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) + { + catchain->blockhash_func = category_default_blockhash; + catchain->stake_func = category_default_stake; + catchain->hit_func = catgory_default_hit; + catchain->default_func = category_default_func; + catchain->ishwm_func = category_default_ishwm; + catchain->payment_func = category_default_payment; + } + else + { + printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); + return(0); + } + } + cat->catchain = catchain; + return(catchain); + } + return(0); +} + +struct crypto777_msghdr *crypto777_msgcreate(struct supernet_info *myinfo,struct crypto777_msghdr *msg,int32_t datalen) +{ + bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; + memset(&msg->sig,0,sizeof(msg->sig)); + datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); + data = (void *)((long)msg + sizeof(msg->sig)); + otherpubkey = acct777_msgpubkey(data,datalen); + timestamp = (uint32_t)time(NULL); + acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); + if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + { + //int32_t i; + //char str[65],str2[65]; + //for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); + memset(buf,0,sizeof(buf)); + acct777_rwsig(1,buf,&msg->sig); + memcpy(&msg->sig,buf,sizeof(buf)); + return(msg); + } else printf("error validating crypto777_msgcreate msg\n"); + return(0); +} + +void crypto777_catchain(struct supernet_info *myinfo,struct category_info *cat,bits256 *prevhashp,bits256 *btchashp) +{ + *btchashp = myinfo->BTCmarkerhash; + *prevhashp = cat->catchain->hwmhash; +} + +char *crypto777_sendmsg(struct supernet_info *myinfo,bits256 category,bits256 subhash,uint8_t *data,int32_t datalen,int32_t hops,char cmdstr[8]) +{ + char *hexstr,*retstr; int32_t i; struct crypto777_msghdr *msg; bits256 prevhash,btchash; struct category_info *cat; + msg = calloc(1,datalen + sizeof(*msg)); + for (i=0; icmd); i++) + if ( (msg->cmd[i]= cmdstr[i]) == 0 ) + break; + cat = category_info(category,subhash); + crypto777_catchain(myinfo,cat,&prevhash,&btchash); + iguana_rwbignum(1,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(1,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + memcpy(msg->serialized,data,datalen); + if ( crypto777_msgcreate(myinfo,msg,datalen) != 0 ) + { + printf(">>>>>>>>>>>> crypto777_send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); + hexstr = malloc(msg->sig.allocsize*2 + 1); + init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); + retstr = SuperNET_categorymulticast(myinfo,0,category,subhash,hexstr,0,hops,1,0,0); + free(hexstr), free(msg); + return(retstr); + } + else + { + free(msg); + printf("cant crypto777 msgcreate datalen.%d\n",datalen); + return(clonestr("{\"error\":\"couldnt create crypto777 message\"}")); + } +} + +char *crypto777_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) +{ + struct crypto777_msghdr *msg = ptr; int32_t slen,datalen,newlen,flag = 0; bits256 prevhash,btchash; + uint8_t *serdata; uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; cJSON *argjson = 0; + datalen = len - (int32_t)sizeof(msg->sig); + serdata = (void *)((long)msg + sizeof(msg->sig)); + acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); + memcpy(&msg->sig,tmp,sizeof(msg->sig)); + /*if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) + { + printf("string crypto777_hexmsg RESULT.(%s)\n",jprint(argjson,0)); + free_json(argjson); + return(clonestr("{\"error\":\"string base packets deprecated\"}")); + } + else*/ if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 ) + { + flag++; + iguana_rwbignum(0,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(0,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + printf("crypto777_hexmsg <<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); + serdata = msg->serialized; + if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) + { + slen = (int32_t)strlen((char *)serdata) + 1; + serdata = &serdata[slen]; + newlen -= slen; + free_json(argjson); + } + } + return(clonestr("{\"result\":\"test packet\"}")); +} + +/* + Consensus rules: + 0. Valid burn protocol or new issuance with small fee to crypto777 account -> OP_RETURN on BTCD with txid of payment/burn + Ti boundary - Balances reconciled and signed by issuer or super majority vote. Only amounts marked as frozen eligible for atomic swaps. + tx via p2p, signed payment to dest acct, based on balance. no outputs to double spend + payment valid during Ti and Ti+1 + atomic cross chain: both sides freeze trade amount, wait for this to be confirmed in BTC OP_RETURN, then a joint swap tx is signed by both and submitted to both chains + + valid tx must be accepted and sig added with Ti slippage. It is valid if signed, and balance is available. + + When Ti boundary changes, all online nodes reconcile the submitted tx to make sure all are confirmed and balances updated. Special tx like freezing, atomics, etc. + +Top PoS account publishes balance changes and majority stake approves. Next trade period starts at Ti+2 + + Split into odd/even offset periods to allow nonstop tx + + 1. all nodes must ntp and all tx must be timestamped within 50 seconds in the past and cant be more than 10 seconds from the future. + 2. tx spends cannot exceed available balance/2 as of prior Ti. + 2. all tx must refer to the latest BTC.Ti and BTCD.Ti and BTC.RTblock. any tx received that has older BTC.Ti is rejected. + 3. +*/ diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index 1bf62f06c..db34842a9 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -950,8 +950,13 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle { argjson = cJSON_CreateObject(); for (i=0; iname)) == 0 && (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) - myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; + if ( (exchange= exchanges777_find(Exchange_funcs[i]->name)) == 0 ) + { + if ( strcmp(Exchange_funcs[i]->name,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforx") == 0 ) + continue; + if ( (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; + } free_json(argjson); } instantdexhash = calc_categoryhashes(0,"InstantDEX",0); diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c index f62a02696..96eed5170 100755 --- a/iguana/iguana_instantdex.c +++ b/iguana/iguana_instantdex.c @@ -1040,7 +1040,7 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms return(clonestr("{\"error\":\"request needs argjson\"}")); } -char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr) { struct instantdex_msghdr *msg = ptr; int32_t i,olen,slen,num,datalen,newlen,flag = 0; uint8_t *serdata; struct supernet_info *myinfos[64]; struct instantdex_offer rawoffer; @@ -1060,10 +1060,10 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char free_json(argjson); return(clonestr("{\"error\":\"string base packets deprecated\"}")); } - else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 || 1 ) + else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 )//|| 1 ) { flag++; - //printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); serdata = msg->serialized; //printf("newlen.%d diff.%ld alloc.%d datalen.%d\n",newlen,((long)msg->serialized - (long)msg),msg->sig.allocsize,datalen); @@ -1147,10 +1147,10 @@ char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_acc void instantdex_update(struct supernet_info *myinfo) { - struct instantdex_msghdr *pm; struct category_msg *m; bits256 instantdexhash; char *str,remote[64]; queue_t *Q; struct queueitem *item; + struct instantdex_msghdr *pm; struct category_msg *m; bits256 instantdexhash; char *str,remote[64]; queue_t *Q; struct queueitem *item; struct category_info *cat; instantdexhash = calc_categoryhashes(0,"InstantDEX",0); //char str2[65]; printf("instantdexhash.(%s)\n",bits256_str(str2,instantdexhash)); - if ( (Q= category_Q(instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) + if ( (Q= category_Q(&cat,instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) { m = (void *)item; m = queue_dequeue(Q,0); @@ -1164,7 +1164,7 @@ void instantdex_update(struct supernet_info *myinfo) if ( m->remoteipbits != 0 ) expand_ipbits(remote,m->remoteipbits); else remote[0] = 0; - if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 ) + if ( (str= InstantDEX_hexmsg(myinfo,cat,pm,m->len,remote)) != 0 ) free(str); } //else printf("instantdex_update: unexpected m.%p changed item.%p\n",m,item); free(m); diff --git a/iguana/iguana_pubkeys.c b/iguana/iguana_pubkeys.c index 1e82f8c52..693c63999 100755 --- a/iguana/iguana_pubkeys.c +++ b/iguana/iguana_pubkeys.c @@ -537,6 +537,14 @@ bool bp_key_secret_get(void *p, size_t len, const struct bp_key *key) return true; } +/*void get_shared_secret( unsigned char bytes[ 32 ], const EC_KEY* p_key ) +{ + const EC_POINT* p_pub = EC_KEY_get0_public_key( p_key ); + const BIGNUM* p_priv = EC_KEY_get0_private_key( p_pub_impl->p_key ); + + ECDH_compute_key( &bytes[ 0 ], 32, p_pub, p_pub_impl->p_key, 0 ); +}*/ + bool bp_sign(EC_KEY *key, const void *data, size_t data_len,void **sig_, size_t *sig_len_) { size_t sig_sz = ECDSA_size(key); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index f84bb9416..6e7a84a6d 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -225,7 +225,7 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st return(0); } -struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,uint64_t *balancep,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) +struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *balancep,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) { uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS; *balancep = 0; @@ -364,17 +364,19 @@ long iguana_spentsfile(struct iguana_info *coin,int32_t n) return(total); } -int64_t iguana_pkhashbalance(struct iguana_info *coin,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind) +int64_t iguana_pkhashbalance(struct iguana_info *coin,int64_t *spentp,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind) { struct iguana_unspent *U; struct iguana_txid *T; uint64_t unspentind; int64_t balance = 0; - *nump = 0; + *spentp = *nump = 0; unspentind = lastunspentind; U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); while ( unspentind > 0 ) { (*nump)++; - balance += U[unspentind].value; + if ( ramchain->spents[unspentind].spendind == 0 ) + balance += U[unspentind].value; + else (*spentp) += U[unspentind].value; if ( unspentind == p->firstunspentind ) break; unspentind = U[unspentind].prevunspentind; @@ -384,21 +386,20 @@ int64_t iguana_pkhashbalance(struct iguana_info *coin,int32_t *nump,struct iguan int32_t iguana_pkhasharray(struct iguana_info *coin,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20]) { - int32_t i,n,m; uint64_t balance,checkbalance,total; uint32_t lastunspentind; struct iguana_ramchain *ramchain; + int32_t i,n,m; int64_t spent,balance,netbalance,total; uint32_t lastunspentind; struct iguana_ramchain *ramchain; for (total=i=n=0; ibundlescount; i++) { if ( iguana_pkhashfind(coin,&ramchain,&balance,&lastunspentind,&P[n],rmd160,i,i) != 0 ) { - if ( (checkbalance= iguana_pkhashbalance(coin,&m,ramchain,&P[n],lastunspentind)) != balance ) + if ( (netbalance= iguana_pkhashbalance(coin,&spent,&m,ramchain,&P[n],lastunspentind)) != balance-spent ) { - printf("pkhash balance mismatch from m.%d check %.8f vs %.8f\n",m,dstr(checkbalance),dstr(balance)); + printf("pkhash balance mismatch from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",m,dstr(netbalance),dstr(balance),dstr(spent),dstr(balance)-dstr(spent)); } else { P[n].firstunspentind = lastunspentind; P[n].flags = m; - total += balance; - // use spents to find ! intersections(unspendinds & spents) + total += netbalance; n++; } } diff --git a/iguana/main.c b/iguana/main.c index 367a29e8e..b9871f037 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1137,7 +1137,7 @@ void iguana_main(void *arg) if ( arg != 0 ) SuperNET_JSON(&MYINFO,cJSON_Parse(arg),0); { - int32_t i,n; int64_t total; char *coinaddr; struct iguana_pkhash *P; struct iguana_info *coin; uint8_t rmd160[20],addrtype; + int32_t i,n; int64_t total; char *coinaddr; struct iguana_pkhash *P; struct iguana_info *coin; uint8_t rmd160[20],addrtype; double startmillis; coin = iguana_coinfind("BTCD"); if ( 1 && coin != 0 ) { @@ -1152,8 +1152,10 @@ void iguana_main(void *arg) P = calloc(coin->bundlescount,sizeof(*P)); n = iguana_pkhasharray(coin,&total,P,coin->bundlescount,rmd160); printf("%s has total outputs %.8f from %d bundles\n",coinaddr,dstr(total),n); - n = iguana_pkhasharray(coin,&total,P,coin->bundlescount,rmd160); - printf("%s has total outputs %.8f from %d bundles\n",coinaddr,dstr(total),n); + startmillis = OS_milliseconds(); + for (i=0; i<1000; i++) + n = iguana_pkhasharray(coin,&total,P,coin->bundlescount,rmd160); + printf("%s has total outputs %.8f from %d bundles %.3f millis\n",coinaddr,dstr(total),n,OS_milliseconds()-startmillis); getchar(); } } diff --git a/iguana/pangea_api.c b/iguana/pangea_api.c index 3b16651b3..25e34a89f 100755 --- a/iguana/pangea_api.c +++ b/iguana/pangea_api.c @@ -454,7 +454,7 @@ void pangea_addfunds(PANGEA_HANDARGS) printf("got remote addfunds\n"); } -char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr) +char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr) { static struct { char *cmdstr; void (*func)(PANGEA_HANDARGS); uint64_t cmdbits; } tablecmds[] = { @@ -541,15 +541,15 @@ char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *re void pangea_update(struct supernet_info *myinfo) { - struct pangea_msghdr *pm; struct category_msg *m; bits256 pangeahash; char remoteaddr[64],*str; + struct pangea_msghdr *pm; struct category_msg *m; bits256 pangeahash; char remoteaddr[64],*str; struct category_info *cat = 0; pangeahash = calc_categoryhashes(0,"pangea",0); - while ( (m= category_gethexmsg(myinfo,pangeahash,GENESIS_PUBKEY)) != 0 ) + while ( (m= category_gethexmsg(myinfo,&cat,pangeahash,GENESIS_PUBKEY)) != 0 ) { pm = (struct pangea_msghdr *)m->msg; if ( m->remoteipbits != 0 ) expand_ipbits(remoteaddr,m->remoteipbits); else remoteaddr[0] = 0; - if ( (str= pangea_hexmsg(myinfo,pm,m->len,remoteaddr)) != 0 ) + if ( (str= pangea_hexmsg(myinfo,cat,pm,m->len,remoteaddr)) != 0 ) free(str); free(m); } diff --git a/iguana/swaps/iguana_PAXswap.c b/iguana/swaps/iguana_PAXswap.c index 0d2fdfb80..9f196f256 100755 --- a/iguana/swaps/iguana_PAXswap.c +++ b/iguana/swaps/iguana_PAXswap.c @@ -54,19 +54,220 @@ char *instantdex_PAXswap(struct supernet_info *myinfo,struct exchange_info *exch //#include "../../crypto777/secp256k1/modules/rangeproof/rangeproof_impl.h" void secp256k1_pedersen_context_initialize(secp256k1_context_t *ctx); int secp256k1_pedersen_commit(const secp256k1_context_t* ctx, unsigned char *commit, unsigned char *blind, uint64_t value); +int secp256k1_pedersen_blind_sum(const secp256k1_context_t* ctx, unsigned char *blind_out, const unsigned char * const *blinds, int n, int npositive); +int secp256k1_pedersen_verify_tally(const secp256k1_context_t* ctx, const unsigned char * const *commits, int pcnt,const unsigned char * const *ncommits, int ncnt, int64_t excess); // ./configure --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof + +void CHECK(int32_t val) { if ( val != 1 ) printf("error\n"),getchar(); } + +typedef struct { + uint64_t d[4]; +} secp256k1_scalar_t; + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) { + bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3]; + bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2]; + bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1]; + bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; +} + +#define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL) +#define SECP256K1_N_1 ((uint64_t)0xBAAEDCE6AF48A03BULL) +#define SECP256K1_N_2 ((uint64_t)0xFFFFFFFFFFFFFFFEULL) +#define SECP256K1_N_3 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) +/* Limbs of 2^256 minus the secp256k1 order. */ +#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) +#define SECP256K1_N_C_1 (~SECP256K1_N_1) +#define SECP256K1_N_C_2 (1) + +static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) { + int yes = 0; + int no = 0; + no |= (a->d[3] < SECP256K1_N_3); /* No need for a > check. */ + no |= (a->d[2] < SECP256K1_N_2); + yes |= (a->d[2] > SECP256K1_N_2) & ~no; + no |= (a->d[1] < SECP256K1_N_1); + yes |= (a->d[1] > SECP256K1_N_1) & ~no; + yes |= (a->d[0] >= SECP256K1_N_0) & ~no; + return yes; +} +typedef unsigned uint128_t __attribute__((mode(TI))); + +static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsigned int overflow) { + uint128_t t; + t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; + r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[1] + overflow * SECP256K1_N_C_1; + r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[2] + overflow * SECP256K1_N_C_2; + r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint64_t)r->d[3]; + r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; + return overflow; +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { + int over; + r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56; + r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56; + r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56; + r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56; + over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); + if (overflow) { + *overflow = over; + } +} + +void random_scalar_order(secp256k1_scalar_t *num) { + do { + unsigned char b32[32]; + int overflow = 0; + OS_randombytes(b32,sizeof(b32)); + //secp256k1_rand256(b32); + secp256k1_scalar_set_b32(num, b32, &overflow); + if ( overflow != 0 || bits256_nonz(*(bits256 *)num) == 0 ) + continue; + break; + } while(1); +} + +bits256 rand_secp() +{ + bits256 s,ret; + random_scalar_order((void *)&s); + secp256k1_scalar_get_b32((void *)&ret,(void *)&s); + return(ret); +} + +void test_pedersen(void) { + secp256k1_context_t *ctx; + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pedersen_context_initialize(ctx); + unsigned char commits[33*19]; + const unsigned char *cptr[19]; + unsigned char blinds[32*19]; + const unsigned char *bptr[19]; + uint64_t values[19]; + int64_t totalv; + secp256k1_scalar_t s; + int i; uint8_t r,r2; + int inputs; + int outputs; + int total; + OS_randombytes((void *)&r,sizeof(r)); + OS_randombytes((void *)&r2,sizeof(r2)); + inputs = (r & 7) + 1; + outputs = (r2 & 7) + 2; + total = inputs + outputs; + printf("inputs.%d outputs.%d\n",inputs,outputs); + for (i = 0; i < 19; i++) { + cptr[i] = &commits[i * 33]; + bptr[i] = &blinds[i * 32]; + } + totalv = 0; + for (i = 0; i < inputs; i++) { + OS_randombytes((void *)&r,sizeof(r)); + values[i] = r; + totalv += values[i]; + } + if (1 ){//rand() & 1) { + for (i = 0; i < outputs; i++) { + int64_t max = INT64_MAX; + if (totalv < 0) { + max += totalv; + } + OS_randombytes((void *)&r,sizeof(r)); + values[i + inputs] = r; + totalv -= values[i + inputs]; + } + } else { + for (i = 0; i < outputs - 1; i++) { + OS_randombytes((void *)&r,sizeof(r)); + values[i + inputs] = r; + totalv -= values[i + inputs]; + } + values[total - 1] = totalv >> (rand() & 1); + totalv -= values[total - 1]; + } + for (i = 0; i < total - 1; i++) { + random_scalar_order(&s); + secp256k1_scalar_get_b32(&blinds[i * 32], &s); + } + CHECK(secp256k1_pedersen_blind_sum(ctx, &blinds[(total - 1) * 32], bptr, total - 1, inputs)); + printf("sum total.%d %lld\n",total,(long long)values[total-1]); + for (i = 0; i < total; i++) { + printf("%llu ",(long long)values[i]); + CHECK(secp256k1_pedersen_commit(ctx, &commits[i * 33], &blinds[i * 32], values[i])); + } + printf("commits totalv.%lld\n",(long long)totalv); + CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv)); + printf("tally\n"); + CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv + 1)); + printf("!tally\n"); + getchar(); + return; + for (i = 0; i < 4; i++) { + //OS_randombytes(&blinds[i * 32],32); + *(bits256 *)&blinds[i * 32] = rand_secp(); + } + values[0] = INT64_MAX; + values[1] = 0; + values[2] = 1; + for (i = 0; i < 3; i++) { + CHECK(secp256k1_pedersen_commit(ctx, &commits[i * 33], &blinds[i * 32], values[i])); + } + printf("a\n"); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[2], 1, -1)); + printf("b\n"); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[2], 1, &cptr[1], 1, 1)); + printf("c\n"); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1, 0)); + printf("d\n"); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[1], 1, INT64_MAX)); + printf("e\n"); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1, 0)); + printf("f\n"); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[0], 1, -INT64_MAX)); + printf("g\n"); +} + void ztest() { #ifdef __APPLE__ printf("ztests\n"); - secp256k1_context_t *ctx; uint8_t commit[33],blind[32]; int32_t i,retval; + //test_pedersen(); + secp256k1_context_t *ctx; uint8_t commits[13][33],blinds[13][32]; int32_t i,j,ret,retvals[13]; int64_t val,excess = 0; const uint8_t *commitptrs[13],*blindptrs[13]; bits256 s; ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); - retval = secp256k1_pedersen_commit(ctx,commit,blind,0x14234); - OS_randombytes(blind,sizeof(blind)); - for (i=0; i<33; i++) - printf("%02x",commit[i]); - printf(" pederson commit.%d\n",retval); + for (j=0; j<13; j++) + { + blindptrs[j] = blinds[j]; + commitptrs[j] = commits[j]; + s = rand_secp(); + memcpy(blinds[j],s.bytes,sizeof(s)); + //OS_randombytes(blinds[j],sizeof(blinds[j])); + } + ret = secp256k1_pedersen_blind_sum(ctx,blinds[12],blindptrs,12,12); + for (i=0; i<32; i++) + printf("%02x",blindptrs[12][i]); + printf(" blindsum.%d\n",ret); + for (j=0; j<13; j++) + { + val = (j < 12) ? (j + 1) : -excess; + while ( 1 ) + { + retvals[j] = secp256k1_pedersen_commit(ctx,commits[j],blinds[j],val); + //if ( commits[j][0] == 0x02 ) + break; + } + if ( j < 12 ) + excess += val; + for (i=0; i<33; i++) + printf("%02x",commits[j][i]); + printf(" pederson commit.%d val.%lld\n",retvals[j],(long long)val); + } + ret = secp256k1_pedersen_verify_tally(ctx,commitptrs,12,&commitptrs[12],1,0); + printf("tally.%d vs %lld\n",ret,(long long)excess); //getchar(); #endif } \ No newline at end of file