jl777 7 years ago
parent
commit
02fcf328ac
  1. 2
      iguana/exchanges/LP_include.h
  2. 2
      iguana/exchanges/LP_nativeDEX.c
  3. 230
      iguana/exchanges/LP_signatures.c

2
iguana/exchanges/LP_include.h

@ -286,7 +286,7 @@ struct LP_pubkeyinfo
}; };
int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item); int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item);
int32_t LP_pubkey_sigadd(cJSON *item,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp); int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp);
void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,uint8_t *data,int32_t datalen,int32_t vout); void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,uint8_t *data,int32_t datalen,int32_t vout);
void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx); void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx);
uint32_t basilisk_requestid(struct basilisk_request *rp); uint32_t basilisk_requestid(struct basilisk_request *rp);

2
iguana/exchanges/LP_nativeDEX.c

@ -19,7 +19,7 @@
// marketmaker // marketmaker
// //
// process stats.log local file -> map of realtime activity! // process stats.log local file -> map of realtime activity!
// sign price // serialize sighash functions
// select oldest utxo first // select oldest utxo first
// handles <-> pubkeys, deal with offline pubkeys, reputations, bonds etc. // handles <-> pubkeys, deal with offline pubkeys, reputations, bonds etc.
// //

230
iguana/exchanges/LP_signatures.c

@ -181,9 +181,106 @@ char *LP_quotereceived(cJSON *argjson)
} else return(clonestr("{\"error\":\"nullptr\"}")); } else return(clonestr("{\"error\":\"nullptr\"}"));
} }
int32_t LP_bitcoinsig_add(cJSON *item,bits256 priv,uint8_t *pubsecp,bits256 sighash)
{
static void *ctx; int32_t i,j,siglen; uint8_t pub33[33],sig[65]; char sigstr[128];
if ( ctx == 0 )
ctx = bitcoin_ctx();
for (j=0; j<100; j++)
{
if ( (siglen= bitcoin_sign(ctx,"sigadd",sig,sighash,priv,1)) > 0 && siglen == 65 )
{
memset(pub33,0,33);
if ( bitcoin_recoververify(ctx,"test",sig,sighash,pub33,0) == 0 && memcmp(pub33,pubsecp,33) == 0 )
{
init_hexbytes_noT(sigstr,sig,siglen);
jaddstr(item,"sig",sigstr);
return(siglen);
}
if ( 0 )
{
for (i=0; i<33; i++)
printf("%02x",pubsecp[i]);
printf(" pubsecp -> ");
for (i=0; i<33; i++)
printf("%02x",pub33[i]);
printf(" mismatched recovered pubkey.%d of %d\n",j,100);
}
}
}
return(-1);
}
bits256 LP_price_sighash(uint32_t timestamp,uint8_t *pubsecp,bits256 pubkey,char *base,char *rel,uint64_t price64)
{
uint8_t buf[sizeof(pubkey) + 33 + sizeof(uint64_t)*3 + sizeof(timestamp)]; uint64_t basebits,relbits; bits256 sighash;
basebits = stringbits(base);
relbits = stringbits(rel);
memcpy(buf,pubkey.bytes,sizeof(pubkey));
memcpy(&buf[sizeof(pubkey)],pubsecp,33);
memcpy(&buf[sizeof(pubkey)+33],&price64,sizeof(price64));
memcpy(&buf[sizeof(pubkey)+33+sizeof(price64)],&basebits,sizeof(basebits));
memcpy(&buf[sizeof(pubkey)+33+sizeof(price64)+sizeof(basebits)],&relbits,sizeof(relbits));
memcpy(&buf[sizeof(pubkey)+33+sizeof(price64)+sizeof(basebits)+sizeof(relbits)],&timestamp,sizeof(timestamp));
vcalc_sha256(0,sighash.bytes,buf,sizeof(buf));
return(sighash);
}
bits256 LP_pubkey_sighash(uint32_t timestamp,bits256 pubkey,uint8_t *rmd160,uint8_t *pubsecp)
{
uint8_t buf[sizeof(pubkey) + 20 + 33 + sizeof(timestamp)]; bits256 sighash;
memcpy(buf,pubkey.bytes,sizeof(pubkey));
memcpy(&buf[sizeof(pubkey)],rmd160,20);
memcpy(&buf[sizeof(pubkey)+20],pubsecp,33);
memcpy(&buf[sizeof(pubkey)+20+33],&timestamp,sizeof(timestamp));
vcalc_sha256(0,sighash.bytes,buf,sizeof(buf));
return(sighash);
}
bits256 LP_utxos_sighash(uint32_t timestamp,uint8_t *pubsecp,bits256 pubkey,char *msg)
{
uint8_t *buf; bits256 sighash; int32_t len;
len = (int32_t)strlen(msg) + sizeof(pubkey)+33+sizeof(timestamp);
buf = malloc(len+1);
memcpy(buf,pubkey.bytes,sizeof(pubkey));
memcpy(&buf[sizeof(pubkey)],pubsecp,33);
memcpy(&buf[sizeof(pubkey)+33],&timestamp,sizeof(timestamp));
strcpy((char *)&buf[sizeof(pubkey)+33+sizeof(timestamp)],msg);
vcalc_sha256(0,sighash.bytes,buf,len);
free(buf);
return(sighash);
}
int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *msg)
{
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( sigstr != 0 && pubsecpstr != 0 && strlen(sigstr) == 65*2 && strlen(pubsecpstr) == 33 *2 )
{
decode_hex(sig,65,sigstr);
decode_hex(pubsecp,33,pubsecpstr);
sighash = LP_utxos_sighash(timestamp,pubsecp,pubkey,msg);
retval = bitcoin_recoververify(ctx,"price",sig,sighash,pub33,0);
if ( memcmp(pub33,pubsecp,33) != 0 || retval != 0 )
{
printf("LP_utxos_sigcheck failure\n");
retval = -1;
} else retval = 0;
}
return(retval);
}
int32_t LP_utxos_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pubsecp,bits256 pubkey,char *msg)
{
bits256 sighash;
sighash = LP_utxos_sighash(timestamp,pubsecp,pubkey,msg);
return(LP_bitcoinsig_add(item,priv,pubsecp,sighash));
}
void LP_postutxos(char *symbol,char *coinaddr) void LP_postutxos(char *symbol,char *coinaddr)
{ {
bits256 zero; struct iguana_info *coin; cJSON *array,*reqjson = cJSON_CreateObject(); bits256 zero; uint32_t timestamp; char *msg,pubsecpstr[67]; struct iguana_info *coin; cJSON *array,*reqjson = cJSON_CreateObject();
if ( (coin= LP_coinfind(symbol)) != 0 && (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) if ( (coin= LP_coinfind(symbol)) != 0 && (array= LP_address_utxos(coin,coinaddr,1)) != 0 )
{ {
//printf("LP_postutxos pubsock.%d %s %s\n",pubsock,symbol,coin->smartaddr); //printf("LP_postutxos pubsock.%d %s %s\n",pubsock,symbol,coin->smartaddr);
@ -196,6 +293,14 @@ void LP_postutxos(char *symbol,char *coinaddr)
jaddstr(reqjson,"coin",symbol); jaddstr(reqjson,"coin",symbol);
jaddstr(reqjson,"coinaddr",coinaddr); jaddstr(reqjson,"coinaddr",coinaddr);
jadd(reqjson,"utxos",array); jadd(reqjson,"utxos",array);
timestamp = (uint32_t)time(NULL);
jaddnum(reqjson,"timetamp",timestamp);
init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33);
jaddstr(reqjson,"pubsecp",pubsecpstr);
jaddbits256(reqjson,"pubkey",G.LP_mypub25519);
msg = jprint(array,0);
LP_utxos_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,msg);
free(msg);
//printf("post (%s) -> %d\n",msg,LP_mypubsock); //printf("post (%s) -> %d\n",msg,LP_mypubsock);
LP_reserved_msg(symbol,symbol,zero,jprint(reqjson,1)); LP_reserved_msg(symbol,symbol,zero,jprint(reqjson,1));
} }
@ -207,11 +312,21 @@ struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; };
char *LP_postutxos_recv(cJSON *argjson) char *LP_postutxos_recv(cJSON *argjson)
{ {
struct LP_utxos_qitem *uitem; struct LP_utxos_qitem *uitem; char *msg; cJSON *obj;
uitem = calloc(1,sizeof(*uitem)); if ( (obj= jobj(argjson,"utxos")) != 0 )
uitem->argjson = jduplicate(argjson); {
queue_enqueue("utxosQ",&utxosQ,&uitem->DL); msg = jprint(obj,0);
return(clonestr("{\"result\":\"success\"}")); if ( LP_utxos_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),jbits256(argjson,"pubkey"),msg) == 0 )
{
free(msg);
uitem = calloc(1,sizeof(*uitem));
uitem->argjson = jduplicate(argjson);
queue_enqueue("utxosQ",&utxosQ,&uitem->DL);
return(clonestr("{\"result\":\"success\"}"));
}
free(msg);
}
return(clonestr("{\"error\":\"sig failure\"}"));
} }
int32_t LP_utxosQ_process() int32_t LP_utxosQ_process()
@ -237,9 +352,36 @@ int32_t LP_utxosQ_process()
return(0); return(0);
} }
int32_t LP_price_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *base,char *rel,uint64_t price64)
{
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( sigstr != 0 && pubsecpstr != 0 && strlen(sigstr) == 65*2 && strlen(pubsecpstr) == 33 *2 )
{
decode_hex(sig,65,sigstr);
decode_hex(pubsecp,33,pubsecpstr);
sighash = LP_price_sighash(timestamp,pubsecp,pubkey,base,rel,price64);
retval = bitcoin_recoververify(ctx,"price",sig,sighash,pub33,0);
if ( memcmp(pub33,pubsecp,33) != 0 || retval != 0 )
{
printf("LP_price_sigcheck failure\n");
retval = -1;
} else retval = 0;
}
return(retval);
}
int32_t LP_price_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pubsecp,bits256 pubkey,char *base,char *rel,uint64_t price64)
{
bits256 sighash;
sighash = LP_price_sighash(timestamp,pubsecp,pubkey,base,rel,price64);
return(LP_bitcoinsig_add(item,priv,pubsecp,sighash));
}
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price)
{ {
struct iguana_info *basecoin,*relcoin; bits256 zero; cJSON *reqjson = cJSON_CreateObject(); struct iguana_info *basecoin,*relcoin; char pubsecpstr[67]; uint32_t timestamp; uint64_t price64; bits256 zero; cJSON *reqjson = cJSON_CreateObject();
// LP_addsig // LP_addsig
if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 && relcoin->electrum == 0 ) if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 && relcoin->electrum == 0 )
{ {
@ -247,8 +389,15 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re
jaddbits256(reqjson,"pubkey",G.LP_mypub25519); jaddbits256(reqjson,"pubkey",G.LP_mypub25519);
jaddstr(reqjson,"base",base); jaddstr(reqjson,"base",base);
jaddstr(reqjson,"rel",rel); jaddstr(reqjson,"rel",rel);
price64 = price * SATOSHIDEN + 0.0000000049;
jaddnum(reqjson,"price",price); jaddnum(reqjson,"price",price);
jadd64bits(reqjson,"price64",price64);
jaddstr(reqjson,"method","postprice"); jaddstr(reqjson,"method","postprice");
timestamp = (uint32_t)time(NULL);
jaddnum(reqjson,"timestamp",timestamp);
init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33);
jaddstr(reqjson,"pubsecp",pubsecpstr);
LP_price_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,base,rel,price64);
LP_reserved_msg(base,rel,zero,jprint(reqjson,1)); LP_reserved_msg(base,rel,zero,jprint(reqjson,1));
return(clonestr("{\"result\":\"success\"}")); return(clonestr("{\"result\":\"success\"}"));
} else return(clonestr("{\"error\":\"electrum node cant post bob asks\"}")); } else return(clonestr("{\"error\":\"electrum node cant post bob asks\"}"));
@ -263,62 +412,30 @@ char *LP_postprice_recv(cJSON *argjson)
pubkey = jbits256(argjson,"pubkey"); pubkey = jbits256(argjson,"pubkey");
if ( bits256_nonz(pubkey) != 0 ) if ( bits256_nonz(pubkey) != 0 )
{ {
LP_pricefeedupdate(pubkey,base,rel,price); if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 )
return(clonestr("{\"result\":\"success\"}")); {
LP_pricefeedupdate(pubkey,base,rel,price);
return(clonestr("{\"result\":\"success\"}"));
} else return(clonestr("{\"error\":\"sig failure\"}"));
} }
} }
return(clonestr("{\"error\":\"missing fields in posted price\"}")); return(clonestr("{\"error\":\"missing fields in posted price\"}"));
} }
bits256 LP_pubkey_sighash(bits256 pub,uint8_t *rmd160,uint8_t *pubsecp) int32_t _LP_pubkey_sigcheck(uint8_t *sig,int32_t siglen,uint32_t timestamp,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp)
{
uint8_t buf[sizeof(pub) + 20 + 33]; bits256 sighash;
memcpy(buf,pub.bytes,sizeof(pub));
memcpy(&buf[sizeof(pub)],rmd160,20);
memcpy(&buf[sizeof(pub)+20],pubsecp,33);
vcalc_sha256(0,sighash.bytes,buf,sizeof(buf));
return(sighash);
}
int32_t _LP_pubkey_sigcheck(uint8_t *sig,int32_t siglen,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp)
{ {
static void *ctx; static void *ctx; uint8_t pub33[33]; bits256 sighash;
uint8_t pub33[33]; bits256 sighash = LP_pubkey_sighash(pub,rmd160,pubsecp);
if ( ctx == 0 ) if ( ctx == 0 )
ctx = bitcoin_ctx(); ctx = bitcoin_ctx();
return(bitcoin_recoververify(ctx,"sigcheck",sig,sighash,pub33,0)); sighash = LP_pubkey_sighash(timestamp,pub,rmd160,pubsecp);
return(bitcoin_recoververify(ctx,"pubkey",sig,sighash,pub33,0));
} }
int32_t LP_pubkey_sigadd(cJSON *item,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp) int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp)
{ {
static void *ctx; bits256 sighash;
uint8_t sig[128],pub33[33]; int32_t i,j,siglen=0; bits256 sighash; char sigstr[256]; sighash = LP_pubkey_sighash(timestamp,pub,rmd160,pubsecp);
sighash = LP_pubkey_sighash(pub,rmd160,pubsecp); return(LP_bitcoinsig_add(item,priv,pubsecp,sighash));
if ( ctx == 0 )
ctx = bitcoin_ctx();
for (j=0; j<100; j++)
{
if ( (siglen= bitcoin_sign(ctx,"sigadd",sig,sighash,priv,1)) > 0 && siglen == 65 )
{
memset(pub33,0,33);
if ( bitcoin_recoververify(ctx,"test",sig,sighash,pub33,0) == 0 && memcmp(pub33,pubsecp,33) == 0 )
{
init_hexbytes_noT(sigstr,sig,siglen);
jaddstr(item,"sig",sigstr);
return(siglen);
}
if ( 0 )
{
for (i=0; i<33; i++)
printf("%02x",pubsecp[i]);
printf(" pubsecp -> ");
for (i=0; i<33; i++)
printf("%02x",pub33[i]);
printf(" mismatched recovered pubkey.%d of %d\n",j,100);
}
}
}
return(0);
} }
int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item) int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item)
@ -342,7 +459,7 @@ int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item)
{ {
siglen = len >> 1; siglen = len >> 1;
decode_hex(sig,siglen,sigstr); decode_hex(sig,siglen,sigstr);
if ( _LP_pubkey_sigcheck(sig,siglen,pubp->pubkey,rmd160,pubsecp) == 0 ) if ( _LP_pubkey_sigcheck(sig,siglen,juint(item,"timestamp"),pubp->pubkey,rmd160,pubsecp) == 0 )
{ {
for (i=0; i<20; i++) for (i=0; i<20; i++)
printf("%02x",pubp->rmd160[i]); printf("%02x",pubp->rmd160[i]);
@ -374,15 +491,16 @@ int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item)
void LP_notify_pubkeys(void *ctx,int32_t pubsock) void LP_notify_pubkeys(void *ctx,int32_t pubsock)
{ {
bits256 zero; char secpstr[67]; cJSON *reqjson = cJSON_CreateObject(); bits256 zero; uint32_t timestamp; char secpstr[67]; cJSON *reqjson = cJSON_CreateObject();
// LP_addsig
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
jaddstr(reqjson,"method","notify"); jaddstr(reqjson,"method","notify");
jaddstr(reqjson,"rmd160",G.LP_myrmd160str); jaddstr(reqjson,"rmd160",G.LP_myrmd160str);
jaddbits256(reqjson,"pub",G.LP_mypub25519); jaddbits256(reqjson,"pub",G.LP_mypub25519);
init_hexbytes_noT(secpstr,G.LP_pubsecp,33); init_hexbytes_noT(secpstr,G.LP_pubsecp,33);
jaddstr(reqjson,"pubsecp",secpstr); jaddstr(reqjson,"pubsecp",secpstr);
LP_pubkey_sigadd(reqjson,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); timestamp = (uint32_t)time(NULL);
jaddnum(reqjson,"timestamp",timestamp);
LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp);
LP_reserved_msg("","",zero,jprint(reqjson,1)); LP_reserved_msg("","",zero,jprint(reqjson,1));
} }

Loading…
Cancel
Save