You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

186 lines
7.7 KiB

/******************************************************************************
* Copyright © 2014-2017 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. *
* *
******************************************************************************/
//
// LP_secp.c
// marketmaker
//
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "../../includes/curve25519.h"
#include "../secp256k1/include/secp256k1.h"
#include "../secp256k1/include/secp256k1_ecdh.h"
#include "../secp256k1/include/secp256k1_schnorr.h"
#include "../secp256k1/include/secp256k1_rangeproof.h"
#include "../secp256k1/include/secp256k1_recovery.h"
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0)
#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);
void *bitcoin_ctx()
{
void *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(ctx);
secp256k1_rangeproof_context_initialize(ctx);
return(ctx);
}
bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey)
{
size_t plen; bits256 pubkey; secp256k1_pubkey secppub;
memset(pubkey.bytes,0,sizeof(pubkey));
SECP_ENSURE_CTX
{
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 )
{
//printf("bitcoin_sign illegal privkey\n");
return(pubkey);
}
if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 )
{
plen = 33;
secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED);
if ( plen == 33 )
memcpy(pubkey.bytes,data+1,sizeof(pubkey));
}
ENDSECP_ENSURE_CTX
}
return(pubkey);
}
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even)
{
bits256 pub256; uint8_t pubkey[33]; int32_t i;
for (i=0; i<100; i++)
{
*privkeyp = rand256(0);
pub256 = bitcoin_pubkey33(ctx,pubkey,*privkeyp);
if ( pubkey[0] == odd_even+2 )
return(pub256);
}
printf("bitcoin_pub256 couldnt generate pubkey.%d\n",odd_even+2);
memset(pub256.bytes,0,sizeof(pub256));
return(pub256);
}
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag)
{
int32_t fCompressed = 1;
secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB;
seed = rand256(0);
extra_entropy = rand256(0);
SECP_ENSURE_CTX
{
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 )
{
//printf("bitcoin_sign illegal privkey\n");
return(-1);
}
if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 )
{
if ( recoverflag != 0 )
{
if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
{
recid = -1;
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG);
if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) != 0 )
{
if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) != 0 )
{
if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 )
{
sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0);
retval = 64 + 1;
//size_t i,plen = 33; uint8_t pubkey[33];
//secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&CHECKPUB,SECP256K1_EC_COMPRESSED);
//for (i=0; i<33; i++)
// printf("%02x",pubkey[i]);
//printf(" bitcoin_sign's pubkey\n");
} //else printf("secpub mismatch\n");
} else printf("pubkey create error\n");
} //else printf("recover error\n");
} else printf("secp256k1_ecdsa_sign_recoverable error\n");
}
else
{
if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
{
if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 )
retval = (int32_t)siglen;
}
}
}
ENDSECP_ENSURE_CTX
}
return(retval);
}
int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen)
{
int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG;
pubkey[0] = 0;
SECP_ENSURE_CTX
{
if ( plen == 0 )
{
plen = (sig[0] <= 31) ? 65 : 33;
sig++;
}
secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig,0);
secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG);
if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 )
{
plen = 33;
memset(pubkey,0,33);
secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);//plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED);
if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 )
{
retval = 0;
/*if ( pubkey[0] == 4 ) // experimentally looks like 04 is set
pubkey[0] = 2;
else if ( pubkey[0] != 2 )
pubkey[0] = 3;*/
} else printf("secp256k1_ecdsa_verify error\n");
} else printf("secp256k1_ecdsa_recover error\n");
ENDSECP_ENSURE_CTX
}
return(retval);
}
int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen)
{
int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG;
SECP_ENSURE_CTX
{
if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 )
{
secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen);
if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) != 0 )
retval = 0;
}
ENDSECP_ENSURE_CTX
}
return(retval);
}