Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
d6d7229eb2
  1. 1
      crypto777/OS_portable.h
  2. 164
      crypto777/libgfshare.c
  3. 19
      deprecated/obsolete.h
  4. 3
      iguana/SuperNET.h
  5. 23
      iguana/exchanges/bitcoin.c
  6. 4
      iguana/exchanges777.h
  7. 1
      iguana/iguana777.h
  8. 7
      iguana/iguana_chains.c
  9. 20
      iguana/iguana_instantdex.c
  10. 2
      iguana/iguana_peers.c
  11. 2
      iguana/iguana_pubkeys.c
  12. 757
      iguana/main.c
  13. 442
      iguana/swaps/iguana_BTCswap.c

1
crypto777/OS_portable.h

@ -355,6 +355,7 @@ bits256 bits256_lshift(bits256 x);
bits256 bits256_from_compact(uint32_t c);
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);
extern char *Iguana_validcommands[];
extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY;

164
crypto777/libgfshare.c

@ -39,10 +39,10 @@
struct _gfshare_ctx
{
uint32_t sharecount,threshold,size,buffersize;
unsigned char sharenrs[255],buffer[];
uint8_t sharenrs[255],buffer[];
};
unsigned char ctx_logs[256] = {
uint8_t ctx_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,
@ -76,7 +76,7 @@ unsigned char ctx_logs[256] = {
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf };
unsigned char ctx_exps[510] = {
uint8_t ctx_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,
@ -142,20 +142,20 @@ unsigned char ctx_exps[510] = {
0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b,
0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e };
/*void _gfshare_fill_rand_using_random(unsigned char *buffer,unsigned long long count)
/*void _gfshare_fill_rand_using_random(uint8_t *buffer,unsigned long long count)
{
uint32_t 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
}*/
//void randombytes(unsigned char *x,long xlen);
//void randombytes(uint8_t *x,long xlen);
//gfshare_rand_func_t gfshare_fill_rand = _gfshare_fill_rand_using_random;
gfshare_rand_func_t gfshare_fill_rand = OS_randombytes;
//gfshare_rand_func_t gfshare_fill_rand = OS_randombytes;
// ------------------------------------------------------[ Preparation ]----
gfshare_ctx *_gfshare_ctx_init_core(unsigned char *sharenrs,uint32_t sharecount,unsigned char threshold,uint32_t size)
gfshare_ctx *_gfshare_ctx_init_core(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size)
{
gfshare_ctx *ctx;
ctx = XMALLOC(sizeof(struct _gfshare_ctx) + threshold * size);
@ -170,7 +170,7 @@ gfshare_ctx *_gfshare_ctx_init_core(unsigned char *sharenrs,uint32_t sharecount,
}
// Initialise a gfshare context for producing shares
gfshare_ctx *gfshare_ctx_init_enc(unsigned char *sharenrs,uint32_t sharecount,unsigned char threshold,uint32_t size)
gfshare_ctx *gfshare_ctx_init_enc(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size)
{
uint32_t i;
// can't have x[i] = 0 - that would just be a copy of the secret, in theory
@ -179,6 +179,7 @@ gfshare_ctx *gfshare_ctx_init_enc(unsigned char *sharenrs,uint32_t sharecount,un
{
if ( sharenrs[i] == 0 )
{
printf("null sharenrs error\n");
errno = EINVAL;
return NULL;
}
@ -187,7 +188,7 @@ gfshare_ctx *gfshare_ctx_init_enc(unsigned char *sharenrs,uint32_t sharecount,un
}
// Initialise a gfshare context for recombining shares
gfshare_ctx *gfshare_ctx_init_dec(unsigned char *sharenrs,uint32_t sharecount,uint32_t size)
gfshare_ctx *gfshare_ctx_init_dec(uint8_t *sharenrs,uint32_t sharecount,uint32_t size)
{
gfshare_ctx *ctx = _gfshare_ctx_init_core(sharenrs,sharecount,sharecount,size);
if ( ctx != NULL )
@ -199,26 +200,28 @@ gfshare_ctx *gfshare_ctx_init_dec(unsigned char *sharenrs,uint32_t sharecount,ui
void gfshare_ctx_free(gfshare_ctx *ctx)
{
long len = sizeof(struct _gfshare_ctx) + ctx->buffersize;
gfshare_fill_rand((unsigned char*)ctx,len);
//gfshare_fill_rand((uint8_t*)ctx,len);
OS_randombytes((uint8_t *)ctx,len);
XFREE(ctx);
}
// --------------------------------------------------------[ Splitting ]----
// Provide a secret to the encoder. (this re-scrambles the coefficients)
void gfshare_ctx_enc_setsecret(gfshare_ctx *ctx,unsigned char *secret)
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);
//gfshare_fill_rand(ctx->buffer,(ctx->threshold-1) * 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 calc_share(unsigned char *buffer,int32_t size,int32_t M,uint32_t ilog,unsigned char *share)
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]];
//unsigned char *coefficient_ptr = buffer;
unsigned char *share_ptr,share_byte;
//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++)
@ -234,46 +237,134 @@ void calc_share(unsigned char *buffer,int32_t size,int32_t M,uint32_t ilog,unsig
}
}
void gfshare_ctx_enc_getshare(gfshare_ctx *ctx,unsigned char sharenr,unsigned char *share)
void gfshare_ctx_enc_getshare(gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share)
{
calc_share(ctx->buffer,ctx->size,ctx->threshold,ctx_logs[ctx->sharenrs[sharenr]],share);
}
void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs)
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;
unsigned char *buffer = calloc(M,width);
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);
//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);
//uint32_t _crc32(uint32_t crc, const void *buf, size_t size);
calc_share(buffer,size,M,ctx_logs[sharenrs[i]],&shares[i * width]);
//printf("(%02x %08x) ",sharenrs[i],_crc32(0,&shares[i*width],size));
printf("(%02x %08x) ",sharenrs[i],calc_crc32(0,&shares[i*width],size));
}
free(buffer);
}
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);
memset(sharenrs,0,n);
if ( orig == 0 && n == m )
{
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
{
remains = n;
orign = n;
memcpy(valid,sharenrs,n);
i = j = 0;
memset(sharenrs,0,n);
for (i=0; i<m; i++)
{
r = (rand() >> 8) % remains;
sharenrs[i] = valid[r];
valid[r] = valid[--remains];
}
/*while ( i < m )
{
if ( j >= 65536 )
{
gfshare_fill_rand(randvals,65536);
printf("refill j.%d\n",j);
j = 0;
}
r = (randvals[j++] % n);
if ( valid[r] != 0 )
{
remains--;
i++;
sharenrs[r] = valid[r];
//printf("%d ",sharenrs[i]);
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);
//printf("sharenrs m.%d of n.%d\n",m,n);
if ( remains != (orign - m) )
{
printf("remains algo error??\n");
return(-1);
}
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);
}
// ----------------------------------------------------[ Recombination ]----
// Inform a recombination context of a change in share indexes
void gfshare_ctx_dec_newshares(gfshare_ctx *ctx,unsigned char *sharenrs)
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,unsigned char sharenr,unsigned char *share)
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_extract(unsigned char *secretbuf,uint8_t *sharenrs,int32_t N,uint8_t *buffer,int32_t size,int32_t width)
void gfshare_extract(uint8_t *secretbuf,uint8_t *sharenrs,int32_t N,uint8_t *buffer,int32_t size,int32_t width)
{
uint32_t i,j,Li_top,Li_bottom;
unsigned char *secret_ptr,*share_ptr,sharei,sharej;
uint32_t i,j,Li_top,Li_bottom; uint8_t *secret_ptr,*share_ptr,sharei,sharej;
memset(secretbuf,0,width);
for (i=0; i<N; i++)
{
@ -309,14 +400,14 @@ void gfshare_extract(unsigned char *secretbuf,uint8_t *sharenrs,int32_t N,uint8_
}
}
void gfshare_ctx_dec_extract(gfshare_ctx *ctx,unsigned char *secretbuf)
void gfshare_ctx_dec_extract(gfshare_ctx *ctx,uint8_t *secretbuf)
{
gfshare_extract(secretbuf,ctx->sharenrs,ctx->sharecount,ctx->buffer,ctx->size,ctx->size);
}
int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n)
int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n)
{
unsigned char *randvals,valid[255];
uint8_t *randvals,valid[255];
int32_t i,j,r,remains,orign;
if ( m > n || n >= 0xff ) // reserve 255 for illegal sharei
{
@ -324,7 +415,7 @@ int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,
return(-1);
}
randvals = calloc(1,65536);
gfshare_fill_rand(randvals,65536);
OS_randombytes(randvals,65536);
memset(sharenrs,0,n);
if ( orig == 0 && n == m )
{
@ -335,10 +426,10 @@ int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,
{
r = (randvals[i] % remains);
sharenrs[i] = valid[r];
//printf("%d ",sharenrs[i]);
printf("%d ",sharenrs[i]);
valid[r] = valid[--remains];
}
//printf("FULL SET\n");
printf("FULL SET\n");
}
else
{
@ -417,7 +508,7 @@ int test_m_of_n(int m,int n,int size,int maxiters)
for (i=0; i<n; i++)
shares[i] = malloc(size);
// Stage 1, make a secret
gfshare_fill_rand(secret,size);
OS_randombytes(secret,size);
err = 0;
r = m;
@ -425,7 +516,7 @@ int test_m_of_n(int m,int n,int size,int maxiters)
{
memset(allshares,0,254*size);
// Stage 2, split it n ways with a threshold of m
if ( 0 )
if ( 1 )
{
G = gfshare_ctx_init_enc(sharenrs,n,r,size);
gfshare_ctx_enc_setsecret(G,secret);
@ -456,7 +547,8 @@ int test_m_of_n(int m,int n,int size,int maxiters)
}
err = 0;
printf("err.%d\n",err);
#ifdef hardcoded_m_of_n_test
//#ifdef hardcoded_m_of_n_test
int32_t ok;
// Stage 3, attempt a recombination with shares 1 and 2
sharenrs[2] = 0;
gfshare_ctx_dec_newshares(G,sharenrs);
@ -497,7 +589,7 @@ int test_m_of_n(int m,int n,int size,int maxiters)
err += (ok == 0), ok = 1;
gfshare_ctx_free( G );
printf("total error test_m_of_n %d\n",err);
#endif
//#endif
cleanup:
for (i=0; i<n; i++)
free(shares[i]);

19
deprecated/obsolete.h

@ -13318,5 +13318,24 @@ len = 0;
nextcmdstr = message = "";
*/
if ( A->orderid != orderid )
{
printf("orderid mismatch %llu vs %llu\n",(long long)orderid,(long long)A->orderid);
return(clonestr("{\"error\":\"instantdex_BTCswap orderid mismatch\"}"));
}
if ( senderaddr == 0 || strcmp(A->A.base,base) != 0 || strcmp(A->A.rel,"BTC") != 0 )
{
printf("senderaddr.%p base.(%s vs %s) rel.(%s vs %s)\n",senderaddr,A->A.base,base,A->A.rel,"BTC");
return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}"));
}
{
printf("satoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)instantdex_relsatoshis(A->A.price64,A->A.basevolume64));
return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}"));
}
if ( othersatoshis != A->A.basevolume64 )
{
printf("othersatoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)A->A.basevolume64);
return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}"));
}
#endif

3
iguana/SuperNET.h

@ -169,6 +169,9 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char
bits256 bitcoin_pubkey33(uint8_t data[33],bits256 privkey);
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len);
uint8_t *cards777_recover(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t numcards,int32_t N);
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 init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n);
#endif

23
iguana/exchanges/bitcoin.c

@ -1099,11 +1099,11 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,struct vin
return(vp->spendlen);
}
int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,int32_t *scriptlens,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V)
int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,int32_t *scriptlens,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighashsingle)
{
bits256 txid,sigtxid,revsigtxid; char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65];
uint8_t *sig,*pubkey,*saveinput; struct vin_info *vp;
int32_t n2,i,j,k,plen,vini=0,flag,numvins,hashtype,retval,siglen,asmtype;
int32_t n2,i,j,k,plen,vini=0,flag,numvins,hashtype,retval,siglen,asmtype,numvouts = msgtx->tx_out;
vpnstr[0] = 0;
*signedtx = 0;
memset(signedtxidp,0,sizeof(*signedtxidp));
@ -1116,7 +1116,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
for (i=0; i<numvins; i++)
msgtx->vins[i].scriptlen = 0;
sig = &msgtx->vins[vini].script[1];
siglen = msgtx->vins[vini].script[0] - 1;
siglen = msgtx->vins[vini].script[0];
vp->vin = msgtx->vins[vini];
flag = 0;
for (k=0; k<2; k++)
@ -1127,6 +1127,11 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
printf("cant get script for (%s).v%d\n",bits256_str(str,vp->vin.prev_hash),vp->vin.prev_vout);
continue;
}
if ( sighashsingle != 0 && vini == 0 )
{
msgtx->tx_out = 1;
hashtype = SIGHASH_SINGLE;
} else msgtx->tx_out = numvouts;
msgtx->vins[vini].script = vp->spendscript;
msgtx->vins[vini].scriptlen = vp->spendlen;
for (j=0; j<vp->N; j++)
@ -1143,6 +1148,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
if ( n2 > 0 )
{
n2 += iguana_rwnum(1,&serialized[n2],sizeof(hashtype),&hashtype);
printf("hashtype.%d [%02x]\n",hashtype,sig[siglen-1]);
revsigtxid = bits256_doublesha256(txidstr,serialized,n2);
for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i];
@ -1150,9 +1156,12 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
{
vp->signers[j].siglen = bitcoin_sign(vp->signers[j].sig,sizeof(vp->signers[j].sig),sigtxid.bytes,sizeof(sigtxid),vp->signers[j].privkey);
sig = vp->signers[j].sig;
sig[vp->signers[j].siglen++] = hashtype;
siglen = vp->signers[j].siglen;
msgtx->vins[vini].scriptlen = bitcoin_scriptsig(msgtx->vins[vini].script,0,(const struct vin_info *)vp);
printf("SIGNEDTX plen.%d siglen.%d\n",plen,siglen);
for (i=0; i<siglen; i++)
printf("%02x",sig[i]);
printf(" SIGNEDTX.[%02x] plen.%d siglen.%d\n",sig[siglen-1],plen,siglen);
}
if ( bitcoin_verify(sig,siglen,sigtxid.bytes,sizeof(sigtxid),0,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 )
{
@ -1161,9 +1170,9 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
}
else
{
printf("SIG.%d VERIFIED\n",vini);
*signedtx = iguana_rawtxbytes(coin,0,msgtx);
*signedtxidp = msgtx->txid;
printf("SIG.%d VERIFIED %s\n",vini,*signedtx);
flag = 1;
break;
}
@ -1214,7 +1223,7 @@ int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **si
scriptlens = calloc(numvins,sizeof(*scriptlens));
for (i=0; i<numvins; i++)
scriptlens[i] = msgtx.vins[i].scriptlen;
if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,scriptlens,&msgtx,serialized2,maxsize,V) == 0 )
if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,scriptlens,&msgtx,serialized2,maxsize,V,0) == 0 )
retval = 0;
else printf("bitcoin_verifytx: bitcoin_verifyvins error\n");
for (i=0; i<numvins; i++)
@ -1340,8 +1349,8 @@ cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid)
struct iguana_msgtx msgtx; char str[65],str2[65]; bits256 checktxid,blockhash,signedtxid;
cJSON *retjson,*txjson; uint8_t *serialized,*serialized2; struct iguana_txid T,*tp;
struct vin_info *V; char vpnstr[64],*txbytes,*signedtx; int32_t n,txstart,height,n2,maxsize,len;
len = (int32_t)strlen(rawtxstr);
rawtxstr = refstr;
len = (int32_t)strlen(rawtxstr);
maxsize = len + 32768;
serialized = calloc(1,maxsize);
serialized2 = calloc(1,maxsize);

4
iguana/exchanges777.h

@ -94,12 +94,12 @@ struct bitcoin_spend
{
char changeaddr[64];
int32_t numinputs;
uint64_t txfee,input_satoshis,satoshis;
int64_t txfee,input_satoshis,satoshis,change,netamount;
struct bitcoin_unspent inputs[];
};
struct instantdex_entry { char base[24],rel[24]; uint64_t price64,basevolume64,offer64; uint32_t expiration,nonce; char myside,acceptdir; };
struct instantdex_accept { struct queueitem DL; uint64_t pendingvolume64,orderid; uint32_t dead; struct instantdex_entry A; };
struct instantdex_accept { struct queueitem DL; cJSON *statusjson; uint64_t pendingvolume64,orderid; uint32_t dead; struct instantdex_entry A; };
struct instantdex_accept *instantdex_acceptablefind(struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel);
cJSON *instantdex_acceptjson(struct instantdex_accept *ap);

1
iguana/iguana777.h

@ -184,6 +184,7 @@ struct iguana_chain
uint8_t genesis_hashdata[32],minconfirms;
uint16_t ramchainport,bundlesize,hasheaders;
char gethdrsmsg[16];
uint64_t txfee,minoutput;
};
struct iguana_msgaddress { uint32_t nTime; uint64_t nServices; uint8_t ip[16]; uint16_t port; } __attribute__((packed));

7
iguana/iguana_chains.c

@ -112,12 +112,17 @@ bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t bits,uin
void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders)
{
chain->hasheaders = hasheaders;
if ( strcmp(chain->symbol,"bitcoin") == 0 )
chain->minoutput = 10000;
if ( strcmp(chain->symbol,"BTC") == 0 )
{
chain->unitval = 0x1d;
chain->txfee = 10000;
}
else
{
if ( strcmp(chain->symbol,"LTC") == 0 )
chain->txfee = 100000;
else chain->txfee = 1000000;
if ( chain->unitval == 0 )
chain->unitval = 0x1e;
}

20
iguana/iguana_instantdex.c

@ -380,8 +380,8 @@ cJSON *instantdex_acceptsendjson(struct instantdex_accept *ap)
char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
{
char cmdstr[16],*traderip,*orderidstr; struct exchange_info *exchange; uint64_t orderid;
struct instantdex_accept A,*ap;
char cmdstr[16],*traderip,*orderidstr,*retstr; struct exchange_info *exchange; uint64_t orderid;
struct instantdex_accept A,*ap = 0;
exchange = exchanges777_find("bitcoin");
memset(cmdstr,0,sizeof(cmdstr)), memcpy(cmdstr,msg->cmd,sizeof(msg->cmd));
if ( argjson != 0 )
@ -397,15 +397,21 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms
orderid = calc_nxt64bits(orderidstr);
if ( (ap= instantdex_acceptablefind(exchange,0,0,orderid,"*","*")) != 0 )
A = *ap;
} else instantdex_acceptextract(&A,argjson);
} else if ( instantdex_acceptextract(&A,argjson) < 0 )
return(clonestr("{\"error\":\"hash txid mismatches orderid\"}"));
if ( strncmp(cmdstr,"BTC",3) == 0 )
return(instantdex_BTCswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
retstr = instantdex_BTCswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen);
else if ( strncmp(cmdstr,"NXT",3) == 0 )
return(instantdex_NXTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
retstr = instantdex_NXTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen);
else if ( strncmp(cmdstr,"ALT",3) == 0 )
return(instantdex_ALTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
retstr = instantdex_ALTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen);
else if ( strncmp(cmdstr,"PAX",3) == 0 )
return(instantdex_PAXswap(myinfo,exchanges777_find("PAX"),&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
retstr = instantdex_PAXswap(myinfo,exchanges777_find("PAX"),&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen);
if ( ap != 0 )
{
ap->statusjson = A.statusjson;
ap->pendingvolume64 = A.pendingvolume64;
}
else return(clonestr("{\"error\":\"unrecognized atomic swap family\"}"));
}
return(clonestr("{\"error\":\"request needs argjson\"}"));

2
iguana/iguana_peers.c

@ -762,7 +762,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr)
printf("error updating status for (%s) ind.%d\n",ipaddr,iA->hh.itemind);
iguana_iAddriterator(coin,iA);
} else printf("ignore.(%s) lastconnect.%u lastkilled.%u numconnects.%d\n",ipaddr,iA->lastconnect,iA->lastkilled,iA->numconnects);
} else printf("skip.(%s) ind.%d status.%d\n",ipaddr,iA->hh.itemind,iA->status);
} //else printf("skip.(%s) ind.%d status.%d\n",ipaddr,iA->hh.itemind,iA->status);
} else printf("cant find (%s) which should have been created\n",ipaddr);
} else printf("reject ipaddr.(%s)\n",ipaddr);
}

2
iguana/iguana_pubkeys.c

@ -668,7 +668,7 @@ int32_t btc_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr)
len = (int32_t)cstr->len;
char tmp[138];
btc_priv2wif(tmp,privkey,*addrtypep);
printf("addrtype.%02x wifstr.(%llx) len.%d\n",*addrtypep,*(long long *)privkey,len);
printf("addrtype.%02x wifstr.(%llx) privlen.%d\n",*addrtypep,*(long long *)privkey,len);
cstr_free(cstr,true);
}
return(len);

757
iguana/main.c

@ -298,11 +298,760 @@ 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 )
{
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 =
_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] = (random() & 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_main(void *arg)
{
int32_t usessl = 0, ismainnet = 1;
struct supernet_info *myinfo; char *tmpstr,*helperargs,*coinargs,helperstr[512]; int32_t i;
mycalloc(0,0,0);
if ( 0 )
{
int32_t M,N;
for (i=0; i<1000000; i++)
{
N = (rand() % 254) + 2;
M = (rand () % (N-1)) + 1;
test(M,N,512);
}
//int test_m_of_n(int m,int n,int size,int maxiters);
// test_m_of_n(2,3,8,1);
getchar();
int32_t i,j,m,size,datasize = 16;
uint8_t *allshares,*myshares[255],sharenrs[255],*recover,*testshares[9],testnrs[255],*data;
memset(sharenrs,0,255);
N = 8, M = 8;
size = N * datasize;
data = calloc(1,datasize);
allshares = malloc(N * datasize);
for (i=0; i<N; i++)
myshares[i] = calloc(1,datasize);
init_sharenrs(sharenrs,0,N,N);
for (i=0; i<N; i++)
testshares[i] = myshares[i];
for (i=0; i<datasize; i++)
data[i] = i, printf("%02x ",data[i]);
printf("data\n");
calcmofn(allshares,myshares,sharenrs,M,data,datasize,N);
if ( (recover= recoverdata(testshares,sharenrs,M,datasize,N)) != 0 )
{
if ( memcmp(data,recover,size) != 0 )
{
for (i=0; i<datasize; i++)
printf("%02x ",recover[i]);
printf("(ERROR M.%d N.%d)\n",M,N);
}
else fprintf(stderr,"reconstructed with M.%d N.%d\n",M,N);
free(recover);
} else printf("nullptr from cards777_recover\n");
for (j=0; j<1; j++)
{break;
memset(testnrs,0,sizeof(testnrs));
memset(testshares,0,sizeof(testshares));
m = (rand() % N) + 1;
if ( m < M )
m = M;
if ( init_sharenrs(testnrs,sharenrs,m,N) < 0 )
{
printf("iter.%d error init_sharenrs(m.%d of n.%d)\n",j,m,N);
}
for (i=0; i<N; i++)
if ( testnrs[i] == sharenrs[i] )
testshares[i] = myshares[i];
if ( (recover= recoverdata(testshares,sharenrs,M,datasize,N)) != 0 )
{
if ( memcmp(data,recover,size) != 0 )
fprintf(stderr,"(ERROR m.%d M.%d N.%d)\n",m,M,N);
else fprintf(stderr,"reconstructed with m.%d M.%d N.%d\n",m,M,N);
free(recover);
} else printf("nullptr from cards777_recover\n");
}
getchar();
}
myinfo = SuperNET_MYINFO(0);
if ( usessl == 0 )
strcpy(myinfo->NXTAPIURL,"http://127.0.0.1:");
@ -351,14 +1100,18 @@ void iguana_main(void *arg)
#ifdef __APPLE__
sleep(1);
char *str;
strcpy(MYINFO.rpcsymbol,"BTCD");
strcpy(MYINFO.rpcsymbol,"BTC");
iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}"));
if ( 0 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"wallet\":\"password\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":3,\"newcoin\":\"BTCD\",\"active\":0}"),0)) != 0 )
if ( 0 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"wallet\":\"password\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":3,\"newcoin\":\"BTC\",\"active\":0}"),0)) != 0 )
{
printf("got.(%s)\n",str);
free(str);
}
sleep(1);
static bits256 txid;
bitcoin_txtest(iguana_coinfind(MYINFO.rpcsymbol),"000",txid);
getchar();
#endif
}
if ( arg != 0 )

442
iguana/swaps/iguana_BTCswap.c

@ -14,6 +14,21 @@
******************************************************************************/
#include "../exchanges/bitcoin.h"
/*
bitcoin_pubkey33(pubkey,myinfo->persistent_priv);
bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey));
bitcoin_addr2rmd160(&addrtype,secret160,coinaddr);
scriptlen = bitcoin_cltvscript(coinbtc->chain->p2shtype,p2sh_coinaddr,p2sh_rmd160,script,0,senderaddr,otheraddr,secret160,locktime);
if ( jobj(argjson,"p2sh") != 0 )
{
if ( strcmp(jstr(argjson,"p2sh"),p2sh_coinaddr) != 0 )
{
printf("mismatched p2sh.(%s) vs (%s)\n",jstr(argjson,"p2sh"),p2sh_coinaddr);
return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}"));
}
}
*/
#define INSTANTDEX_DONATION 2000
// https://github.com/TierNolan/bips/blob/bip4x/bip-atom.mediawiki
@ -24,23 +39,23 @@ uint64_t instantdex_relsatoshis(uint64_t price,uint64_t volume)
else return(dstr(price) * volume);
}
bits256 instantdex_sharedpub256(uint8_t pubkey[33],bits256 privkey,bits256 hash,int32_t n)
bits256 instantdex_sharedpub256(bits256 *sharedprivp,uint8_t pubkey[33],bits256 privkey,bits256 hash,int32_t n)
{
bits256 tmppriv,shared,iters; int32_t i;
bits256 shared,iters; int32_t i;
iters = shared = curve25519_shared(privkey,hash);
for (i=0; i<n; i++)
iters = curve25519(iters,curve25519(iters,curve25519_basepoint9()));
vcalc_sha256cat(tmppriv.bytes,shared.bytes,sizeof(shared),iters.bytes,sizeof(iters));
return(bitcoin_pubkey33(pubkey,tmppriv));
vcalc_sha256cat(sharedprivp->bytes,shared.bytes,sizeof(shared),iters.bytes,sizeof(iters));
return(bitcoin_pubkey33(pubkey,*sharedprivp));
}
int32_t instantdex_pubkeyargs(cJSON *argjson,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte)
int32_t instantdex_pubkeyargs(bits256 *sharedprivs,cJSON *argjson,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte)
{
char buf[3]; int32_t i,n; bits256 tmp; uint8_t pubkey[33];
sprintf(buf,"%c0",'A' - 0x02 + firstbyte);
for (i=n=0; i<numpubs*100&&n<numpubs; i++)
{
tmp = instantdex_sharedpub256(pubkey,privkey,hash,i+1);
tmp = instantdex_sharedpub256(&sharedprivs[n],pubkey,privkey,hash,i+1);
if ( pubkey[0] != firstbyte )
continue;
buf[1] = '0' + n++;
@ -61,35 +76,108 @@ int32_t bitcoin_2of2spendscript(int32_t *paymentlenp,uint8_t *paymentscript,uint
return(p2shlen);
}
/*struct bitcoin_unspent { bits256 txid,privkey; uint64_t value; int32_t vout; };
struct bitcoin_spend
struct bitcoin_unspent *instantdex_bestfit(struct iguana_info *coin,struct bitcoin_unspent *unspents,int32_t numunspents,uint64_t value,int32_t mode)
{
int32_t i; uint64_t above,below,gap,atx_value; struct bitcoin_unspent *vin,*abovevin,*belowvin;
abovevin = belowvin = 0;
for (above=below=i=0; i<numunspents; i++)
{
vin = &unspents[i];
atx_value = vin->value;
//printf("(%.8f vs %.8f)\n",dstr(atx_value),dstr(value));
if ( atx_value == value )
return(vin);
else if ( atx_value > value )
{
gap = (atx_value - value);
if ( above == 0 || gap < above )
{
above = gap;
abovevin = vin;
}
}
else if ( mode == 0 )
{
gap = (value - atx_value);
if ( below == 0 || gap < below )
{
below = gap;
belowvin = vin;
}
}
}
if ( (vin= (abovevin != 0) ? abovevin : belowvin) == 0 && mode == 1 )
vin = unspents;
return(vin);
}
struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numunspentsp)
{
char changeaddr[64];
int32_t numinputs;
uint64_t txfee,input_satoshis,satoshis;
struct bitcoin_unspent inputs[];
};*/
struct bitcoin_unspent *ups = calloc(1,sizeof(*ups));
// struct bitcoin_unspent { bits256 txid,privkey; uint64_t value; int32_t vout; };
*numunspentsp = 0;
return(ups);
}
char *instantdex_bailintx(struct iguana_info *coin,bits256 *txidp,struct bitcoin_spend *spend,bits256 A0,bits256 B0,uint8_t x[20],int32_t isbob)
struct bitcoin_spend *instantdex_spendset(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t satoshis,uint64_t donation)
{
/*Input value: B + 2*fb + change
Input source: (From Bob's coins, multiple inputs are allowed)
Output 0 value: B
ScriptPubKey 0: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL
Output 1 value: fb
ScriptPubKey 1: OP_HASH160 Hash160(x) OP_EQUALVERIFY pub-A1 OP_CHECKSIG
Output 2 value: change
ScriptPubKey 2: <= 100 bytes
P2SH Redeem: OP_2 pub-A1 pub-B1 OP_2 OP_CHECKMULTISIG
int32_t i,mode,numunspents,maxinputs = 1024; int64_t remains; struct bitcoin_unspent *ptr,*up;
struct bitcoin_unspent *ups; struct bitcoin_spend *spend;
if ( (ups= iguana_unspentsget(myinfo,coin,&numunspents)) == 0 )
return(0);
spend = calloc(1,sizeof(*spend) + sizeof(*spend->inputs) * maxinputs);
spend->satoshis = satoshis;
spend->txfee = coin->chain->txfee;
if ( strcmp(coin->symbol,"BTC") == 0 )
remains = spend->txfee + spend->satoshis + donation;
ptr = spend->inputs;
for (i=0; i<maxinputs; i++,ptr++)
{
for (mode=1; mode>=0; mode--)
if ( (up= instantdex_bestfit(coin,ups,numunspents,remains,mode)) != 0 )
break;
if ( up != 0 )
{
spend->input_satoshis += up->value;
spend->inputs[spend->numinputs++] = *up;
if ( spend->input_satoshis >= satoshis )
{
spend->netamount = (spend->input_satoshis - spend->txfee - donation);
spend->change = (spend->input_satoshis - spend->netamount);
printf("numinputs %d sum %.8f vs satoshis %.8f change %.8f -> txfee %.8f\n",spend->numinputs,dstr(spend->input_satoshis),dstr(satoshis),dstr(spend->change),dstr(spend->input_satoshis - spend->change - spend->netamount));
break;
}
remains -= up->value;
} else break;
}
if ( spend->input_satoshis >= (satoshis + spend->txfee) )
{
realloc(spend,sizeof(*spend) + sizeof(*spend->inputs) * spend->numinputs);
return(spend);
}
else
{
free(spend);
return(0);
}
}
/*
Name: Bob.Bail.In
Input value: B + 2*fb + change
Input source: (From Bob's coins, multiple inputs are allowed)
vout0 value: B, ScriptPubKey 0: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL
vout1 value: fb, ScriptPubKey 1: OP_HASH160 Hash160(x) OP_EQUALVERIFY pub-A1 OP_CHECKSIG
vout2 value: change, ScriptPubKey 2: <= 100 bytes
P2SH Redeem: OP_2 pub-A1 pub-B1 OP_2 OP_CHECKMULTISIG
Name: Alice.Bail.In
Input value: A + 2*fa + change
Input source: (From Alice's altcoins, multiple inputs are allowed)
Output 0 value: A
ScriptPubKey 0: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL
Output 1 value: fa
ScriptPubKey 1: OP_HASH160 Hash160(x) OP_EQUAL
Output 2 value: change
ScriptPubKey 2: <= 100 bytes*/
vins: A + 2*fa + change, Input source: (From Alice's altcoins, multiple inputs are allowed)
vout0 value: A, ScriptPubKey 0: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL
vout1 value: fa, ScriptPubKey 1: OP_HASH160 Hash160(x) OP_EQUAL
vout2 value: change, ScriptPubKey 2: <= 100 bytes
*/
char *instantdex_bailintx(struct iguana_info *coin,bits256 *txidp,struct bitcoin_spend *spend,bits256 A0,bits256 B0,uint8_t x[20],int32_t isbob)
{
uint64_t change; char *rawtxstr,*signedtx; struct vin_info *V; bits256 txid,signedtxid;
int32_t p2shlen,i; cJSON *txobj; int32_t scriptv0len,scriptv1len,scriptv2len;
uint8_t p2shscript[256],scriptv0[128],scriptv1[128],changescript[128],pubkey[35];
@ -114,19 +202,98 @@ Name: Alice.Bail.In
bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V);
free(rawtxstr), free(V);
if ( signedtx != 0 )
printf("signed bob_bailin.%s (%s)\n",bits256_str(str,signedtxid),signedtx);
printf("signed %s_bailin.%s (%s)\n",isbob!=0?"bob":"alice",bits256_str(str,signedtxid),signedtx);
else printf("error generating signedtx\n");
free_json(txobj);
*txidp = txid;
return(signedtx);
}
int32_t instantdex_calcx20(char hexstr[41],uint8_t *p2shscript,uint8_t firstbyte,bits256 pub3)
cJSON *instantdex_bailinspend(struct iguana_info *coin,bits256 privkey,uint64_t amount)
{
bits256 hash; int32_t n; cJSON *txobj;
int32_t scriptv0len; uint8_t p2shscript[256],rmd160[20],scriptv0[128],pubkey[35];
bitcoin_pubkey33(pubkey,privkey);
n = bitcoin_pubkeyspend(p2shscript,0,pubkey);
vcalc_sha256(0,hash.bytes,p2shscript,n);
calc_rmd160(0,rmd160,hash.bytes,sizeof(hash.bytes));
scriptv0len = bitcoin_p2shspend(scriptv0,0,rmd160);
txobj = bitcoin_createtx(coin,0);
bitcoin_addoutput(coin,txobj,scriptv0,scriptv0len,amount);
return(txobj);
}
/*
Name: Bob.Payout
vin0: A, Input source: Alice.Bail.In:0
vin1: fa, Input source: Alice.Bail.In:1
vout0: A, ScriptPubKey: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL; P2SH Redeem: pub-B2 OP_CHECKSIG
Name: Alice.Payout
vin0: B, Input source: Bob.Bail.In:0
vin1: fb, Input source: Bob.Bail.In:1
vout0: B, ScriptPubKey: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL; P2SH Redeem: pub-A2 OP_CHECKSIG
*/
char *instantdex_bailinsign(struct iguana_info *coin,bits256 bailinpriv,char *sigstr,int32_t *siglenp,bits256 *txidp,struct vin_info *V,cJSON *txobj,int32_t isbob)
{
char *rawtxstr,*signedtx;
rawtxstr = bitcoin_json2hex(coin,txidp,txobj);
char str[65]; printf("%s_payout.%s (%s)\n",isbob!=0?"bob":"alice",bits256_str(str,*txidp),rawtxstr);
V->signers[isbob].privkey = bailinpriv;
bitcoin_verifytx(coin,txidp,&signedtx,rawtxstr,V);
*siglenp = V->signers[isbob].siglen;
init_hexbytes_noT(sigstr,V->signers[isbob].sig,*siglenp);
free(rawtxstr);
if ( signedtx != 0 )
printf("signed %s_payout.%s (%s) sig.%s\n",isbob!=0?"bob":"alice",bits256_str(str,*txidp),signedtx,sigstr);
else printf("error generating signedtx\n");
free_json(txobj);
return(signedtx);
}
char *instantdex_payouttx(struct iguana_info *coin,char *sigstr,int32_t *siglenp,bits256 *txidp,bits256 *sharedprivs,bits256 bailintxid,int64_t amount,int64_t txfee,int32_t isbob,char *othersigstr)
{
struct vin_info V; cJSON *txobj;
txobj = instantdex_bailinspend(coin,sharedprivs[1],amount);
bitcoin_addinput(coin,txobj,bailintxid,0,0xffffffff);
bitcoin_addinput(coin,txobj,bailintxid,1,0xffffffff);
memset(&V,0,sizeof(V));
if ( othersigstr != 0 )
{
printf("OTHERSIG.(%s)\n",othersigstr);
V.signers[isbob ^ 1].siglen = (int32_t)strlen(othersigstr) >> 1;
decode_hex(V.signers[isbob ^ 1].sig,V.signers[isbob ^ 1].siglen,othersigstr);
}
return(instantdex_bailinsign(coin,sharedprivs[0],sigstr,siglenp,txidp,&V,txobj,isbob));
}
/*
Name: Alice.Refund
vin0: A, Input source: Alice.Bail.In:0
vout0: A - fa, ScriptPubKey: OP_HASH160 Hash160(P2SH) OP_EQUAL; P2SH Redeem: pub-A3 OP_CHECKSIG
Locktime: current block height + ((T/2)/(altcoin block rate))
Name: Bob.Refund
vin0: B, Input source: Bob.Bail.In:0
vout0: B - fb, ScriptPubKey: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL; P2SH Redeem: pub-B3 OP_CHECKSIG
Locktime: (current block height) + (T / 10 minutes)
*/
char *instantdex_refundtx(struct iguana_info *coin,bits256 *txidp,bits256 bailinpriv,bits256 priv2,bits256 bailintxid,int64_t amount,int64_t txfee,int32_t isbob)
{
char sigstr[256]; int32_t siglen; struct vin_info V; cJSON *txobj;
txobj = instantdex_bailinspend(coin,priv2,amount - txfee);
bitcoin_addinput(coin,txobj,bailintxid,0,0xffffffff);
return(instantdex_bailinsign(coin,bailinpriv,sigstr,&siglen,txidp,&V,txobj,isbob));
}
int32_t instantdex_calcx20(char hexstr[41],uint8_t *p2shscript,uint8_t firstbyte,bits256 pub)
{
uint8_t pubkey[33],script[64],rmd160[20]; int32_t n; bits256 hash;
memcpy(pubkey+1,pub3.bytes,sizeof(pub3)), pubkey[0] = firstbyte;
uint8_t pubkey[33],rmd160[20]; int32_t n; bits256 hash;
memcpy(pubkey+1,pub.bytes,sizeof(pub)), pubkey[0] = firstbyte;
n = bitcoin_pubkeyspend(p2shscript,0,pubkey);
vcalc_sha256(0,hash.bytes,script,n);
vcalc_sha256(0,hash.bytes,p2shscript,n);
calc_rmd160(0,rmd160,hash.bytes,sizeof(hash.bytes));
init_hexbytes_noT(hexstr,rmd160,sizeof(rmd160));
return(n);
@ -134,17 +301,17 @@ int32_t instantdex_calcx20(char hexstr[41],uint8_t *p2shscript,uint8_t firstbyte
char *instantdex_btcoffer(struct supernet_info *myinfo,struct exchange_info *exchange,char *othercoin,double othervolume,double maxprice) // Bob sending to network (Alice)
{
char *str,coinaddr[64],xstr[41]; uint8_t xscript[64]; struct iguana_info *other;
struct instantdex_accept A; cJSON *newjson; bits256 hash,pub3;
char *str,coinaddr[64],xstr[41]; uint8_t xscript[64]; struct iguana_info *other; int32_t isbob = 1;
struct instantdex_accept A; cJSON *newjson; bits256 hash,pub3,sharedprivs[4];
if ( othercoin == 0 || (other= iguana_coinfind(othercoin)) == 0 )
return(clonestr("{\"error\":\"invalid othercoin\"}"));
hash = instantdex_acceptset(&A,othercoin,"BTC",INSTANTDEX_OFFERDURATION,1,-1,maxprice,othervolume,myinfo->myaddr.nxt64bits);
newjson = instantdex_acceptsendjson(&A);
if ( instantdex_pubkeyargs(newjson,4,myinfo->persistent_priv,hash,0x03) != 4 )
if ( instantdex_pubkeyargs(sharedprivs,newjson,4,myinfo->persistent_priv,hash,0x02+isbob) != 4 )
return(clonestr("{\"error\":\"highly unlikely run of 02 pubkeys\"}"));
pub3 = jbits256(newjson,"B3");
jdelete(newjson,"B3");
instantdex_calcx20(xstr,xscript,0x03,pub3);
instantdex_calcx20(xstr,xscript,0x02+isbob,pub3);
jaddstr(newjson,"x",xstr);
if ( coinaddr[0] != 0 )
jaddstr(newjson,othercoin,coinaddr);
@ -156,15 +323,87 @@ char *instantdex_btcoffer(struct supernet_info *myinfo,struct exchange_info *exc
return(instantdex_sendcmd(myinfo,newjson,"BTCoffer",myinfo->ipaddr,INSTANTDEX_HOPS));
}
void instantdex_pendingnotice(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,struct instantdex_accept *A)
{
printf("need to start monitoring thread\n");
ap->pendingvolume64 -= A->A.basevolume64;
}
cJSON *instantdex_newjson(struct supernet_info *myinfo,bits256 *A0p,bits256 *B0p,bits256 *sharedprivs,uint8_t secret160[20],int32_t isbob,cJSON *argjson,bits256 hash)
{
cJSON *newjson = cJSON_CreateObject(); char *xstr;
if ( instantdex_pubkeyargs(sharedprivs,newjson,3+isbob,myinfo->persistent_priv,hash,0x02+isbob) != 3 )
return(0);
if ( isbob == 0 )
*A0p = jbits256(newjson,"A0");
else *A0p = jbits256(argjson,"A0");
*B0p = jbits256(argjson,"B0");
if ( (xstr= jstr(argjson,"x")) != 0 )
{
decode_hex(secret160,20,xstr);
jaddstr(newjson,"x",xstr);
}
return(newjson);
}
char *instantdex_bailinrefund(struct supernet_info *myinfo,struct iguana_info *coin,struct exchange_info *exchange,struct instantdex_accept *A,char *nextcmd,uint8_t secret160[20],cJSON *newjson,int32_t isbob,bits256 A0,bits256 B0,bits256 *sharedprivs)
{
struct bitcoin_spend *spend; char *bailintx,*refundtx,field[64]; bits256 bailintxid,refundtxid;
if ( bits256_nonz(A0) > 0 && bits256_nonz(B0) > 0 )
{
if ( (spend= instantdex_spendset(myinfo,coin,A->A.basevolume64,INSTANTDEX_DONATION)) != 0 )
{
bailintx = instantdex_bailintx(coin,&bailintxid,spend,A0,B0,secret160,0);
refundtx = instantdex_refundtx(coin,&refundtxid,sharedprivs[0],sharedprivs[2],bailintxid,A->A.basevolume64,coin->chain->txfee,isbob);
if ( A->statusjson == 0 )
A->statusjson = cJSON_CreateObject();
sprintf(field,"bailin%c",'A'+isbob), jaddstr(A->statusjson,field,bailintx), free(bailintx);
sprintf(field,"refund%c",'A'+isbob), jaddstr(A->statusjson,field,refundtx), free(refundtx);
sprintf(field,"bailintx%c",'A'+isbob), jaddbits256(A->statusjson,field,bailintxid);
sprintf(field,"bailintxid%c",'A'+isbob), jaddbits256(newjson,field,bailintxid);
free(spend);
return(instantdex_sendcmd(myinfo,newjson,nextcmd,myinfo->ipaddr,INSTANTDEX_HOPS));
} else return(clonestr("{\"error\":\"couldnt create bailintx\"}"));
} else return(clonestr("{\"error\":\"dont have pubkey0 pair\"}"));
}
cJSON *instantdex_payout(struct supernet_info *myinfo,struct iguana_info *coin,struct exchange_info *exchange,struct instantdex_accept *A,uint8_t secret160[20],int32_t isbob,bits256 *A0p,bits256 *B0p,bits256 *sharedprivs,bits256 hash,uint64_t satoshis[2],cJSON *argjson)
{
cJSON *newjson; char field[32],payoutsigstr[256],*signedpayout; int32_t payoutsiglen; bits256 payouttxid,bailintxid;
if ( (newjson= instantdex_newjson(myinfo,A0p,B0p,sharedprivs,secret160,isbob,argjson,hash)) == 0 )
return(0);
sprintf(field,"bailintxid%c",'A' + (isbob^1)), bailintxid = jbits256(argjson,field);
sprintf(field,"payoutsig%c",'A' + (isbob^1));
if ( (signedpayout= instantdex_payouttx(coin,payoutsigstr,&payoutsiglen,&payouttxid,sharedprivs,bailintxid,satoshis[isbob],coin->chain->txfee,isbob,jstr(argjson,field))) != 0 )
{
sprintf(field,"payoutsig%c",'A'+isbob), jaddstr(newjson,field,payoutsigstr);
if ( A->statusjson == 0 )
A->statusjson = cJSON_CreateObject();
sprintf(field,"payout%c",'A'+isbob), jaddstr(A->statusjson,field,signedpayout);
free(signedpayout);
}
return(newjson);
}
char *instantdex_advance(struct supernet_info *myinfo,bits256 *sharedprivs,int32_t isbob,cJSON *argjson,bits256 hash,char *addfield,char *nextstate,struct instantdex_accept *A)
{
cJSON *newjson; bits256 A0,B0; uint8_t secret160[20];
if ( (newjson= instantdex_newjson(myinfo,&A0,&B0,sharedprivs,secret160,isbob,argjson,hash)) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}"));
if ( A->statusjson != 0 && jstr(A->statusjson,addfield) != 0 )
{
jaddstr(newjson,addfield,jstr(A->statusjson,addfield));
if ( nextstate != 0 )
return(instantdex_sendcmd(myinfo,newjson,nextstate,myinfo->ipaddr,INSTANTDEX_HOPS));
else return(clonestr("{\"result\":\"instantdex_BTCswap advance complete, wait or refund\"}"));
} else return(clonestr("{\"error\":\"instantdex_BTCswap advance cant find statusjson\"}"));
}
char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
{
uint8_t script[999],p2sh_rmd160[20],secret160[20],pubkey[36],addrtype;
bits256 hash,bailintxid,A0,B0; struct bitcoin_spend SPEND;
struct instantdex_accept *ap; uint64_t satoshis,othersatoshis,orderid;
char p2sh_coinaddr[64],*senderaddr,otheraddr[64],base[24],coinaddr[64],*retstr,*bailintx;
int32_t scriptlen,locktime,offerdir = 0; struct iguana_info *coinbtc,*other; cJSON *newjson;
retstr = 0;
memset(&SPEND,0,sizeof(SPEND));
uint8_t secret160[20]; bits256 hash,A0,B0,sharedprivs[4]; uint64_t satoshis[2]; cJSON *newjson;
struct instantdex_accept *ap; char *retstr=0,*str;
int32_t locktime,isbob=0,offerdir = 0; struct iguana_info *coinbtc,*other;
if ( exchange == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}"));
offerdir = instantdex_bidaskdir(A);
@ -173,84 +412,69 @@ char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exch
locktime = (uint32_t)(A->A.expiration + INSTANTDEX_OFFERDURATION);
if ( A->A.rel == 0 || strcmp(A->A.rel,"BTC") != 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}"));
vcalc_sha256(0,hash.bytes,(void *)&A->A,sizeof(ap->A));
if ( hash.txid != A->orderid )
return(clonestr("{\"error\":\"txid mismatches orderid\"}"));
satoshis[0] = A->A.basevolume64;
satoshis[1] = instantdex_relsatoshis(A->A.price64,A->A.basevolume64);
printf("got offer.(%s) offerside.%d offerdir.%d\n",jprint(argjson,0),A->A.myside,A->A.acceptdir);
if ( strcmp(cmdstr,"offer") == 0 ) // sender is Bob, receiver is network (Alice)
{
// should add to orderbook if not accepted
if ( A->A.expiration < (time(NULL) + INSTANTDEX_DURATION) )
return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}"));
printf("got offer.(%s) offerside.%d offerdir.%d\n",jprint(argjson,0),A->A.myside,A->A.acceptdir);
if ( (ap= instantdex_acceptable(exchange,A,myinfo->myaddr.nxt64bits)) != 0 )
{
ap->pendingvolume64 -= A->A.basevolume64;
satoshis = instantdex_relsatoshis(A->A.price64,A->A.basevolume64);
newjson = cJSON_CreateObject();
if ( instantdex_pubkeyargs(argjson,3,myinfo->persistent_priv,hash,0x02) != 3 )
return(clonestr("{\"error\":\"highly unlikely run of 03 pubkeys\"}"));
jadd64bits(newjson,"id",A->orderid);
jadd64bits(newjson,"BTC",satoshis);
jadd64bits(newjson,"v",A->A.basevolume64);
jaddstr(newjson,"b",other->symbol);
jaddstr(newjson,other->symbol,otheraddr);
jaddstr(newjson,"p2sh",p2sh_coinaddr);
bailintx = instantdex_bailintx(coinbtc,&bailintxid,&SPEND,A0,B0,secret160,1);
jaddstr(newjson,"bailin",bailintx);
jaddbits256(newjson,"bailintxid",bailintxid);
free(bailintx);
return(instantdex_sendcmd(myinfo,newjson,"proposal",myinfo->ipaddr,INSTANTDEX_HOPS));
} else printf("no matching trade.(%s)\n",jprint(argjson,0));
}
else if ( strcmp(cmdstr,"proposal") == 0 ) // sender is Alice, receiver is Bob
{
satoshis = j64bits(argjson,"BTC");
orderid = j64bits(argjson,"id");
othersatoshis = j64bits(argjson,"v");
senderaddr = myinfo->myaddr.BTC;
if ( jobj(argjson,other->symbol) != 0 )
safecopy(otheraddr,jstr(argjson,other->symbol),sizeof(otheraddr));
if ( jobj(argjson,"b") != 0 )
safecopy(base,jstr(argjson,"b"),sizeof(base));
printf("proposal orderid.%llu BTC satoshis %.8f for %s vol %.8f ps2h.%s\n",A->orderid,dstr(satoshis),base,dstr(othersatoshis),p2sh_coinaddr);
if ( A->orderid != orderid )
{
printf("orderid mismatch %llu vs %llu\n",(long long)orderid,(long long)A->orderid);
return(clonestr("{\"error\":\"instantdex_BTCswap orderid mismatch\"}"));
}
if ( senderaddr == 0 || strcmp(A->A.base,base) != 0 || strcmp(A->A.rel,"BTC") != 0 )
{
printf("senderaddr.%p base.(%s vs %s) rel.(%s vs %s)\n",senderaddr,A->A.base,base,A->A.rel,"BTC");
return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}"));
}
bitcoin_pubkey33(pubkey,myinfo->persistent_priv);
bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey));
bitcoin_addr2rmd160(&addrtype,secret160,coinaddr);
scriptlen = bitcoin_cltvscript(coinbtc->chain->p2shtype,p2sh_coinaddr,p2sh_rmd160,script,0,senderaddr,otheraddr,secret160,locktime);
if ( jobj(argjson,"p2sh") != 0 )
{
if ( strcmp(jstr(argjson,"p2sh"),p2sh_coinaddr) != 0 )
isbob = 0;
if ( (newjson= instantdex_newjson(myinfo,&A0,&B0,sharedprivs,secret160,isbob,argjson,hash)) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}"));
else
{
printf("mismatched p2sh.(%s) vs (%s)\n",jstr(argjson,"p2sh"),p2sh_coinaddr);
return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}"));
// should add to orderbook if not accepted
instantdex_pendingnotice(myinfo,exchange,ap,A);
return(instantdex_bailinrefund(myinfo,other,exchange,A,"proposal",secret160,newjson,isbob,A0,B0,sharedprivs));
}
}
if ( satoshis != instantdex_relsatoshis(A->A.price64,A->A.basevolume64) )
{
printf("satoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)instantdex_relsatoshis(A->A.price64,A->A.basevolume64));
return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}"));
}
if ( othersatoshis != A->A.basevolume64 )
else
{
printf("othersatoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)A->A.basevolume64);
return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}"));
printf("no matching trade.(%s)\n",jprint(argjson,0));
if ( (str= InstantDEX_minaccept(myinfo,0,argjson,0,A->A.base,"BTC",dstr(A->A.price64),dstr(A->A.basevolume64))) != 0 )
free(str);
}
// return(instantdex_sendcmd(myinfo,newjson,"accept",myinfo->ipaddr,INSTANTDEX_HOPS));
}
else if ( strcmp(cmdstr,"proposal") == 0 ) // sender is Alice, receiver is Bob
{
isbob = 1;
newjson = instantdex_payout(myinfo,coinbtc,exchange,A,secret160,isbob,&A0,&B0,sharedprivs,hash,satoshis,argjson);
return(instantdex_bailinrefund(myinfo,coinbtc,exchange,A,"BTCaccept",secret160,newjson,isbob,A0,B0,sharedprivs));
}
else if ( strcmp(cmdstr,"accept") == 0 ) // sender is Bob, receiver is Alice
{
isbob = 0;
newjson = instantdex_payout(myinfo,other,exchange,A,secret160,isbob,&A0,&B0,sharedprivs,hash,satoshis,argjson);
return(instantdex_sendcmd(myinfo,newjson,"BTCconfirm",myinfo->ipaddr,INSTANTDEX_HOPS));
}
else if ( strcmp(cmdstr,"confirm") == 0 ) // sender is Alice, receiver is Bob
{
isbob = 1;
newjson = instantdex_payout(myinfo,coinbtc,exchange,A,secret160,isbob,&A0,&B0,sharedprivs,hash,satoshis,argjson);
return(instantdex_sendcmd(myinfo,newjson,"BTCbroadcast",myinfo->ipaddr,INSTANTDEX_HOPS));
}
else if ( strcmp(cmdstr,"broadcast") == 0 ) // sender is Bob, receiver is Alice
{
isbob = 0;
return(instantdex_advance(myinfo,sharedprivs,isbob,argjson,hash,"bailintxA","BTCcommit",A));
}
else if ( strcmp(cmdstr,"commit") == 0 ) // sender is Alice, receiver is Bob
{
isbob = 1;
// go into refund state, ie watch for payouts to complete or get refund
return(instantdex_advance(myinfo,sharedprivs,isbob,argjson,hash,"payoutB","BTCcomplete",A));
}
else if ( strcmp(cmdstr,"confirm") == 0 ) // both send and receive
else if ( strcmp(cmdstr,"complete") == 0 ) // sender is Bob, receiver is Alice
{
isbob = 0;
// go into refund state, ie watch for payouts to complete or get refund
return(instantdex_advance(myinfo,sharedprivs,isbob,argjson,hash,"payoutA",0,A));
}
else retstr = clonestr("{\"error\":\"BTC swap got unrecognized command\"}");
if ( retstr == 0 )

Loading…
Cancel
Save