Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
851c195eab
  1. 95
      basilisk/basilisk.c
  2. 67
      basilisk/basilisk_DEX.c
  3. 28
      basilisk/basilisk_swap.c
  4. 202
      basilisk/basilisk_tradebot.c
  5. 11
      crypto777/OS_portable.h
  6. 2
      crypto777/iguana_utils.c
  7. 16
      iguana/cards777.c
  8. 1
      iguana/iguana777.h
  9. 789
      iguana/iguana_mofn.c
  10. 1
      iguana/iguana_passport.c
  11. 2
      iguana/iguana_realtime.c
  12. 929
      iguana/main.c
  13. 3
      iguana/pangea777.h
  14. 2
      iguana/pangea_hand.c
  15. 24
      includes/iguana_funcs.h
  16. 6
      includes/iguana_structs.h
  17. 1
      includes/iguana_types.h
  18. 10
      includes/libgfshare.h

95
basilisk/basilisk.c

@ -409,6 +409,7 @@ int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits)
#include "basilisk_lisk.c"
#include "basilisk_MSG.c"
#include "basilisk_tradebot.c"
#include "basilisk_swap.c"
#include "basilisk_DEX.c"
#include "basilisk_ping.c"
@ -726,98 +727,6 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t
free(ptr);
}
double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n)
{
int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; uint64_t destamount,minamount = 0,maxamount = 0; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.;
memset(issueR,0,sizeof(*issueR));
minamount = list[0].minamount;
//printf("need to verify null quoteid is list[0] requestid.%u quoteid.%u\n",list[0].requestid,list[0].quoteid);
if ( (active= basilisk_request_started(myinfo,list[0].requestid)) != 0 )
pendingid = active->req.quoteid;
if ( bits256_cmp(myinfo->myaddr.persistent,list[0].hash) == 0 ) // my request
myrequest = 1;
for (i=0; i<n; i++)
{
if ( basilisk_request_cmpref(&list[0],&list[i]) != 0 )
return(-1);
if ( list[i].quoteid != 0 )
{
if ( bits256_cmp(myinfo->myaddr.persistent,list[i].desthash) == 0 ) // my quoteid
myrequest |= 2;
havequoteflag++;
if ( pendingid == 0 )
{
if ( list[i].destamount > maxamount )
{
maxamount = list[i].destamount;
maxi = i;
}
}
else if ( active != 0 && pendingid == list[i].quoteid )
{
}
} else noquoteflag++;
}
//printf("myrequest.%d pendingid.%u noquoteflag.%d havequoteflag.%d maxi.%d %.8f\n",myrequest,pendingid,noquoteflag,havequoteflag,maxi,dstr(maxamount));
if ( myrequest == 0 && pendingid == 0 && noquoteflag != 0 )
{
double retvals[4],aveprice;
aveprice = instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,dstr(list[0].srcamount));
destamount = 0.99 * aveprice * list[0].srcamount;
printf("destamount %.8f aveprice %.8f minamount %.8f\n",dstr(destamount),aveprice,dstr(minamount));
if ( destamount > 0 && destamount >= maxamount && destamount >= minamount )
{
metric = 1.;
*issueR = list[0];
issueR->desthash = myinfo->myaddr.persistent;
issueR->destamount = destamount;
issueR->quotetime = (uint32_t)time(NULL);
}
}
else if ( myrequest != 0 && pendingid == 0 && maxi >= 0 ) // automatch best quote
{
if ( minamount != 0 && maxamount > minamount && time(NULL) > BASILISK_DEXDURATION/2 )
{
printf("automatch quoteid.%u triggered %.8f > %.8f\n",list[maxi].quoteid,dstr(maxamount),dstr(minamount));
*issueR = list[maxi];
if ( minamount > 0 )
metric = (dstr(maxamount) / dstr(minamount)) - 1.;
else metric = 1.;
}
}
return(metric);
}
double basilisk_process_results(struct supernet_info *myinfo,struct basilisk_request *issueR,cJSON *retjson,double hwm)
{
cJSON *array,*item; int32_t i,n,m; struct basilisk_request tmpR,R,refR,list[BASILISK_MAXRELAYS]; double metric=0.;
if ( (array= jarray(&n,retjson,"result")) != 0 )
{
for (i=m=0; i<n; i++)
{
item = jitem(array,i);
if ( i != 0 )
{
basilisk_parsejson(&R,item);
if ( refR.requestid == R.requestid )
list[m++] = R;
else
{
if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm )
*issueR = tmpR, hwm = metric;
m = 0;
}
}
if ( m < sizeof(list)/sizeof(*list) )
basilisk_parsejson(&list[m++],item);
}
if ( m > 0 && m < sizeof(list)/sizeof(*list) )
if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm )
*issueR = tmpR, hwm = metric;
}
return(hwm);
}
void basilisk_requests_poll(struct supernet_info *myinfo)
{
char *retstr; cJSON *outerarray; int32_t i,n; struct basilisk_request issueR; double hwm = 0.;
@ -869,7 +778,7 @@ void basilisks_loop(void *arg)
{
if ( pending != 0 && (pending->finished != 0 || OS_milliseconds() > pending->expiration+60000) )
{
//printf("HASH_DELETE.(%p)\n",pending);
printf("enable free for HASH_DELETE.(%p)\n",pending);
HASH_DELETE(hh,myinfo->basilisks.issued,pending);
//memset(pending,0,sizeof(*pending));
//free(pending);

67
basilisk/basilisk_DEX.c

@ -17,33 +17,6 @@
// requestid is invariant for a specific request
// quoteid is invariant for a specific request after dest fields are set
uint32_t basilisk_requestid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
R.requestid = R.quoteid = R.quotetime = 0;
R.destamount = 0;
R.relaybits = 0;
memset(R.desthash.bytes,0,sizeof(R.desthash.bytes));
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(R); i++)
printf("%02x",((uint8_t *)&R)[i]);
printf(" <- crc.%u\n",calc_crc32(0,(void *)&R,sizeof(R)));
char str[65],str2[65]; printf("B REQUESTID: t.%u r.%u q.%u %s %.8f %s -> %s %.8f %s crc.%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.hash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R)));
}
return(calc_crc32(0,(void *)&R,sizeof(R)));
}
uint32_t basilisk_quoteid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
R.requestid = R.quoteid = R.relaybits = 0;
return(calc_crc32(0,(void *)&R,sizeof(R)));
}
int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp)
{
int32_t len = 0;
@ -91,38 +64,9 @@ uint32_t basilisk_request_enqueue(struct supernet_info *myinfo,struct basilisk_r
return(0);
}
struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson)
{
uint32_t requestid,quoteid; //char *msgstr;
memset(rp,0,sizeof(*rp));
rp->hash = jbits256(reqjson,"hash");
rp->desthash = jbits256(reqjson,"desthash");
rp->srcamount = j64bits(reqjson,"srcamount");
rp->minamount = j64bits(reqjson,"minamount");
rp->destamount = j64bits(reqjson,"destamount");
requestid = juint(reqjson,"requestid");
quoteid = juint(reqjson,"quoteid");
if ( jstr(reqjson,"relay") != 0 )
rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay"));
rp->timestamp = juint(reqjson,"timestamp");
rp->quotetime = juint(reqjson,"quotetime");
safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src));
safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest));
if ( quoteid != 0 )
{
rp->quoteid = basilisk_quoteid(rp);
if ( quoteid != rp->quoteid )
printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid);
}
rp->requestid = basilisk_requestid(rp);
if ( requestid != rp->requestid )
printf("basilisk_parsejson requestid.%u != %u error\n",requestid,rp->requestid);
return(rp);
}
cJSON *basilisk_requestjson(struct basilisk_request *rp)
{
char ipaddr[64]; cJSON *item = cJSON_CreateObject(); //*msgobj,
char ipaddr[64]; cJSON *item = cJSON_CreateObject();
if ( rp->relaybits != 0 )
{
expand_ipbits(ipaddr,rp->relaybits);
@ -596,12 +540,3 @@ TWO_INTS(InstantDEX,accept,requestid,quoteid)
}
}
#include "../includes/iguana_apiundefs.h"
int32_t basilisk_request_cmpref(struct basilisk_request *ref,struct basilisk_request *rp)
{
if ( bits256_cmp(rp->hash,ref->hash) != 0 || memcmp(rp->src,ref->src,sizeof(ref->src)) != 0 || memcmp(rp->dest,ref->dest,sizeof(ref->dest)) != 0 || rp->srcamount != ref->srcamount || rp->timestamp != ref->timestamp )
{
printf("basilisk_request_listprocess mismatched hash\n");
return(-1);
} else return(0);
}

28
basilisk/basilisk_swap.c

@ -1088,7 +1088,11 @@ void basilisk_swaploop(void *_swap)
basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend);
if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobspend,0x40000) == 0 )
printf("Bob error spending alice payment\n");
else printf("Bob spend alicepayment\n");
else
{
basilisk_swap_balancingtrade(myinfo,swap,1);
printf("Bob spends alicepayment\n");
}
break;
}
else if ( basilisk_privAm_extract(myinfo,swap) == 0 )
@ -1097,7 +1101,11 @@ void basilisk_swaploop(void *_swap)
swap->statebits |= 0x40000;
if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobspend,0x40000) == 0 )
printf("Bob error spending alice payment after privAm\n");
else printf("Bob spends alicepayment\n");
else
{
basilisk_swap_balancingtrade(myinfo,swap,1);
printf("Bob spends alicepayment\n");
}
break;
}
else if ( swap->bobpayment.locktime != 0 && time(NULL) > swap->bobpayment.locktime )
@ -1199,6 +1207,7 @@ void basilisk_swaploop(void *_swap)
data[datalen++] = swap->privAm.bytes[j];
swap->statebits |= basilisk_swapsend(myinfo,swap,0x40000,data,datalen,0x20000);
swap->sleeptime = 1;
basilisk_swap_balancingtrade(myinfo,swap,0);
}
}
else if ( (swap->statebits & 0x40000) == 0 )
@ -1265,18 +1274,3 @@ struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,struct
portable_mutex_unlock(&myinfo->DEX_swapmutex);
return(swap);
}
struct basilisk_swap *basilisk_request_started(struct supernet_info *myinfo,uint32_t requestid)
{
int32_t i; struct basilisk_swap *active = 0;
portable_mutex_lock(&myinfo->DEX_swapmutex);
for (i=0; i<myinfo->numswaps; i++)
if ( myinfo->swaps[i]->req.requestid == requestid )
{
//printf("REQUEST STARTED.[%d] <- req.%u\n",i,requestid);
active = myinfo->swaps[i];
break;
}
portable_mutex_unlock(&myinfo->DEX_swapmutex);
return(active);
}

202
basilisk/basilisk_tradebot.c

@ -0,0 +1,202 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
// included from basilisk.c
uint32_t basilisk_requestid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
R.requestid = R.quoteid = R.quotetime = 0;
R.destamount = 0;
R.relaybits = 0;
memset(R.desthash.bytes,0,sizeof(R.desthash.bytes));
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(R); i++)
printf("%02x",((uint8_t *)&R)[i]);
printf(" <- crc.%u\n",calc_crc32(0,(void *)&R,sizeof(R)));
char str[65],str2[65]; printf("B REQUESTID: t.%u r.%u q.%u %s %.8f %s -> %s %.8f %s crc.%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.hash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R)));
}
return(calc_crc32(0,(void *)&R,sizeof(R)));
}
uint32_t basilisk_quoteid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
R.requestid = R.quoteid = R.relaybits = 0;
return(calc_crc32(0,(void *)&R,sizeof(R)));
}
struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson)
{
uint32_t requestid,quoteid;
memset(rp,0,sizeof(*rp));
rp->hash = jbits256(reqjson,"hash");
rp->desthash = jbits256(reqjson,"desthash");
rp->srcamount = j64bits(reqjson,"srcamount");
rp->minamount = j64bits(reqjson,"minamount");
rp->destamount = j64bits(reqjson,"destamount");
requestid = juint(reqjson,"requestid");
quoteid = juint(reqjson,"quoteid");
if ( jstr(reqjson,"relay") != 0 )
rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay"));
rp->timestamp = juint(reqjson,"timestamp");
rp->quotetime = juint(reqjson,"quotetime");
safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src));
safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest));
if ( quoteid != 0 )
{
rp->quoteid = basilisk_quoteid(rp);
if ( quoteid != rp->quoteid )
printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid);
}
rp->requestid = basilisk_requestid(rp);
if ( requestid != rp->requestid )
printf("basilisk_parsejson requestid.%u != %u error\n",requestid,rp->requestid);
return(rp);
}
void basilisk_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob)
{
// update balance, compare to target balance, issue balancing trade via central exchanges, if needed
if ( iambob != 0 )
{
}
else
{
}
}
struct basilisk_swap *basilisk_request_started(struct supernet_info *myinfo,uint32_t requestid)
{
int32_t i; struct basilisk_swap *active = 0;
portable_mutex_lock(&myinfo->DEX_swapmutex);
for (i=0; i<myinfo->numswaps; i++)
if ( myinfo->swaps[i]->req.requestid == requestid )
{
//printf("REQUEST STARTED.[%d] <- req.%u\n",i,requestid);
active = myinfo->swaps[i];
break;
}
portable_mutex_unlock(&myinfo->DEX_swapmutex);
return(active);
}
int32_t basilisk_request_cmpref(struct basilisk_request *ref,struct basilisk_request *rp)
{
if ( bits256_cmp(rp->hash,ref->hash) != 0 || memcmp(rp->src,ref->src,sizeof(ref->src)) != 0 || memcmp(rp->dest,ref->dest,sizeof(ref->dest)) != 0 || rp->srcamount != ref->srcamount || rp->timestamp != ref->timestamp )
{
printf("basilisk_request_listprocess mismatched hash\n");
return(-1);
} else return(0);
}
double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n)
{
int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; uint64_t destamount,minamount = 0,maxamount = 0; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.;
memset(issueR,0,sizeof(*issueR));
minamount = list[0].minamount;
//printf("need to verify null quoteid is list[0] requestid.%u quoteid.%u\n",list[0].requestid,list[0].quoteid);
if ( (active= basilisk_request_started(myinfo,list[0].requestid)) != 0 )
pendingid = active->req.quoteid;
if ( bits256_cmp(myinfo->myaddr.persistent,list[0].hash) == 0 ) // my request
myrequest = 1;
for (i=0; i<n; i++)
{
if ( basilisk_request_cmpref(&list[0],&list[i]) != 0 )
return(-1);
if ( list[i].quoteid != 0 )
{
if ( bits256_cmp(myinfo->myaddr.persistent,list[i].desthash) == 0 ) // my quoteid
myrequest |= 2;
havequoteflag++;
if ( pendingid == 0 )
{
if ( list[i].destamount > maxamount )
{
maxamount = list[i].destamount;
maxi = i;
}
}
else if ( active != 0 && pendingid == list[i].quoteid )
{
}
} else noquoteflag++;
}
//printf("myrequest.%d pendingid.%u noquoteflag.%d havequoteflag.%d maxi.%d %.8f\n",myrequest,pendingid,noquoteflag,havequoteflag,maxi,dstr(maxamount));
if ( myrequest == 0 && pendingid == 0 && noquoteflag != 0 )
{
double retvals[4],aveprice;
aveprice = instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,1.3 * dstr(list[0].srcamount));
destamount = 0.99 * aveprice * list[0].srcamount;
printf("destamount %.8f aveprice %.8f minamount %.8f\n",dstr(destamount),aveprice,dstr(minamount));
if ( destamount > 0 && destamount >= maxamount && destamount >= minamount )
{
metric = 1.;
*issueR = list[0];
issueR->desthash = myinfo->myaddr.persistent;
issueR->destamount = destamount;
issueR->quotetime = (uint32_t)time(NULL);
}
}
else if ( myrequest != 0 && pendingid == 0 && maxi >= 0 ) // automatch best quote
{
if ( minamount != 0 && maxamount > minamount && time(NULL) > BASILISK_DEXDURATION/2 )
{
printf("automatch quoteid.%u triggered %.8f > %.8f\n",list[maxi].quoteid,dstr(maxamount),dstr(minamount));
*issueR = list[maxi];
if ( minamount > 0 )
metric = (dstr(maxamount) / dstr(minamount)) - 1.;
else metric = 1.;
}
}
return(metric);
}
double basilisk_process_results(struct supernet_info *myinfo,struct basilisk_request *issueR,cJSON *retjson,double hwm)
{
cJSON *array,*item; int32_t i,n,m; struct basilisk_request tmpR,R,refR,list[BASILISK_MAXRELAYS]; double metric=0.;
if ( (array= jarray(&n,retjson,"result")) != 0 )
{
for (i=m=0; i<n; i++)
{
item = jitem(array,i);
if ( i != 0 )
{
basilisk_parsejson(&R,item);
if ( refR.requestid == R.requestid )
list[m++] = R;
else
{
if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm )
*issueR = tmpR, hwm = metric;
m = 0;
}
}
if ( m < sizeof(list)/sizeof(*list) )
basilisk_parsejson(&list[m++],item);
}
if ( m > 0 && m < sizeof(list)/sizeof(*list) )
if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm )
*issueR = tmpR, hwm = metric;
}
return(hwm);
}

11
crypto777/OS_portable.h

@ -175,7 +175,7 @@ void *OS_nonportable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,l
char *OS_portable_path(char *str);
int32_t OS_nonportable_renamefile(char *fname,char *newfname);
int32_t OS_nonportable_launch(char *args[]);
void OS_nonportable_randombytes(unsigned char *x,long xlen);
void OS_nonportable_randombytes(uint8_t *x,long xlen);
int32_t OS_nonportable_init();
#endif
@ -183,7 +183,7 @@ void OS_portable_init();
void OS_init();
double OS_portable_milliseconds();
void OS_portable_randombytes(unsigned char *x,long xlen);
void OS_portable_randombytes(uint8_t *x,long xlen);
int32_t OS_portable_truncate(char *fname,long filesize);
char *OS_portable_path(char *str);
void OS_remove_directory(char *dirname);
@ -203,7 +203,7 @@ uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t sec
int32_t OS_conv_unixtime(struct tai *t,int32_t *secondsp,time_t timestamp);
double OS_milliseconds();
void OS_randombytes(unsigned char *x,long xlen);
void OS_randombytes(uint8_t *x,long xlen);
int32_t OS_truncate(char *fname,long filesize);
char *OS_compatible_path(char *str);
@ -261,12 +261,12 @@ int32_t is_decimalstr(char *str);
void tolowercase(char *str);
char *clonestr(char *str);
int32_t is_hexstr(char *str,int32_t n);
int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
void reverse_hexstr(char *str);
int32_t init_hexbytes_noT(char *hexbytes,uint8_t *message,long len);
uint16_t parse_ipaddr(char *ipaddr,char *ip_port);
int32_t bitweight(uint64_t x);
unsigned char _decode_hex(char *hex);
uint8_t _decode_hex(char *hex);
char *uppercase_str(char *buf,char *str);
char *lowercase_str(char *buf,char *str);
int32_t strsearch(char *strs[],int32_t num,char *name);
@ -371,7 +371,6 @@ bits256 bits256_from_compact(uint32_t c);
uint32_t bits256_to_compact(bits256 x);
bits256 bits256_conv(char *hexstr);
int32_t btc_priv2pub(uint8_t pubkey[33],uint8_t privkey[32]);
void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs);
int32_t OS_portable_rmdir(char *dirname,int32_t diralso);
void calc_hmac_sha256(uint8_t *mac,int32_t maclen,uint8_t *key,int32_t key_size,uint8_t *message,int32_t len);
int32_t revsort32(uint32_t *buf,uint32_t num,int32_t size);

2
crypto777/iguana_utils.c

@ -92,11 +92,13 @@ int32_t bits256_cmp(bits256 a,bits256 b)
int32_t i;
for (i=3; i>=0; i--)
{
//printf("%llx %llx, ",(long long)a.ulongs[i],(long long)b.ulongs[i]);
if ( a.ulongs[i] > b.ulongs[i] )
return(1);
else if ( a.ulongs[i] < b.ulongs[i] )
return(-1);
}
//printf("thesame\n");
return(0);
}

16
iguana/cards777.c

@ -130,11 +130,11 @@ void cards777_layer(bits256 *layered,bits256 *xoverz,bits256 *incards,int32_t nu
}
}
int32_t cards777_calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N)
int32_t cards777_calcmofn(struct supernet_info *myinfo,uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N)
{
int32_t size,j;
int32_t size,j; uint8_t space[8192];
size = N * sizeof(bits256) * numcards;
calc_shares(allshares,(void *)xoverz,size,size,M,N,sharenrs); // PM &allshares[playerj * size] to playerJ
calc_shares(myinfo,allshares,(void *)xoverz,size,size,M,N,sharenrs,space,sizeof(space)); // PM &allshares[playerj * size] to playerJ
for (j=0; j<N; j++)
myshares[j] = &allshares[j * size];
return(size);
@ -142,7 +142,7 @@ int32_t cards777_calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharen
uint8_t *cards777_recover(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t numcards,int32_t N)
{
void *G; int32_t i,size; uint8_t *recover,recovernrs[255];
void *G; int32_t i,size; uint8_t *recover,recovernrs[255],space[8192];
size = N * sizeof(bits256) * numcards;
if ( (recover= calloc(1,size)) == 0 )
{
@ -153,12 +153,12 @@ uint8_t *cards777_recover(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t
for (i=0; i<N; i++)
if ( shares[i] != 0 )
recovernrs[i] = sharenrs[i];
G = gfshare_ctx_init_dec(recovernrs,N,size);
G = gfshare_ctx_initdec(recovernrs,N,size,space,sizeof(space));
for (i=0; i<N; i++)
if ( shares[i] != 0 )
gfshare_ctx_dec_giveshare(G,i,shares[i]);
gfshare_ctx_dec_newshares(G,recovernrs);
gfshare_ctx_dec_extract(G,recover);
gfshare_ctx_decextract(0,0,G,recover);
gfshare_ctx_free(G);
return(recover);
}
@ -229,14 +229,14 @@ bits256 cards777_initdeck(bits256 *cards,bits256 *cardpubs,int32_t numcards,int3
return(prod);
}
uint8_t *cards777_encode(bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N)
uint8_t *cards777_encode(struct supernet_info *myinfo,bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N)
{
bits256 shuffled[CARDS777_MAXCARDS * CARDS777_MAXPLAYERS];
cards777_shuffle(shuffled,ciphers,numcards,N);
cards777_layer(encoded,xoverz,shuffled,numcards,N);
memset(sharenrs,0,255);
init_sharenrs(sharenrs,0,N,N);
cards777_calcmofn(allshares,myshares,sharenrs,M,xoverz,numcards,N);
cards777_calcmofn(myinfo,allshares,myshares,sharenrs,M,xoverz,numcards,N);
memcpy(ciphers,shuffled,numcards * N * sizeof(bits256));
if ( 0 )
{

1
iguana/iguana777.h

@ -64,6 +64,7 @@ struct supernet_info
int32_t numrelays,RELAYID;
// compatibility
bits256 pangea_category,instantdex_category;
uint8_t logs[256],exps[510];
};
#endif

789
iguana/iguana_mofn.c

@ -0,0 +1,789 @@
/*
* This file is Copyright Daniel Silverstone <dsilvers@digital-scurf.org> 2006,2015
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#include "iguana777.h"
#include "secp256k1/include/secp256k1.h"
#include "secp256k1/include/secp256k1_schnorr.h"
#include "secp256k1/include/secp256k1_rangeproof.h"
// ------------------------------------------------------[ Preparation ]----
static gfshare_ctx *_gfshare_ctx_init_core(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size,void *space,int32_t spacesize)
{
gfshare_ctx *ctx; int32_t allocsize;
allocsize = (int32_t)(sizeof(struct _gfshare_ctx) + threshold * size);
if ( allocsize > spacesize )
{
printf("malloc allocsize %d vs spacesize.%d\n",allocsize,spacesize);
ctx = malloc(allocsize);
if( ctx == NULL )
return NULL; // errno should still be set from XMALLOC()
ctx->allocsize = allocsize;
} else ctx = space;
memset(ctx,0,allocsize);
ctx->sharecount = sharecount;
ctx->threshold = threshold;
ctx->size = size;
memcpy(ctx->sharenrs,sharenrs,sharecount);
ctx->buffersize = threshold * size;
return(ctx);
}
// Initialise a gfshare context for producing shares
gfshare_ctx *gfshare_ctx_initenc(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size,void *space,int32_t spacesize)
{
uint32_t i;
for (i=0; i<sharecount; i++)
{
if ( sharenrs[i] == 0 )
{
// can't have x[i] = 0 - that would just be a copy of the secret, in
// theory (in fact, due to the way we use exp/log for multiplication and
// treat log(0) as 0, it ends up as a copy of x[i] = 1)
errno = EINVAL;
return NULL;
}
}
return(_gfshare_ctx_init_core(sharenrs,sharecount,threshold,size,space,spacesize));
}
// Initialise a gfshare context for recombining shares
gfshare_ctx *gfshare_ctx_initdec(uint8_t *sharenrs,uint32_t sharecount,uint32_t size,void *space,int32_t spacesize)
{
gfshare_ctx *ctx = _gfshare_ctx_init_core(sharenrs,sharecount,sharecount,size,space,spacesize);
if ( ctx != NULL )
ctx->threshold = 0;
return(ctx);
}
// Free a share context's memory
void gfshare_ctx_free(gfshare_ctx *ctx)
{
OS_randombytes(ctx->buffer,ctx->buffersize);
OS_randombytes(ctx->sharenrs,ctx->sharecount);
if ( ctx->allocsize != 0 )
{
OS_randombytes((uint8_t *)ctx,sizeof(struct _gfshare_ctx));
free(ctx);
}
OS_randombytes((uint8_t *)ctx,sizeof(struct _gfshare_ctx));
}
// --------------------------------------------------------[ Splitting ]----
// Provide a secret to the encoder. (this re-scrambles the coefficients)
void gfshare_ctx_enc_setsecret(gfshare_ctx *ctx,uint8_t *secret)
{
memcpy(ctx->buffer + ((ctx->threshold-1) * ctx->size),secret,ctx->size);
OS_randombytes(ctx->buffer,(ctx->threshold-1) * ctx->size);
}
// Extract a share from the context. 'share' must be preallocated and at least 'size' bytes long. 'sharenr' is the index into the 'sharenrs' array of the share you want.
void gfshare_ctx_encgetshare(uint8_t *_logs,uint8_t *_exps,gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share)
{
uint32_t pos,coefficient,ilog = _logs[ctx->sharenrs[sharenr]];
uint8_t *share_ptr,*coefficient_ptr = ctx->buffer;
for (pos=0; pos<ctx->size; pos++)
share[pos] = *(coefficient_ptr++);
for (coefficient=1; coefficient<ctx->threshold; coefficient++)
{
share_ptr = share;
for (pos=0; pos<ctx->size; pos++)
{
uint8_t share_byte = *share_ptr;
if ( share_byte != 0 )
share_byte = _exps[ilog + _logs[share_byte]];
*share_ptr++ = share_byte ^ *coefficient_ptr++;
}
}
}
// ----------------------------------------------------[ Recombination ]----
// Inform a recombination context of a change in share indexes
void gfshare_ctx_dec_newshares(gfshare_ctx *ctx,uint8_t *sharenrs)
{
memcpy(ctx->sharenrs,sharenrs,ctx->sharecount);
}
// Provide a share context with one of the shares. The 'sharenr' is the index into the 'sharenrs' array
void gfshare_ctx_dec_giveshare(gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share)
{
memcpy(ctx->buffer + (sharenr * ctx->size),share,ctx->size);
}
// Extract the secret by interpolating the shares. secretbuf must be allocated and at least 'size' bytes
void gfshare_ctx_decextract(uint8_t *_logs,uint8_t *_exps,gfshare_ctx *ctx,uint8_t *secretbuf)
{
uint32_t i,j; uint8_t *secret_ptr,*share_ptr,sharei,sharej;
for (i=0; i<ctx->size; i++)
secretbuf[i] = 0;
for (i=0; i<ctx->sharecount; i++)
{
// Compute L(i) as per Lagrange Interpolation
unsigned Li_top = 0, Li_bottom = 0;
if ( (sharei= ctx->sharenrs[i]) != 0 )
{
for (j=0; j<ctx->sharecount; j++)
{
if ( i != j && sharei != (sharej= ctx->sharenrs[j]) )
{
if ( sharej == 0 )
continue; // skip empty share
Li_top += _logs[sharej];
if ( Li_top >= 0xff )
Li_top -= 0xff;
Li_bottom += _logs[sharei ^ sharej];
if ( Li_bottom >= 0xff )
Li_bottom -= 0xff;
}
}
if ( Li_bottom > Li_top )
Li_top += 0xff;
Li_top -= Li_bottom; // Li_top is now log(L(i))
secret_ptr = secretbuf, share_ptr = ctx->buffer + (ctx->size * i);
for (j=0; j<ctx->size; j++)
{
if ( *share_ptr != 0 )
*secret_ptr ^= _exps[Li_top + _logs[*share_ptr]];
share_ptr++, secret_ptr++;
}
}
}
}
int32_t gfshare_test(struct supernet_info *myinfo,int32_t M,int32_t N,int32_t datasize)
{
int ok = 1, i,k;
uint8_t * secret = malloc(datasize);
uint8_t *shares[255];
uint8_t *recomb = malloc(datasize);
uint8_t space[8192],sharenrs[255],newsharenrs[255];// = (uint8_t *)strdup("0124z89abehtr");
gfshare_ctx *G;
for (i=0; i<N; i++)
{
sharenrs[i] = i+1;
shares[i] = malloc(datasize);
}
init_sharenrs(sharenrs,0,N,N);
/* Stage 1, make a secret */
for( i = 0; i < datasize; ++i )
secret[i] = (rand() & 0xff00) >> 8;
/* Stage 2, split it N ways with a threshold of M */
G = gfshare_ctx_initenc( sharenrs, N, M, datasize,space,sizeof(space) );
gfshare_ctx_enc_setsecret( G, secret );
for (i=0; i<N; i++)
gfshare_ctx_encgetshare(myinfo->logs,myinfo->exps, G, i, shares[i] );
gfshare_ctx_free( G );
/* Prep the decode shape */
uint8_t save[255];
memcpy(save,sharenrs,sizeof(sharenrs));
G = gfshare_ctx_initdec( sharenrs, N, datasize,space,sizeof(space) );
for (k=0; k<10; k++)
{
memcpy(sharenrs,save,sizeof(sharenrs));
memset(newsharenrs,0,N);
int32_t j,r,m;
m = M + (rand() % (N-M+1));
for (i=0; i<m && i<N; i++)
{
r = rand() % N;
while ( (j= sharenrs[r]) == 0 || newsharenrs[r] != 0 )
r = rand() % N;
newsharenrs[r] = j;
sharenrs[r] = 0;
}
for (i=0; i<N; i++)
{
if ( newsharenrs[i] != 0 )
{
fprintf(stderr,"%d ",newsharenrs[i]);
gfshare_ctx_dec_giveshare( G, i, shares[i] );
}
//newsharenrs[i] = sharenrs[i];
}
gfshare_ctx_dec_newshares( G, newsharenrs );
gfshare_ctx_decextract(myinfo->logs,myinfo->exps, G, recomb );
for (i=0; i<datasize; i++)
if ( secret[i] != recomb[i] )
ok = 0;
printf("m.%d M.%-3d N.%-3d ok.%d datalen.%d\n",m,M,N,ok,datasize);
}
free(recomb), free(secret);
for (i=0; i<N; i++)
free(shares[i]);
return ok!=1;
}
void libgfshare_init(struct supernet_info *myinfo,uint8_t _logs[256],uint8_t _exps[510])
{
uint32_t i,x = 1;
myinfo->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(myinfo->ctx);
secp256k1_rangeproof_context_initialize(myinfo->ctx);
for (i=0; i<255; i++)
{
_exps[i] = x;
_logs[x] = i;
x <<= 1;
if ( x & 0x100 )
x ^= 0x11d; // Unset the 8th bit and mix in 0x1d
}
for (i=255; i<510; i++)
_exps[i] = _exps[i % 255];
_logs[0] = 0; // can't log(0) so just set it neatly to 0
if ( 0 )
{
void test_mofn(struct supernet_info *myinfo);
gfshare_test(myinfo,6,11,32);
test_mofn(myinfo);
getchar();
}
}
// Construct and write out the tables for the gfshare code
int maingen(int argc,char **argv)
{
uint8_t logs[256],exps[255]; uint32_t i;
libgfshare_init(0,logs,exps);
// The above generation algorithm clearly demonstrates that
// logs[exps[i]] == i for 0 <= i <= 254
// exps[logs[i]] == i for 1 <= i <= 255
// Spew out the tables
fprintf(stdout, "\
/*\n\
* This file is autogenerated by gfshare_maketable.\n\
*/\n\
\n\
static uint8_t logs[256] = {\n ");
for ( i = 0; i < 256; ++i )
{
fprintf(stdout, "0x%02x", logs[i]);
if( i == 255 )
fprintf(stdout, " };\n");
else if( (i % 8) == 7 )
fprintf(stdout, ",\n ");
else
fprintf(stdout, ", ");
}
// The exp table we output from 0 to 509 because that way when we
// do the lagrange interpolation we don't have to be quite so strict
// with staying inside the field which makes it quicker
fprintf(stdout, "\
\n\
static uint8_t exps[510] = {\n ");
for ( i = 0; i < 510; ++i )
{
fprintf(stdout, "0x%02x", exps[i % 255]); /* exps[255]==exps[0] */
if ( i == 509 )
fprintf(stdout, " };\n");
else if( (i % 8) == 7)
fprintf(stdout, ",\n ");
else
fprintf(stdout, ", ");
}
return 0;
}
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n)
{
uint8_t *randvals,valid[255];
int32_t i,j,r,remains,orign;
if ( m > n || n >= 0xff ) // reserve 255 for illegal sharei
{
printf("illegal M.%d of N.%d\n",m,n);
return(-1);
}
randvals = calloc(1,65536);
OS_randombytes(randvals,65536);
if ( orig == 0 && n == m )
{
memset(sharenrs,0,n);
for (i=0; i<255; i++)
valid[i] = (i + 1);
remains = orign = 255;
for (i=0; i<n; i++)
{
r = (randvals[i] % remains);
sharenrs[i] = valid[r];
printf("%d ",sharenrs[i]);
valid[r] = valid[--remains];
}
printf("FULL SET\n");
}
else
{
memcpy(valid,orig,n);
memset(sharenrs,0,n);
for (i=0; i<n; i++)
printf("%d ",valid[i]);
printf("valid\n");
for (i=0; i<m; i++)
{
r = rand() % n;
while ( (j= valid[r]) == 0 )
{
//printf("i.%d j.%d m.%d n.%d r.%d\n",i,j,m,n,r);
r = rand() % n;
}
sharenrs[i] = j;
valid[r] = 0;
}
for (i=0; i<n; i++)
printf("%d ",valid[i]);
printf("valid\n");
for (i=0; i<m; i++)
printf("%d ",sharenrs[i]);
printf("sharenrs vals m.%d of n.%d\n",m,n);
//getchar();
}
free(randvals);
for (i=0; i<m; i++)
{
for (j=0; j<m; j++)
{
if ( i == j )
continue;
if ( sharenrs[i] != 0 && sharenrs[i] == sharenrs[j] )
{
printf("FATAL: duplicate entry sharenrs[%d] %d vs %d sharenrs[%d]\n",i,sharenrs[i],sharenrs[j],j);
return(-1);
}
}
}
return(0);
}
uint8_t *recoverdata(struct supernet_info *myinfo,uint8_t *shares[],uint8_t *sharenrs,int32_t M,uint8_t *recover,int32_t datasize,int32_t N)
{
void *G; int32_t i,m=0; uint8_t recovernrs[255],space[8192];
memset(recovernrs,0,sizeof(recovernrs));
for (i=0; i<N; i++)
if ( shares[i] != 0 )
recovernrs[i] = sharenrs[i], m++;
if ( m >= M )
{
G = gfshare_ctx_initdec(recovernrs,N,datasize,space,sizeof(space));
for (i=0; i<N; i++)
if ( shares[i] != 0 )
gfshare_ctx_dec_giveshare(G,i,shares[i]);
gfshare_ctx_dec_newshares(G,recovernrs);
gfshare_ctx_decextract(myinfo->logs,myinfo->exps,G,recover);
gfshare_ctx_free(G);
return(recover);
} else return(0);
}
void calc_share(struct supernet_info *myinfo,uint8_t *buffer,int32_t size,int32_t M,uint32_t ilog,uint8_t *share)
{
uint32_t pos,coefficient; uint8_t *share_ptr,share_byte;
for (pos=0; pos<size; pos++)
share[pos] = *(buffer++);
for (coefficient=1; coefficient<M; coefficient++)
{
share_ptr = share;
for (pos=0; pos<size; pos++)
{
share_byte = *share_ptr;
if ( share_byte != 0 )
share_byte = myinfo->exps[ilog + myinfo->logs[share_byte]];
*share_ptr++ = (share_byte ^ *buffer++);
}
}
}
void calc_shares(struct supernet_info *myinfo,uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs,uint8_t *space,int32_t spacesize)
{
int32_t i; uint8_t *buffer;
if ( M*width > spacesize )
{
buffer = calloc(M,width);
printf("calloc M.%d width.%d\n",M,width);
} else buffer = space;
memset(shares,0,N * width);
memcpy(buffer + ((M - 1) * size),secret,size);
OS_randombytes(buffer,(M - 1) * size);
for (i=0; i<N; i++)
{
calc_share(myinfo,buffer,size,M,myinfo->logs[sharenrs[i]],&shares[i * width]);
//printf("(%03d %08x) ",sharenrs[i],calc_crc32(0,&shares[i * width],size));
}
if ( buffer != space )
free(buffer);
}
int32_t calc_sharenrs(uint8_t *sharenrs,int32_t N,uint8_t *data,int32_t datasize)
{
bits256 hash,hash2; uint8_t r; int32_t i,j,n = sizeof(hash);
vcalc_sha256(0,hash.bytes,data,datasize);
vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash));
for (i=0; i<N; i++)
{
while ( 1 )
{
if ( n >= sizeof(hash) )
{
vcalc_sha256(0,hash.bytes,hash2.bytes,sizeof(hash2));
vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash));
n = 0;
}
r = hash2.bytes[n++];
if ( (sharenrs[i]= r) == 0 || sharenrs[i] == 0xff )
continue;
for (j=0; j<i; j++)
if ( sharenrs[j] == sharenrs[i] )
break;
if ( j == i )
break;
}
//printf("%3d ",sharenrs[i]);
}
return(N);
}
int32_t calcmofn(struct supernet_info *myinfo,uint8_t *allshares,uint8_t *sharenrs,int32_t M,uint8_t *data,int32_t datasize,int32_t N)
{
uint8_t space[8192];
calc_sharenrs(sharenrs,N,data,datasize);
calc_shares(myinfo,allshares,(void *)data,datasize,datasize,M,N,sharenrs,space,sizeof(space));
return(datasize);
}
struct mofn256_info
{
bits256 secret;
uint8_t *sharenrs;
int32_t M,N,allocsize;
bits256 allshares[];
};
int32_t mofn256_size(uint8_t M,uint8_t N)
{
int32_t allocsize;
allocsize = ((int32_t)(sizeof(struct mofn256_info) + sizeof(bits256) * N + N));
if ( (allocsize & 0xf) != 0 )
allocsize += 0x10 - (allocsize & 0xf);
return(allocsize);
}
struct mofn256_info *mofn256_init(struct supernet_info *myinfo,bits256 secret,uint8_t M,uint8_t N,int32_t calcflag,uint8_t *space,int32_t spacesize)
{
int32_t allocsize; struct mofn256_info *mofn = 0;
if ( M > N || N == 0 || N == 0xff )
return(0);
allocsize = mofn256_size(M,N);
if ( allocsize > spacesize )
{
mofn = calloc(1,allocsize);
mofn->allocsize = allocsize;
}
else
{
mofn = (void *)space;
memset(mofn,0,allocsize);
}
mofn->M = M;
mofn->N = N;
mofn->sharenrs = (void *)&mofn->allshares[N];
if ( calcflag != 0 )
{
mofn->secret = secret;
calcmofn(myinfo,mofn->allshares[0].bytes,mofn->sharenrs,M,secret.bytes,sizeof(secret),N);
}
return(mofn);
}
bits256 mofn256_recover(struct supernet_info *myinfo,struct mofn256_info *mofn)
{
uint8_t *shares[255]; bits256 recover; int32_t i;
for (i=0; i<mofn->N; i++)
{
if ( bits256_nonz(mofn->allshares[i]) != 0 )
shares[i] = mofn->allshares[i].bytes;
else shares[i] = 0;
}
if ( recoverdata(myinfo,shares,mofn->sharenrs,mofn->M,recover.bytes,sizeof(recover),mofn->N) == 0 )
memset(recover.bytes,0,sizeof(recover));
return(recover);
}
int32_t test_mofn256(struct supernet_info *myinfo,int32_t M,int32_t N)
{
uint8_t space[8192]; char str[65],str2[65]; struct mofn256_info *mofn,*cmp; bits256 secret,recover; int32_t i,allocsize,retval,m = 0;
allocsize = mofn256_size(M,N);
cmp = mofn256_init(myinfo,GENESIS_PUBKEY,M,N,0,space,sizeof(space));
secret = rand256(0);
mofn = mofn256_init(myinfo,secret,M,N,1,&space[allocsize],sizeof(space) - allocsize);
memcpy(cmp->sharenrs,mofn->sharenrs,mofn->N);
for (i=0; i<N; i++)
if ( (rand() % 100) < 50 )
cmp->allshares[i] = mofn->allshares[i], m++;
recover = mofn256_recover(myinfo,cmp);
retval = -1 * (bits256_cmp(recover,mofn->secret) != 0);
if ( bits256_cmp(recover,mofn->secret) != 0 )
{
if ( m >= M )
printf("%s %s error m.%d vs M.%d N.%d\n",bits256_str(str,secret),bits256_str(str2,recover),m,mofn->M,mofn->N);
}
if ( ((long)mofn - (long)space) >= sizeof(space) || ((long)mofn - (long)space) < 0 )
free(mofn);
if ( ((long)cmp - (long)space) >= sizeof(space) || ((long)cmp - (long)space) < 0 )
free(cmp);
return(retval);
}
#define N 11
#define M 6
void test_mofn(struct supernet_info *myinfo)
{
bits256 allshares[N],secret,recover; uint8_t *shares[N],sharenrs[N]; int32_t i,j,m;
secret = rand256(0);
srand(secret.uints[0]);
calcmofn(myinfo,allshares[0].bytes,sharenrs,M,secret.bytes,sizeof(secret),N);
for (i=0; i<10000; i++)
{
memset(shares,0,sizeof(shares));
for (j=m=0; j<N; j++)
if ( (rand() % 100) < 55 )
shares[j] = allshares[j].bytes, m++;
if ( recoverdata(myinfo,shares,sharenrs,M,recover.bytes,sizeof(secret),N) != 0 )
{
if ( memcmp(secret.bytes,recover.bytes,sizeof(secret)) != 0 )
printf("FAILED m.%d M.%d N.%d\n",m,M,N);
else if ( 0 )
{
char str[65];
printf("%s PASSED m.%d M.%d N.%d\n",bits256_str(str,recover),m,M,N);
}
} //else printf("not enough shares m.%d M.%d N.%d\n",m,M,N);
}
printf("finished %d tests\n",i);
for (i=0; i<10000; i++)
test_mofn256(myinfo,M,N);
printf("finished %d tests256\n",i);
}
#undef M
#undef N
#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 )
#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx);
int32_t iguana_schnorr_peersign(void *ctx,uint8_t *allpub33,uint8_t *partialsig64,int32_t peeri,bits256 mypriv,bits256 privnonce,bits256 *nonces,int32_t n,bits256 msg256)
{
secp256k1_pubkey Rall,ALL,PUBS[256],*PUBptrs[256]; int32_t i,num,retval = -1; size_t plen; uint8_t pubkey[33];
pubkey[0] = 2;
SECP_ENSURE_CTX
{
for (i=num=0; i<n; i++)
{
plen = 33;
memcpy(pubkey+1,nonces[i].bytes,32);
if ( secp256k1_ec_pubkey_parse(ctx,&PUBS[i],pubkey,plen) == 0 )
printf("error extracting pubkey.%d of %d\n",i,n);
if ( i != peeri )
PUBptrs[num++] = &PUBS[i];
}
PUBptrs[num] = &PUBS[peeri];
if ( secp256k1_ec_pubkey_combine(ctx,&ALL,(void *)PUBptrs,num+1) != 0 )
{
plen = 33;
secp256k1_ec_pubkey_serialize(ctx,allpub33,&plen,&ALL,SECP256K1_EC_COMPRESSED);
//for (i=0; i<33; i++)
// printf("%02x",allpub33[i]);
//printf("\n");
} else printf("error combining ALL\n");
if ( secp256k1_ec_pubkey_combine(ctx,&Rall,(void *)PUBptrs,num) != 0 )
{
if ( secp256k1_schnorr_partial_sign(ctx,partialsig64,msg256.bytes,mypriv.bytes,&Rall,privnonce.bytes) == 0 )
printf("iguana_schnorr_peersign: err %d of num.%d\n",peeri,n);
else retval = 0;
} else printf("error parsing pubkey.%d\n",peeri);
ENDSECP_ENSURE_CTX
}
return(retval);
}
bits256 iguana_schnorr_noncepair(void *ctx,bits256 *pubkey,uint8_t odd_even,bits256 msg256,bits256 privkey,int32_t maxj)
{
bits256 privnonce; int32_t j; uint8_t pubkey33[33];
for (j=0; j<maxj; j++)
{
privnonce = bitcoin_schnorr_noncepair(ctx,pubkey33,msg256,privkey);
if ( pubkey33[0] == (odd_even + 2) )
{
memcpy(pubkey->bytes,pubkey33+1,32);
break;
}
}
if ( j == maxj )
{
printf("couldnt generate even noncepair\n");
exit(-1);
}
return(privnonce);
}
struct schnorr_info
{
bits256 msg256,privkey,pubkey,privnonce,pubnonce,serhash2;
int32_t M,N; uint32_t msgid;
uint8_t sig64[64],combinedsig64[64],allpub[33],combined_allpub[33];
uint16_t ind,nonz;
bits256 *pubkeys,*pubnonces;
uint8_t serialized[65 + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(bits256)*4];
uint8_t sigs[];
};
int32_t schnorr_rwinitdata(int32_t rwflag,uint8_t *serialized,uint16_t *indp,uint32_t *msgidp,bits256 hashes[4])
{
int32_t i,j,len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(*indp),indp);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(*msgidp),msgidp);
for (j=0; j<4; j++)
for (i=0; i<32; i++)
iguana_rwnum(rwflag,&serialized[len++],1,&hashes[j].bytes[i]);
return(len);
}
struct schnorr_info *schnorr_init(struct supernet_info *myinfo,uint32_t msgid,uint16_t ind,int32_t M,int32_t N,void *space,int32_t spacesize,bits256 msg256)
{
uint8_t *serialized; bits256 hashes[4]; int32_t len,odd_even = 0; struct schnorr_info *si = space;
si->pubnonces = (void *)&si->sigs[N * 64];
si->pubkeys = &si->pubnonces[N];
si->M = M;
si->N = N;
si->ind = ind;
si->msgid = msgid;
si->msg256 = msg256;
si->pubkey = bitcoin_pub256(myinfo->ctx,&si->privkey,odd_even);
si->privnonce = iguana_schnorr_noncepair(myinfo->ctx,&si->pubnonce,odd_even,msg256,si->privkey,100);
len = 0;
serialized = &si->serialized[65];
hashes[0] = myinfo->myaddr.persistent;
hashes[1] = si->pubkey;
hashes[2] = si->pubnonce;
hashes[3] = msg256;
len = schnorr_rwinitdata(1,serialized,&ind,&msgid,hashes);
blockhash_sha256(si->serhash2.bytes,serialized,len);
if ( bitcoin_sign(myinfo->ctx,"SCHNORR",si->serialized,si->serhash2,myinfo->persistent_priv,1) != 65 )
printf("error signing schnorr initdata\n");
return(si);
}
int32_t schnorr_update(struct supernet_info *myinfo,struct schnorr_info *si,uint8_t *serialized,int32_t recvlen)
{
int32_t len; uint16_t ind; uint32_t msgid; bits256 hashes[4];
// verify compact sig
len = schnorr_rwinitdata(0,&serialized[65],&ind,&msgid,hashes);
// verify persistent pubkey matches ind
if ( bits256_cmp(hashes[3],si->msg256) == 0 && msgid == si->msgid && bits256_nonz(si->pubkeys[ind]) == 0 && bits256_nonz(si->pubnonces[ind]) == 0 )
{
si->pubkeys[ind] = hashes[1];
si->pubnonces[ind] = hashes[2];
if ( ++si->nonz >= si->M )
{
iguana_schnorr_peersign(myinfo->ctx,si->allpub,si->sig64,si->ind,si->privkey,si->privnonce,si->pubnonces,si->M,si->msg256);
// broadcast si->sig64 + ind + msgid
}
}
return(si->M);
}
/*{
if ( bitcoin_schnorr_combine(myinfo->ctx,si->combinedsig64,si->combined_allpub,si->sigs,si->M,si->msg256) < 0 )
printf("error combining k.%d sig64 iter.%d\n",k,iter);
if ( bitcoin_schnorr_verify(myinfo->ctx,si->combinedsig64,si->msg256,si->combined_allpub,33) < 0 )
printf("allpub2 error verifying combined sig k.%d\n",k);
}*/
void iguana_schnorr(struct supernet_info *myinfo)
{
uint8_t allpubs[256][33],allpub[33],allpub2[33],sig64s[256][64],sig64[64],*sigs[256]; bits256 msg256,privnonces[256],signers,privkeys[256],pubkeys[256],pubkeysB[256],nonces[256]; int32_t i,iter,n,k,maxj = 100;
OS_randombytes((void *)&n,sizeof(n));
srand(n);
n = 1 + (rand() % 255);
// generate onetime keypairs
for (i=0; i<n; i++)
pubkeys[i] = bitcoin_pub256(myinfo->ctx,&privkeys[i],0);
msg256 = rand256(0);
for (i=0; i<n; i++)
privnonces[i] = iguana_schnorr_noncepair(myinfo->ctx,&nonces[i],0,msg256,privkeys[i],maxj);
for (i=0; i<n; i++)
iguana_schnorr_peersign(myinfo->ctx,allpubs[i],sig64s[i],i,privkeys[i],privnonces[i],nonces,n,msg256);
for (iter=0; iter<1; iter++)
{
memset(signers.bytes,0,sizeof(signers));
for (i=k=0; i<n; i++)
{
if ( (rand() % 100) < 50 )
{
printf("%2d ",i);
sigs[k] = sig64s[i];
pubkeysB[k] = pubkeys[i];
k++;
SETBIT(signers.bytes,i);
}
}
if ( bitcoin_schnorr_combine(myinfo->ctx,sig64,allpub2,sigs,k,msg256) < 0 )
printf("error combining k.%d sig64 iter.%d\n",k,iter);
else if ( bitcoin_schnorr_verify(myinfo->ctx,sig64,msg256,allpub2,33) < 0 )
printf("allpub2 error verifying combined sig k.%d\n",k);
else if ( 0 ) // doesnt replicate with subsets
{
if ( bitcoin_pubkey_combine(myinfo->ctx,allpub,0,pubkeys,n,0,0) == 0 )
{
if ( memcmp(allpub,allpubs[0],33) != 0 )
{
printf("\n");
for (k=0; k<33; k++)
printf("%02x",allpubs[0][k]);
printf(" combined\n");
for (k=0; k<33; k++)
printf("%02x",allpub[k]);
printf(" allpub, ");
printf("allpub mismatch iter.%d i.%d n.%d\n",iter,i,n);
} else printf("validated iter.%d k.%d %llx\n",iter,k,(long long)signers.txid);
} //else printf("error combining\n");
} else printf("passed n.%d\n",n);
}
}

1
iguana/iguana_passport.c

@ -28,6 +28,7 @@ While it is not expected that there will be more than 256 such blockchains, by u
'b' -> bitcoin/BitcoinDark (BTC)
'c' -> colored coins
'e' -> ethereum (ETH)
'h' -> HEAT
'n' -> NXT
'o' -> open assets
's' -> BURST

2
iguana/iguana_realtime.c

@ -220,7 +220,7 @@ int32_t iguana_realtime_update(struct supernet_info *myinfo,struct iguana_info *
}
if ( coin->spendvectorsaved <= 1 )
{
printf("spendvectorsaved not yet\n");
//printf("spendvectorsaved not yet\n");
usleep(100000);
return(0);
}

929
iguana/main.c

@ -24,10 +24,6 @@
#include "../pnacl_main.h"
#include "iguana777.h"
#include "secp256k1/include/secp256k1.h"
#include "secp256k1/include/secp256k1_schnorr.h"
#include "secp256k1/include/secp256k1_rangeproof.h"
struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char *retjsonstr; char remoteaddr[64]; uint16_t port; char jsonstr[]; };
uint16_t SuperNET_API2num(char *agent,char *method)
@ -81,9 +77,6 @@ struct supernet_info *SuperNET_MYINFO(char *passphrase)
{
if ( MYINFO.ctx == 0 )
{
MYINFO.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(MYINFO.ctx);
secp256k1_rangeproof_context_initialize(MYINFO.ctx);
OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey));
MYINFO.myaddr.pubkey = curve25519(MYINFO.privkey,curve25519_basepoint9());
printf("SuperNET_MYINFO: generate session keypair\n");
@ -476,653 +469,6 @@ void mainloop(struct supernet_info *myinfo)
}
}
int32_t calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,uint8_t *data,int32_t datasize,int32_t N)
{
int32_t j;
calc_shares(allshares,(void *)data,datasize,datasize,M,N,sharenrs);
for (j=0; j<N; j++)
myshares[j] = &allshares[j * datasize];
return(datasize);
}
uint8_t *recoverdata(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t datasize,int32_t N)
{
void *G; int32_t i; uint8_t *recover,recovernrs[255];
if ( (recover= calloc(1,datasize)) == 0 )
{
printf("cards777_recover: unexpected out of memory error\n");
return(0);
}
memset(recovernrs,0,sizeof(recovernrs));
for (i=0; i<N; i++)
if ( shares[i] != 0 )
recovernrs[i] = sharenrs[i];
G = gfshare_ctx_init_dec(recovernrs,N,datasize);
for (i=0; i<N; i++)
if ( shares[i] != 0 )
gfshare_ctx_dec_giveshare(G,i,shares[i]);
gfshare_ctx_dec_newshares(G,recovernrs);
gfshare_ctx_dec_extract(G,recover);
gfshare_ctx_free(G);
return(recover);
}
static uint8_t logs[256] = {
0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf };
static uint8_t exps[510] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01,
0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d,
0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c,
0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f,
0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x9d,
0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a,
0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0x46,
0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d,
0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, 0x5f,
0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65,
0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0xfd,
0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe,
0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0xd9,
0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d,
0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, 0x81,
0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b,
0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85,
0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f,
0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, 0xa8,
0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49,
0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, 0xe6,
0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc,
0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3,
0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95,
0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, 0x82,
0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c,
0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, 0x51,
0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3,
0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, 0x12,
0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7,
0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, 0x2c,
0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b,
0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e };
/*
* This file is Copyright Daniel Silverstone <dsilvers@digital-scurf.org> 2006,2015
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
//#include "config.h"
//#include "libgfshare.h"
//#include "libgfshare_tables.h"
#ifndef LIBGFSHARE_H
#define LIBGFSHARE_H
typedef struct _gfshare_ctx gfshare_ctx;
typedef void (*gfshare_rand_func_t)(uint8_t*, unsigned int);
/* This will, use random(). It's not very good so you should not use it unless
* you must. If you can't be bothered to write your own, be sure to srandom()
* before you use any of the gfshare_ctx_enc_* functions
*/
extern const gfshare_rand_func_t gfshare_bad_idea_but_fill_rand_using_random;
/* This must be filled out before running any of the gfshare_ctx_enc_* calls
* or bad things will happen since it is initialised to NULL be default.
* You should fill this with a routine which uses urandom or similar ideally.
* If you cannot do that on your platform, you can use the function provided
* which does random() calls, but I recommend against it unless you must.
*/
extern gfshare_rand_func_t gfshare_fill_rand;
/* ------------------------------------------------------[ Preparation ]---- */
/* Initialise a gfshare context for producing shares */
gfshare_ctx* gfshare_ctx_init_enc(uint8_t* /* sharenrs */,unsigned int /* sharecount */, uint8_t /* threshold */,unsigned int /* size */);
/* Initialise a gfshare context for recombining shares */
gfshare_ctx* gfshare_ctx_init_dec(uint8_t* /* sharenrs */,unsigned int /* sharecount */,unsigned int /* size */);
/* Free a share context's memory. */
void gfshare_ctx_free(gfshare_ctx* /* ctx */);
/* --------------------------------------------------------[ Splitting ]---- */
/* Provide a secret to the encoder. (this re-scrambles the coefficients) */
void gfshare_ctx_enc_setsecret(gfshare_ctx* /* ctx */,uint8_t* /* secret */);
/* Extract a share from the context.
* 'share' must be preallocated and at least 'size' bytes long.
* 'sharenr' is the index into the 'sharenrs' array of the share you want.
*/
void gfshare_ctx_enc_getshare(gfshare_ctx* /* ctx */,uint8_t /* sharenr */,uint8_t* /* share */);
/* ----------------------------------------------------[ Recombination ]---- */
/* Inform a recombination context of a change in share indexes */
void gfshare_ctx_dec_newshares(gfshare_ctx* /* ctx */, uint8_t* /* sharenrs */);
/* Provide a share context with one of the shares.
* The 'sharenr' is the index into the 'sharenrs' array
*/
void gfshare_ctx_dec_giveshare(gfshare_ctx* /* ctx */,uint8_t /* sharenr */,uint8_t* /* share */);
/* Extract the secret by interpolation of the shares.
* secretbuf must be allocated and at least 'size' bytes long
*/
void gfshare_ctx_dec_extract(gfshare_ctx* /* ctx */,uint8_t* /* secretbuf */);
#endif /* LIBGFSHARE_H */
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define XMALLOC malloc
#define XFREE free
struct _gfshare_ctx {
unsigned int sharecount;
unsigned int threshold;
unsigned int size;
uint8_t* sharenrs;
uint8_t* buffer;
unsigned int buffersize;
};
static void _gfshare_fill_rand_using_random( uint8_t* buffer,unsigned int count )
{
OS_randombytes(buffer,count);
/*unsigned int i;
for( i = 0; i < count; ++i )
buffer[i] = (random() & 0xff00) >> 8; apparently the bottom 8 aren't
* very random but the middles ones
* are
*/
}
const gfshare_rand_func_t gfshare_bad_idea_but_fill_rand_using_random = (void *)_gfshare_fill_rand_using_random;
gfshare_rand_func_t gfshare_fill_rand = NULL;
/* ------------------------------------------------------[ Preparation ]---- */
static gfshare_ctx * _gfshare_ctx_init_core( uint8_t *sharenrs,unsigned int sharecount,uint8_t threshold,unsigned int size )
{
gfshare_ctx *ctx;
ctx = XMALLOC( sizeof(struct _gfshare_ctx) );
if( ctx == NULL )
return NULL; /* errno should still be set from XMALLOC() */
ctx->sharecount = sharecount;
ctx->threshold = threshold;
ctx->size = size;
ctx->sharenrs = XMALLOC( sharecount );
if( ctx->sharenrs == NULL ) {
int saved_errno = errno;
XFREE( ctx );
errno = saved_errno;
return NULL;
}
memcpy( ctx->sharenrs, sharenrs, sharecount );
ctx->buffersize = threshold * size;
ctx->buffer = XMALLOC( ctx->buffersize );
if( ctx->buffer == NULL ) {
int saved_errno = errno;
XFREE( ctx->sharenrs );
XFREE( ctx );
errno = saved_errno;
return NULL;
}
return ctx;
}
/* Initialise a gfshare context for producing shares */
gfshare_ctx * gfshare_ctx_init_enc( uint8_t* sharenrs,unsigned int sharecount,uint8_t threshold,unsigned int size )
{
unsigned int i;
for (i = 0; i < sharecount; i++) {
if (sharenrs[i] == 0) {
/* can't have x[i] = 0 - that would just be a copy of the secret, in
* theory (in fact, due to the way we use exp/log for multiplication and
* treat log(0) as 0, it ends up as a copy of x[i] = 1) */
errno = EINVAL;
return NULL;
}
}
return _gfshare_ctx_init_core( sharenrs, sharecount, threshold, size );
}
/* Initialise a gfshare context for recombining shares */
gfshare_ctx* gfshare_ctx_init_dec( uint8_t* sharenrs,unsigned int sharecount,unsigned int size )
{
gfshare_ctx *ctx = _gfshare_ctx_init_core( sharenrs, sharecount, sharecount, size );
if( ctx != NULL )
ctx->threshold = 0;
return ctx;
}
/* Free a share context's memory. */
void gfshare_ctx_free( gfshare_ctx* ctx )
{
gfshare_fill_rand( ctx->buffer, ctx->buffersize );
gfshare_fill_rand( ctx->sharenrs, ctx->sharecount );
XFREE( ctx->sharenrs );
XFREE( ctx->buffer );
gfshare_fill_rand( (uint8_t*)ctx, sizeof(struct _gfshare_ctx) );
XFREE( ctx );
}
/* --------------------------------------------------------[ Splitting ]---- */
/* Provide a secret to the encoder. (this re-scrambles the coefficients) */
void gfshare_ctx_enc_setsecret( gfshare_ctx* ctx,uint8_t* secret)
{
memcpy( ctx->buffer + ((ctx->threshold-1) * ctx->size),
secret,
ctx->size );
gfshare_fill_rand( ctx->buffer, (ctx->threshold-1) * ctx->size );
}
/* Extract a share from the context.
* 'share' must be preallocated and at least 'size' bytes long.
* 'sharenr' is the index into the 'sharenrs' array of the share you want.
*/
void gfshare_ctx_enc_getshare( gfshare_ctx* ctx,uint8_t sharenr,uint8_t* share)
{
unsigned int pos, coefficient;
unsigned int ilog = logs[ctx->sharenrs[sharenr]];
uint8_t *coefficient_ptr = ctx->buffer;
uint8_t *share_ptr;
for( pos = 0; pos < ctx->size; ++pos )
share[pos] = *(coefficient_ptr++);
for( coefficient = 1; coefficient < ctx->threshold; ++coefficient ) {
share_ptr = share;
for( pos = 0; pos < ctx->size; ++pos ) {
uint8_t share_byte = *share_ptr;
if( share_byte )
share_byte = exps[ilog + logs[share_byte]];
*share_ptr++ = share_byte ^ *coefficient_ptr++;
}
}
}
/* ----------------------------------------------------[ Recombination ]---- */
/* Inform a recombination context of a change in share indexes */
void gfshare_ctx_dec_newshares( gfshare_ctx* ctx,uint8_t* sharenrs)
{
memcpy( ctx->sharenrs, sharenrs, ctx->sharecount );
}
/* Provide a share context with one of the shares.
* The 'sharenr' is the index into the 'sharenrs' array
*/
void gfshare_ctx_dec_giveshare( gfshare_ctx* ctx,uint8_t sharenr,uint8_t* share )
{
memcpy( ctx->buffer + (sharenr * ctx->size), share, ctx->size );
}
/* Extract the secret by interpolation of the shares.
* secretbuf must be allocated and at least 'size' bytes long
*/
void gfshare_ctx_dec_extract( gfshare_ctx* ctx,uint8_t* secretbuf )
{
unsigned int i, j;
uint8_t *secret_ptr, *share_ptr, sharei,sharej;
for( i = 0; i < ctx->size; ++i )
secretbuf[i] = 0;
for( i = 0; i < ctx->sharecount; ++i )
{
// Compute L(i) as per Lagrange Interpolation
unsigned Li_top = 0, Li_bottom = 0;
if ( (sharei= ctx->sharenrs[i]) != 0 )
{
for ( j = 0; j < ctx->sharecount; ++j )
{
if ( i != j && sharei != (sharej= ctx->sharenrs[j]) )
{
if ( sharej == 0 )
continue; // skip empty share */
Li_top += logs[sharej];
if ( Li_top >= 0xff )
Li_top -= 0xff;
Li_bottom += logs[sharei ^ sharej];
if ( Li_bottom >= 0xff )
Li_bottom -= 0xff;
}
}
if ( Li_bottom > Li_top )
Li_top += 0xff;
Li_top -= Li_bottom; // Li_top is now log(L(i))
secret_ptr = secretbuf, share_ptr = ctx->buffer + (ctx->size * i);
for (j=0; j<ctx->size; j++)
{
if ( *share_ptr != 0 )
*secret_ptr ^= exps[Li_top + logs[*share_ptr]];
share_ptr++, secret_ptr++;
}
}
}
}
void calc_share(uint8_t *buffer,int32_t size,int32_t M,uint32_t ilog,uint8_t *share)
{
uint32_t pos,coefficient;//,ilog = ctx_logs[ctx->sharenrs[sharenr]];
//uint8_t *coefficient_ptr = buffer;
uint8_t *share_ptr,share_byte;
for (pos=0; pos<size; pos++)
share[pos] = *(buffer++);
for (coefficient=1; coefficient<M; coefficient++)
{
share_ptr = share;
for (pos=0; pos<size; pos++)
{
share_byte = *share_ptr;
if ( share_byte != 0 )
share_byte = exps[ilog + logs[share_byte]];
*share_ptr++ = (share_byte ^ *buffer++);
}
}
}
void calc_shares(uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs)
{
int32_t i;
uint8_t *buffer = calloc(M,width);
memset(shares,0,N*width);
memcpy(buffer + ((M - 1) * size),secret,size);
//gfshare_fill_rand(buffer,(M - 1) * size);
OS_randombytes(buffer,(M - 1) * size);
for (i=0; i<N; i++)
{
//uint32_t _crc32(uint32_t crc, const void *buf, size_t size);
calc_share(buffer,size,M,logs[sharenrs[i]],&shares[i * width]);
printf("(%02x %08x) ",sharenrs[i],calc_crc32(0,&shares[i*width],size));
}
free(buffer);
}
//#include <stdio.h>
int32_t test(int32_t M,int32_t N,int32_t datasize)
{
int ok = 1, i;
uint8_t * secret = malloc(datasize);
uint8_t *shares[255];
uint8_t *recomb = malloc(datasize);
uint8_t sharenrs[255],newsharenrs[255];// = (uint8_t *)strdup("0124z89abehtr");
gfshare_ctx *G;
gfshare_fill_rand = gfshare_bad_idea_but_fill_rand_using_random;
for (i=0; i<N; i++)
{
sharenrs[i] = i+1;
shares[i] = malloc(datasize);
}
/* Stage 1, make a secret */
for( i = 0; i < datasize; ++i )
secret[i] = (rand() & 0xff00) >> 8;
/* Stage 2, split it N ways with a threshold of M */
G = gfshare_ctx_init_enc( sharenrs, N, M, datasize );
gfshare_ctx_enc_setsecret( G, secret );
for (i=0; i<N; i++)
gfshare_ctx_enc_getshare( G, i, shares[i] );
gfshare_ctx_free( G );
/* Prep the decode shape */
G = gfshare_ctx_init_dec( sharenrs, N, datasize );
memset(newsharenrs,0,N);
int32_t j,r;
for (i=0; i<M; i++)
{
r = rand() % N;
while ( (j= sharenrs[r]) == 0 || newsharenrs[r] != 0 )
r = rand() % N;
newsharenrs[r] = j;
sharenrs[r] = 0;
}
for (i=0; i<N; i++)
{
if ( newsharenrs[i] != 0 )
gfshare_ctx_dec_giveshare( G, i, shares[i] );
//newsharenrs[i] = sharenrs[i];
}
/* Stage 3, attempt a recombination with shares 1 and 2 */
//sharenrs[2] = 0;
gfshare_ctx_dec_newshares( G, newsharenrs );
gfshare_ctx_dec_extract( G, recomb );
for( i = 0; i < datasize; ++i )
if( secret[i] != recomb[i] )
ok = 0;
printf("M.%-3d N.%-3d ok.%d datalen.%d\n",M,N,ok,datasize);
free(recomb), free(secret);
for (i=0; i<N; i++)
free(shares[i]);
return ok!=1;
}
int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n)
{
uint8_t *randvals,valid[255];
int32_t i,j,r,remains,orign;
if ( m > n || n >= 0xff ) // reserve 255 for illegal sharei
{
printf("illegal M.%d of N.%d\n",m,n);
return(-1);
}
randvals = calloc(1,65536);
OS_randombytes(randvals,65536);
if ( orig == 0 && n == m )
{
memset(sharenrs,0,n);
for (i=0; i<255; i++)
valid[i] = (i + 1);
remains = orign = 255;
for (i=0; i<n; i++)
{
r = (randvals[i] % remains);
sharenrs[i] = valid[r];
printf("%d ",sharenrs[i]);
valid[r] = valid[--remains];
}
printf("FULL SET\n");
}
else
{
memcpy(valid,orig,n);
memset(sharenrs,0,n);
for (i=0; i<n; i++)
printf("%d ",valid[i]);
printf("valid\n");
for (i=0; i<m; i++)
{
r = rand() % n;
while ( (j= valid[r]) == 0 )
{
//printf("i.%d j.%d m.%d n.%d r.%d\n",i,j,m,n,r);
r = rand() % n;
}
sharenrs[i] = j;
valid[r] = 0;
}
for (i=0; i<n; i++)
printf("%d ",valid[i]);
printf("valid\n");
for (i=0; i<m; i++)
printf("%d ",sharenrs[i]);
printf("sharenrs vals m.%d of n.%d\n",m,n);
//getchar();
}
free(randvals);
for (i=0; i<m; i++)
{
for (j=0; j<m; j++)
{
if ( i == j )
continue;
if ( sharenrs[i] != 0 && sharenrs[i] == sharenrs[j] )
{
printf("FATAL: duplicate entry sharenrs[%d] %d vs %d sharenrs[%d]\n",i,sharenrs[i],sharenrs[j],j);
return(-1);
}
}
}
return(0);
}
/* Construct and write out the tables for the gfshare code */
int maingen(int argc, char** argv)
{
uint8_t logs[256];
uint8_t exps[255];
unsigned int x;
unsigned int i;
x = 1;
for( i = 0; i < 255; ++i ) {
exps[i] = x;
logs[x] = i;
x <<= 1;
if( x & 0x100 )
x ^= 0x11d; /* Unset the 8th bit and mix in 0x1d */
}
logs[0] = 0; /* can't log(0) so just set it neatly to 0 */
/* The above generation algorithm clearly demonstrates that
* logs[exps[i]] == i for 0 <= i <= 254
* exps[logs[i]] == i for 1 <= i <= 255
*/
/* Spew out the tables */
fprintf(stdout, "\
/*\n\
* This file is autogenerated by gfshare_maketable.\n\
*/\n\
\n\
static uint8_t logs[256] = {\n ");
for( i = 0; i < 256; ++i ) {
fprintf(stdout, "0x%02x", logs[i]);
if( i == 255 )
fprintf(stdout, " };\n");
else if( (i % 8) == 7 )
fprintf(stdout, ",\n ");
else
fprintf(stdout, ", ");
}
/* The exp table we output from 0 to 509 because that way when we
* do the lagrange interpolation we don't have to be quite so strict
* with staying inside the field which makes it quicker
*/
fprintf(stdout, "\
\n\
static uint8_t exps[510] = {\n ");
for( i = 0; i < 510; ++i ) {
fprintf(stdout, "0x%02x", exps[i % 255]); /* exps[255]==exps[0] */
if( i == 509 )
fprintf(stdout, " };\n");
else if( (i % 8) == 7)
fprintf(stdout, ",\n ");
else
fprintf(stdout, ", ");
}
return 0;
}
void iguana_appletests(struct supernet_info *myinfo)
{
char *str;
@ -1314,197 +660,6 @@ int32_t iguana_isbigendian()
else return(-1);
}
#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 )
#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx);
int32_t iguana_schnorr_peersign(void *ctx,uint8_t *allpub33,uint8_t *partialsig64,int32_t peeri,bits256 mypriv,bits256 privnonce,bits256 *nonces,int32_t n,bits256 msg256)
{
secp256k1_pubkey Rall,ALL,PUBS[256],*PUBptrs[256]; int32_t i,num,retval = -1; size_t plen; uint8_t pubkey[33];
pubkey[0] = 2;
SECP_ENSURE_CTX
{
for (i=num=0; i<n; i++)
{
plen = 33;
memcpy(pubkey+1,nonces[i].bytes,32);
if ( secp256k1_ec_pubkey_parse(ctx,&PUBS[i],pubkey,plen) == 0 )
printf("error extracting pubkey.%d of %d\n",i,n);
if ( i != peeri )
PUBptrs[num++] = &PUBS[i];
}
PUBptrs[num] = &PUBS[peeri];
if ( secp256k1_ec_pubkey_combine(ctx,&ALL,(void *)PUBptrs,num+1) != 0 )
{
plen = 33;
secp256k1_ec_pubkey_serialize(ctx,allpub33,&plen,&ALL,SECP256K1_EC_COMPRESSED);
//for (i=0; i<33; i++)
// printf("%02x",allpub33[i]);
//printf("\n");
} else printf("error combining ALL\n");
if ( secp256k1_ec_pubkey_combine(ctx,&Rall,(void *)PUBptrs,num) != 0 )
{
if ( secp256k1_schnorr_partial_sign(ctx,partialsig64,msg256.bytes,mypriv.bytes,&Rall,privnonce.bytes) == 0 )
printf("iguana_schnorr_peersign: err %d of num.%d\n",peeri,n);
else retval = 0;
} else printf("error parsing pubkey.%d\n",peeri);
ENDSECP_ENSURE_CTX
}
return(retval);
}
bits256 iguana_schnorr_noncepair(void *ctx,bits256 *pubkey,uint8_t odd_even,bits256 msg256,bits256 privkey,int32_t maxj)
{
bits256 privnonce; int32_t j; uint8_t pubkey33[33];
for (j=0; j<maxj; j++)
{
privnonce = bitcoin_schnorr_noncepair(ctx,pubkey33,msg256,privkey);
if ( pubkey33[0] == (odd_even + 2) )
{
memcpy(pubkey->bytes,pubkey33+1,32);
break;
}
}
if ( j == maxj )
{
printf("couldnt generate even noncepair\n");
exit(-1);
}
return(privnonce);
}
void iguana_schnorr(struct supernet_info *myinfo)
{
uint8_t allpubs[256][33],allpub[33],sig64s[256][64],sig64[64],*sigs[256]; bits256 msg256,privnonces[256],signers,privkeys[256],pubkeys[256],pubkeysB[256],nonces[256]; int32_t i,iter,n,k,maxj = 100;
OS_randombytes((void *)&n,sizeof(n));
srand(n);
n = 64;//(rand() % 200);
// generate onetime keypairs
for (i=0; i<n; i++)
pubkeys[i] = bitcoin_pub256(myinfo->ctx,&privkeys[i],0);
msg256 = rand256(0);
for (i=0; i<n; i++)
privnonces[i] = iguana_schnorr_noncepair(myinfo->ctx,&nonces[i],0,msg256,privkeys[i],maxj);
for (i=0; i<n; i++)
iguana_schnorr_peersign(myinfo->ctx,allpubs[i],sig64s[i],i,privkeys[i],privnonces[i],nonces,n,msg256);
for (iter=0; iter<1; iter++)
{
memset(signers.bytes,0,sizeof(signers));
for (i=k=0; i<n; i++)
{
if ( (rand() % 100) < 50 )
{
//printf("%d ",i);
sigs[k] = sig64s[i];
pubkeysB[k] = pubkeys[i];
k++;
SETBIT(signers.bytes,i);
}
}
if ( bitcoin_schnorr_combine(myinfo->ctx,sig64,allpub,sigs,k,msg256) < 0 )
printf("error combining k.%d sig64 iter.%d\n",k,iter);
else if ( bitcoin_schnorr_verify(myinfo->ctx,sig64,msg256,allpub,33) < 0 )
printf("error verifying combined sig k.%d\n",k);
else if ( 0 )
{
if ( bitcoin_pubkey_combine(myinfo->ctx,allpub,0,pubkeys,n,0,0) == 0 )
{
if ( memcmp(allpub,allpubs[0],33) != 0 )
{
printf("\n");
for (k=0; k<33; k++)
printf("%02x",allpubs[0][k]);
printf(" combined\n");
for (k=0; k<33; k++)
printf("%02x",allpub[k]);
printf(" allpub, ");
printf("allpub mismatch iter.%d i.%d n.%d\n",iter,i,n);
} else printf("validated iter.%d k.%d %llx\n",iter,k,(long long)signers.txid);
} //else printf("error combining\n");
} else printf("passed\n");
}
}
void iguana_main(void *arg)
{
int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; cJSON *argjson = 0;
if ( (IGUANA_BIGENDIAN= iguana_isbigendian()) > 0 )
printf("BIGENDIAN\n");
else if ( IGUANA_BIGENDIAN == 0 )
printf("LITTLE ENDIAN arg.%p\n",arg);
else printf("ENDIAN ERROR\n");
mycalloc(0,0,0);
decode_hex(CRYPTO777_RMD160,20,CRYPTO777_RMD160STR);
decode_hex(CRYPTO777_PUBSECP33,33,CRYPTO777_PUBSECPSTR);
if ( 0 )
iguana_signalsinit();
if ( 0 )
{
int32_t i,max=10000000; FILE *fp; bits256 check,val,hash = rand256(0);
if ( (fp= fopen("/tmp/seeds2","rb")) != 0 )
{
if ( fread(&check,1,sizeof(check),fp) != sizeof(check) )
printf("check read error\n");
for (i=1; i<max; i++)
{
if ( (i % 1000000) == 0 )
fprintf(stderr,".");
if ( fread(&val,1,sizeof(val),fp) != sizeof(val) )
printf("val read error\n");
hash = bits256_sha256(val);
hash = bits256_sha256(hash);
if ( bits256_cmp(hash,check) != 0 )
printf("hash error at i.%d\n",i);
check = val;
}
printf("validated %d seeds\n",max);
getchar();
}
else if ( (fp= fopen("/tmp/seeds2","wb")) != 0 )
{
for (i=0; i<max; i++)
{
if ( (i % 1000000) == 0 )
fprintf(stderr,".");
hash = bits256_sha256(hash);
hash = bits256_sha256(hash);
fseek(fp,(max-i-1) * sizeof(bits256),SEEK_SET);
if ( fwrite(hash.bytes,1,sizeof(hash),fp) != sizeof(hash) )
printf("error writing hash[%d] i.%d\n",(max-i-1),i);
}
fclose(fp);
}
}
iguana_ensuredirs();
iguana_Qinit();
myinfo = SuperNET_MYINFO(0);
if ( 0 )
{
int32_t i; for (i=0; i<10; i++)
iguana_schnorr(myinfo);
getchar();
}
myinfo->rpcport = IGUANA_RPCPORT;
strcpy(myinfo->rpcsymbol,"BTCD");
iguana_urlinit(myinfo,ismainnet,usessl);
//category_init(myinfo);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("bitcoin",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("poloniex",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("bittrex",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("btc38",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("huobi",0);
argjson = arg != 0 ? cJSON_Parse(arg) : cJSON_Parse("{}");
//iguana_coinadd("BTC",argjson); dont do this here, coin args not set
///iguana_coinadd("LTC",argjson);
free_json(argjson);
iguana_helpinit(myinfo);
basilisks_init(myinfo);
iguana_commandline(myinfo,arg);
#ifdef __APPLE__
iguana_appletests(myinfo);
#endif
iguana_launchdaemons(myinfo);
}
void *SuperNET_deciphercalc(void **ptrp,int32_t *msglenp,bits256 privkey,bits256 srcpubkey,uint8_t *cipher,int32_t cipherlen,uint8_t *buf,int32_t bufsize)
{
uint8_t *origptr,*nonce,*message; void *retptr;
@ -2284,3 +1439,87 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase)
}
#include "../includes/iguana_apiundefs.h"
void iguana_main(void *arg)
{
int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; cJSON *argjson = 0;
if ( (IGUANA_BIGENDIAN= iguana_isbigendian()) > 0 )
printf("BIGENDIAN\n");
else if ( IGUANA_BIGENDIAN == 0 )
printf("LITTLE ENDIAN arg.%p\n",arg);
else printf("ENDIAN ERROR\n");
mycalloc(0,0,0);
decode_hex(CRYPTO777_RMD160,20,CRYPTO777_RMD160STR);
decode_hex(CRYPTO777_PUBSECP33,33,CRYPTO777_PUBSECPSTR);
if ( 0 )
iguana_signalsinit();
if ( 0 )
{
int32_t i,max=10000000; FILE *fp; bits256 check,val,hash = rand256(0);
if ( (fp= fopen("/tmp/seeds2","rb")) != 0 )
{
if ( fread(&check,1,sizeof(check),fp) != sizeof(check) )
printf("check read error\n");
for (i=1; i<max; i++)
{
if ( (i % 1000000) == 0 )
fprintf(stderr,".");
if ( fread(&val,1,sizeof(val),fp) != sizeof(val) )
printf("val read error\n");
hash = bits256_sha256(val);
hash = bits256_sha256(hash);
if ( bits256_cmp(hash,check) != 0 )
printf("hash error at i.%d\n",i);
check = val;
}
printf("validated %d seeds\n",max);
getchar();
}
else if ( (fp= fopen("/tmp/seeds2","wb")) != 0 )
{
for (i=0; i<max; i++)
{
if ( (i % 1000000) == 0 )
fprintf(stderr,".");
hash = bits256_sha256(hash);
hash = bits256_sha256(hash);
fseek(fp,(max-i-1) * sizeof(bits256),SEEK_SET);
if ( fwrite(hash.bytes,1,sizeof(hash),fp) != sizeof(hash) )
printf("error writing hash[%d] i.%d\n",(max-i-1),i);
}
fclose(fp);
}
}
iguana_ensuredirs();
iguana_Qinit();
myinfo = SuperNET_MYINFO(0);
libgfshare_init(myinfo,myinfo->logs,myinfo->exps);
if ( 0 )
{
int32_t i; for (i=0; i<10; i++)
iguana_schnorr(myinfo);
getchar();
}
myinfo->rpcport = IGUANA_RPCPORT;
strcpy(myinfo->rpcsymbol,"BTCD");
iguana_urlinit(myinfo,ismainnet,usessl);
//category_init(myinfo);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("bitcoin",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("poloniex",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("bittrex",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("btc38",0);
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create("huobi",0);
argjson = arg != 0 ? cJSON_Parse(arg) : cJSON_Parse("{}");
//iguana_coinadd("BTC",argjson); dont do this here, coin args not set
///iguana_coinadd("LTC",argjson);
free_json(argjson);
iguana_helpinit(myinfo);
basilisks_init(myinfo);
iguana_commandline(myinfo,arg);
#ifdef __APPLE__
iguana_appletests(myinfo);
#endif
iguana_launchdaemons(myinfo);
}

3
iguana/pangea777.h

@ -118,7 +118,6 @@ bits256 xoverz_donna(bits256 a);
bits256 crecip_donna(bits256 a);
bits256 fmul_donna(bits256 a,bits256 b);
void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs);
int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n);
struct pangea_msghdr
@ -146,7 +145,7 @@ bits256 cards777_pubkeys(bits256 *pubkeys,int32_t numcards,bits256 cmppubkey);
int32_t cards777_checkcard(bits256 *cardprivp,int32_t cardi,int32_t slot,int32_t destplayer,bits256 playerpriv,bits256 *cardpubs,int32_t numcards,bits256 card);
int32_t cards777_validate(bits256 cardpriv,bits256 final,bits256 *cardpubs,int32_t numcards,bits256 *audit,int32_t numplayers,bits256 playerpub);
bits256 cards777_decode(bits256 *seedp,bits256 *xoverz,int32_t destplayer,bits256 cipher,bits256 *outcards,int32_t numcards,int32_t N);
uint8_t *cards777_encode(bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N);
uint8_t *cards777_encode(struct supernet_info *myinfo,bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N);
void pangea_sendcmd(struct supernet_info *myinfo,struct table_info *tp,char *cmdstr,int32_t destplayer,uint8_t *data,int32_t datalen,int32_t cardi,int32_t turni);
void pangea_summaryadd(struct supernet_info *myinfo,struct table_info *tp,uint8_t type,void *arg0,int32_t size0,void *arg1,int32_t size1);

2
iguana/pangea_hand.c

@ -336,7 +336,7 @@ void pangea_encoded(PANGEA_HANDARGS)
return;
}
hand->encodestarted = (uint32_t)time(NULL);//pm->sig.timestamp;
cards777_encode(tp->priv.outcards,tp->priv.xoverz,tp->priv.allshares,tp->priv.myshares,hand->sharenrs[tp->priv.myind],tp->G.M,(void *)data,tp->G.numcards,N);
cards777_encode(myinfo,tp->priv.outcards,tp->priv.xoverz,tp->priv.allshares,tp->priv.myshares,hand->sharenrs[tp->priv.myind],tp->G.M,(void *)data,tp->G.numcards,N);
PNACL_message("player.%d ind.%d encodes into %p %llx -> %llx next.%d N %d\n",tp->priv.myind,tp->priv.myind,tp->priv.outcards,(long long)*(uint64_t *)data,(long long)tp->priv.outcards[0].txid,pangea_nextnode(tp),N);
if ( tp->priv.myind > 0 )
{

24
includes/iguana_funcs.h

@ -413,6 +413,7 @@ int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint
cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr);
int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]);
struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_waccount **wacctp,char *coinaddr);
void calc_shares(struct supernet_info *myinfo,uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs,uint8_t *space,int32_t spacesize);
int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,int16_t hdrsi,uint32_t unspentind,int64_t value);
int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,cJSON *unspents,cJSON *spends,char *coinaddr,int32_t minconf,int32_t firstheight);
cJSON *iguana_walletjson(struct supernet_info *myinfo);
@ -537,6 +538,29 @@ double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *b
int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]);
int64_t iguana_lockval(int32_t finalized,int64_t locktime);
// ------------------------------------------------------[ Preparation ]----
// Initialise a gfshare context for producing shares
gfshare_ctx *gfshare_ctx_initenc(uint8_t * /* sharenrs */,uint32_t /* sharecount */, uint8_t /* threshold */,uint32_t /* size */,void *,int32_t);
// Initialise a gfshare context for recombining shares
gfshare_ctx *gfshare_ctx_initdec(uint8_t * /* sharenrs */,uint32_t /* sharecount */,uint32_t /* size */,void *,int32_t);
// Free a share context's memory
void gfshare_ctx_free(gfshare_ctx * /* ctx */);
// --------------------------------------------------------[ Splitting ]----
// Provide a secret to the encoder. (this re-scrambles the coefficients)
void gfshare_ctx_enc_setsecret(gfshare_ctx * /* ctx */,uint8_t * /* secret */);
// Extract a share from the context. 'share' must be preallocated and at least 'size' bytes long. 'sharenr' is the index into the 'sharenrs' array of the share you want.
void gfshare_ctx_encgetshare(uint8_t *logs,uint8_t *exps,gfshare_ctx * /* ctx */,uint8_t /* sharenr */,uint8_t * /* share */);
// ----------------------------------------------------[ Recombination ]----
// Inform a recombination context of a change in share indexes
void gfshare_ctx_dec_newshares(gfshare_ctx * /* ctx */, uint8_t * /* sharenrs */);
// Provide a share context with one of the shares. The 'sharenr' is the index into the 'sharenrs' array
void gfshare_ctx_dec_giveshare(gfshare_ctx * /* ctx */,uint8_t /* sharenr */,uint8_t * /* share */);
// Extract the secret by interpolation of the shares. secretbuf must be allocated and at least 'size' bytes long
void gfshare_ctx_decextract(uint8_t *logs,uint8_t *exps,gfshare_ctx * /* ctx */,uint8_t * /* secretbuf */);
void libgfshare_init(struct supernet_info *myinfo,uint8_t _logs[256],uint8_t _exps[510]);
int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n);
void iguana_schnorr(struct supernet_info *myinfo);
#include "../includes/iguana_api.h"

6
includes/iguana_structs.h

@ -446,5 +446,11 @@ struct bitcoin_spend
};
struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; };
struct _gfshare_ctx
{
uint32_t sharecount,threshold,size,buffersize,allocsize;
uint8_t sharenrs[255],buffer[];
};
#endif

1
includes/iguana_types.h

@ -21,6 +21,7 @@ typedef void (*iguana_func)(void *);
typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len);
//typedef void *(*basilisk_func)(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals);
//typedef double (*basilisk_metricfunc)(struct supernet_info *myinfo,struct basilisk_item *ptr,char *result);
typedef struct _gfshare_ctx gfshare_ctx;
#endif

10
includes/libgfshare.h

@ -64,9 +64,8 @@ void gfshare_ctx_enc_setsecret(gfshare_ctx* /* ctx */,
* 'share' must be preallocated and at least 'size' bytes long.
* 'sharenr' is the index into the 'sharenrs' array of the share you want.
*/
void gfshare_ctx_enc_getshare(gfshare_ctx* /* ctx */,
unsigned char /* sharenr */,
unsigned char* /* share */);
void gfshare_ctx_encgetshare(uint8_t *logs,uint8_t *exps,gfshare_ctx* /* ctx */, unsigned char /* sharenr */, unsigned char* /* share */);
void gfshare_ctx_enc_getshare(gfshare_ctx* /* ctx */, unsigned char /* sharenr */, unsigned char* /* share */);
/* ----------------------------------------------------[ Recombination ]---- */
@ -84,8 +83,9 @@ void gfshare_ctx_dec_giveshare(gfshare_ctx* /* ctx */,
/* Extract the secret by interpolation of the shares.
* secretbuf must be allocated and at least 'size' bytes long
*/
void gfshare_ctx_dec_extract(gfshare_ctx* /* ctx */,
unsigned char* /* secretbuf */);
void gfshare_ctx_decextract(uint8_t *logs,uint8_t *exps,gfshare_ctx* /* ctx */, unsigned char* /* secretbuf */);
void gfshare_ctx_dec_extract(gfshare_ctx* /* ctx */, unsigned char* /* secretbuf */);
#endif /* LIBGFSHARE_H */

Loading…
Cancel
Save