Merge pull request #1283 from jl777/jl777

update with latest rogue fixes, musig support and dilithium initial version
This commit is contained in:
jl777
2019-02-25 03:49:28 -11:00
committed by GitHub
29 changed files with 4907 additions and 253 deletions

View File

@@ -32,9 +32,9 @@ build:ubuntu:
variables:
DOCKER_DRIVER: overlay2
cache:
key: "${CI_JOB_NAME}${CI_COMMIT_REF_NAME}"
key: ${CI_COMMIT_REF_SLUG}
paths:
- depends/built
- depends/
script:
- zcutil/build.sh -j$(nproc)
- mkdir ${PACKAGE_DIR_LINUX}

View File

@@ -884,6 +884,7 @@ fi
AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin])
AM_CONDITIONAL([TARGET_LINUX], [test x$TARGET_OS = xlinux])
AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes])
AM_CONDITIONAL([ENABLE_MINING],[test x$enable_mining = xyes])

View File

@@ -1,8 +1,8 @@
package=boost
$(package)_version=1_69_0
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.69.0/source
$(package)_version=1_66_0
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.66.0/source
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
$(package)_sha256_hash=8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406
$(package)_sha256_hash=5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9
define $(package)_set_vars
$(package)_config_opts_release=variant=release

View File

@@ -36,7 +36,8 @@ LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl
endif
if TARGET_DARWIN
LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl
else
endif
if TARGET_LINUX
LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl
endif
@@ -578,7 +579,8 @@ komodod_LDADD += libcc.dylib $(LIBSECP256K1)
endif
if TARGET_WINDOWS
komodod_LDADD += libcc.dll $(LIBSECP256K1)
else
endif
if TARGET_LINUX
komodod_LDADD += libcc.so $(LIBSECP256K1)
endif

View File

@@ -224,5 +224,21 @@
"addnode": [
"37.187.225.231"
]
}
},
{
"ac_name": "OUR",
"ac_reward": "1478310502",
"ac_halving": "525600",
"ac_cc": "42",
"ac_supply": "100000000",
"ac_perc": "77700",
"ac_staked": "93",
"ac_pubkey": "02652a3f3e00b3a1875a918314f0bac838d6dd189a346fa623f5efe9541ac0b98c",
"ac_public": "1",
"addnode": [
"51.255.195.65",
"217.182.129.38",
"95.216.150.177"
]
}
]

View File

@@ -37,6 +37,7 @@ std::string MYCCLIBNAME = (char *)"rogue";
#define EVAL_SUDOKU 17
#define EVAL_MUSIG 18
#define EVAL_DILITHIUM 19
std::string MYCCLIBNAME = (char *)"sudoku";
#endif
@@ -72,15 +73,20 @@ CClib_methods[] =
{ (char *)"sudoku", (char *)"pending", (char *)"<no args>", 0, 0, 'U', EVAL_SUDOKU },
{ (char *)"sudoku", (char *)"solution", (char *)"txid solution timestamps[81]", 83, 83, 'S', EVAL_SUDOKU },
{ (char *)"musig", (char *)"calcmsg", (char *)"sendtxid scriptPubKey", 2, 2, 'C', EVAL_MUSIG },
{ (char *)"musig", (char *)"combine", (char *)"pubkeys ...", 2, 256, 'P', EVAL_MUSIG },
{ (char *)"musig", (char *)"session", (char *)"msg pkhash", 2, 2, 'R', EVAL_MUSIG },
{ (char *)"musig", (char *)"commit", (char *)"pubkeys ...", 2, 256, 'H', EVAL_MUSIG },
{ (char *)"musig", (char *)"nonce", (char *)"pubkeys ...", 2, 256, 'N', EVAL_MUSIG },
{ (char *)"musig", (char *)"partialsign", (char *)"pubkeys ...", 2, 256, 'S', EVAL_MUSIG },
{ (char *)"musig", (char *)"sigcombine", (char *)"pubkeys ...", 2, 256, 'M', EVAL_MUSIG },
{ (char *)"musig", (char *)"combine", (char *)"pubkeys ...", 2, 999999999, 'P', EVAL_MUSIG },
{ (char *)"musig", (char *)"session", (char *)"myindex,numsigners,combined_pk,pkhash,msg32", 5, 5, 'R', EVAL_MUSIG },
{ (char *)"musig", (char *)"commit", (char *)"pkhash,ind,commitment", 3, 3, 'H', EVAL_MUSIG },
{ (char *)"musig", (char *)"nonce", (char *)"pkhash,ind,nonce", 3, 3, 'N', EVAL_MUSIG },
{ (char *)"musig", (char *)"partialsig", (char *)"pkhash,ind,partialsig", 3, 3, 'S', EVAL_MUSIG },
{ (char *)"musig", (char *)"verify", (char *)"msg sig pubkey", 3, 3, 'V', EVAL_MUSIG },
{ (char *)"musig", (char *)"send", (char *)"combined_pk amount", 2, 2, 'x', EVAL_MUSIG },
{ (char *)"musig", (char *)"spend", (char *)"sendtxid sig destpubkey", 3, 3, 'y', EVAL_MUSIG },
{ (char *)"musig", (char *)"spend", (char *)"sendtxid sig scriptPubKey", 3, 3, 'y', EVAL_MUSIG },
{ (char *)"dilithium", (char *)"keypair", (char *)"[hexseed]", 0, 1, 'K', EVAL_DILITHIUM },
{ (char *)"dilithium", (char *)"register", (char *)"handle, [hexseed]", 1, 2, 'R', EVAL_DILITHIUM },
{ (char *)"dilithium", (char *)"sign", (char *)"msg [hexseed]", 1, 2, 'S', EVAL_DILITHIUM },
{ (char *)"dilithium", (char *)"verify", (char *)"pubtxid msg sig", 3, 3, 'V', EVAL_DILITHIUM },
{ (char *)"dilithium", (char *)"send", (char *)"handle pubtxid amount", 3, 3, 'x', EVAL_DILITHIUM },
{ (char *)"dilithium", (char *)"spend", (char *)"sendtxid scriptPubKey [hexseed]", 2, 3, 'y', EVAL_DILITHIUM },
#endif
};
@@ -116,11 +122,19 @@ UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_partialsign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_sigcombine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx);
UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue dilithium_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
#endif
cJSON *cclib_reparse(int32_t *nump,char *jsonstr) // assumes origparams will be freed by caller
@@ -229,10 +243,8 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
return(musig_commit(txfee,cp,params));
else if ( strcmp(method,"nonce") == 0 ) // returns combined nonce if ready
return(musig_nonce(txfee,cp,params));
else if ( strcmp(method,"partialsign") == 0 )
return(musig_partialsign(txfee,cp,params));
else if ( strcmp(method,"sigcombine") == 0 )
return(musig_sigcombine(txfee,cp,params));
else if ( strcmp(method,"partialsig") == 0 )
return(musig_partialsig(txfee,cp,params));
else if ( strcmp(method,"verify") == 0 )
return(musig_verify(txfee,cp,params));
else if ( strcmp(method,"send") == 0 )
@@ -247,6 +259,28 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
return(result);
}
}
else if ( cp->evalcode == EVAL_DILITHIUM )
{
if ( strcmp(method,"send") == 0 )
return(dilithium_send(txfee,cp,params));
else if ( strcmp(method,"spend") == 0 )
return(dilithium_spend(txfee,cp,params));
else if ( strcmp(method,"keypair") == 0 )
return(dilithium_keypair(txfee,cp,params));
else if ( strcmp(method,"register") == 0 )
return(dilithium_register(txfee,cp,params));
else if ( strcmp(method,"sign") == 0 )
return(dilithium_sign(txfee,cp,params));
else if ( strcmp(method,"verify") == 0 )
return(dilithium_verify(txfee,cp,params));
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid dilithium method"));
result.push_back(Pair("method",method));
return(result);
}
}
#endif
else
{
@@ -373,6 +407,8 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
return(sudoku_validate(cp,height,eval,tx));
else if ( cp->evalcode == EVAL_MUSIG )
return(musig_validate(cp,height,eval,tx));
else if ( cp->evalcode == EVAL_DILITHIUM )
return(dilithium_validate(cp,height,eval,tx));
else return eval->Invalid("invalid evalcode");
#endif
}
@@ -544,6 +580,15 @@ uint256 juint256(cJSON *obj)
return(revuint256(tmp));
}
int32_t cclib_parsehash(uint8_t *hash32,cJSON *item,int32_t len)
{
char *hexstr;
if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == len*2 )
{
decode_hex(hash32,len,hexstr);
return(0);
} else return(-1);
}
#ifdef BUILD_ROGUE
#include "rogue_rpc.cpp"
@@ -584,37 +629,8 @@ uint256 juint256(cJSON *obj)
#else
#include "sudoku.cpp"
/*
#include "../secp256k1/src/util.h"
#include "../secp256k1/src/num_impl.h"
#include "../secp256k1/src/field_impl.h"
#include "../secp256k1/src/scalar_impl.h"
#include "../secp256k1/src/group_impl.h"
#include "../secp256k1/src/scratch_impl.h"
#include "../secp256k1/src/ecmult_impl.h"
#include "../secp256k1/src/ecmult_const_impl.h"
#include "../secp256k1/src/ecmult_gen_impl.h"
#include "../secp256k1/src/ecdsa_impl.h"
#include "../secp256k1/src/eckey_impl.h"
#include "../secp256k1/src/hash_impl.h"
typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data);
extern "C" void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge);
extern "C" int secp256k1_nonce_function_bipschnorr(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter);
extern "C" int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey);
extern "C" void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2, const unsigned char *seed, uint64_t idx);
#define ARG_CHECK(cond) do { \
if (EXPECT(!(cond), 0)) { \
secp256k1_callback_call(&ctx->illegal_callback, #cond); \
return 0; \
} \
} while(0)*/
//#include "../secp256k1/src/secp256k1.c"
#include "musig.cpp"
#include "dilithium.c"
//#include "../secp256k1/src/modules/musig/example.c"
#endif

0
src/cc/dapps/cJSON.c Executable file → Normal file
View File

3269
src/cc/dilithium.c Normal file

File diff suppressed because one or more lines are too long

475
src/cc/dilithium.h Normal file
View File

@@ -0,0 +1,475 @@
#include <stdint.h>
/*
#ifndef CPUCYCLES_H
#define CPUCYCLES_H
#ifdef DBENCH
#define DBENCH_START() uint64_t time = cpucycles_start()
#define DBENCH_STOP(t) t += cpucycles_stop() - time - timing_overhead
#else
#define DBENCH_START()
#define DBENCH_STOP(t)
#endif
#ifdef USE_RDPMC // Needs echo 2 > /sys/devices/cpu/rdpmc
#ifdef SERIALIZE_RDC
static inline uint64_t cpucycles_start(void) {
const uint32_t ecx = (1U << 30) + 1;
uint64_t result;
asm volatile("cpuid; movl %1,%%ecx; rdpmc; shlq $32,%%rdx; orq %%rdx,%%rax"
: "=&a" (result) : "r" (ecx) : "rbx", "rcx", "rdx");
return result;
}
static inline uint64_t cpucycles_stop(void) {
const uint32_t ecx = (1U << 30) + 1;
uint64_t result, dummy;
asm volatile("rdpmc; shlq $32,%%rdx; orq %%rdx,%%rax; movq %%rax,%0; cpuid"
: "=&r" (result), "=c" (dummy) : "c" (ecx) : "rax", "rbx", "rdx");
return result;
}
#else
static inline uint64_t cpucycles_start(void) {
const uint32_t ecx = (1U << 30) + 1;
uint64_t result;
asm volatile("rdpmc; shlq $32,%%rdx; orq %%rdx,%%rax"
: "=a" (result) : "c" (ecx) : "rdx");
return result;
}
static inline uint64_t cpucycles_stop(void) {
const uint32_t ecx = (1U << 30) + 1;
uint64_t result;
asm volatile("rdpmc; shlq $32,%%rdx; orq %%rdx,%%rax"
: "=a" (result) : "c" (ecx) : "rdx");
return result;
}
#endif
#else
#ifdef SERIALIZE_RDC
static inline uint64_t cpucycles_start(void) {
uint64_t result;
asm volatile("cpuid; rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax"
: "=a" (result) : : "%rbx", "%rcx", "%rdx");
return result;
}
static inline uint64_t cpucycles_stop(void) {
uint64_t result;
asm volatile("rdtscp; shlq $32,%%rdx; orq %%rdx,%%rax; mov %%rax,%0; cpuid"
: "=r" (result) : : "%rax", "%rbx", "%rcx", "%rdx");
return result;
}
#else
static inline uint64_t cpucycles_start(void) {
uint64_t result;
asm volatile("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax"
: "=a" (result) : : "%rdx");
return result;
}
static inline uint64_t cpucycles_stop(void) {
uint64_t result;
asm volatile("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax"
: "=a" (result) : : "%rdx");
return result;
}
#endif
#endif
int64_t cpucycles_overhead(void);
#endif*/
#ifndef FIPS202_H
#define FIPS202_H
#define SHAKE128_RATE 168
#define SHAKE256_RATE 136
void shake128_absorb(uint64_t *s,
const uint8_t *input,
int32_t inlen);
void shake128_squeezeblocks(uint8_t *output,
int32_t nblocks,
uint64_t *s);
void shake256_absorb(uint64_t *s,
const uint8_t *input,
int32_t inlen);
void shake256_squeezeblocks(uint8_t *output,
int32_t nblocks,
uint64_t *s);
void shake128(uint8_t *output,
int32_t outlen,
const uint8_t *input,
int32_t inlen);
void shake256(uint8_t *output,
int32_t outlen,
const uint8_t *input,
int32_t inlen);
#endif
#ifndef PARAMS_H
#define PARAMS_H
#ifndef MODE
#define MODE 3
#endif
#define SEEDBYTES 32U
#define CRHBYTES 48U
#define N 256U
#define Q 8380417U
#define QBITS 23U
#define ROOT_OF_UNITY 1753U
#define D 14U
#define GAMMA1 ((Q - 1U)/16U)
#define GAMMA2 (GAMMA1/2U)
#define ALPHA (2U*GAMMA2)
#if MODE == 0
#define K 3U
#define L 2U
#define ETA 7U
#define SETABITS 4U
#define BETA 375U
#define OMEGA 64U
#elif MODE == 1
#define K 4U
#define L 3U
#define ETA 6U
#define SETABITS 4U
#define BETA 325U
#define OMEGA 80U
#elif MODE == 2
#define K 5U
#define L 4U
#define ETA 5U
#define SETABITS 4U
#define BETA 275U
#define OMEGA 96U
#elif MODE == 3
#define K 6U
#define L 5U
#define ETA 3U
#define SETABITS 3U
#define BETA 175U
#define OMEGA 120U
#endif
#define POL_SIZE_PACKED ((N*QBITS)/8)
#define POLT1_SIZE_PACKED ((N*(QBITS - D))/8)
#define POLT0_SIZE_PACKED ((N*D)/8)
#define POLETA_SIZE_PACKED ((N*SETABITS)/8)
#define POLZ_SIZE_PACKED ((N*(QBITS - 3))/8)
#define POLW1_SIZE_PACKED ((N*4)/8)
#define POLVECK_SIZE_PACKED (K*POL_SIZE_PACKED)
#define POLVECL_SIZE_PACKED (L*POL_SIZE_PACKED)
#define CRYPTO_PUBLICKEYBYTES (SEEDBYTES + K*POLT1_SIZE_PACKED)
#define CRYPTO_SECRETKEYBYTES (2*SEEDBYTES + (L + K)*POLETA_SIZE_PACKED + CRHBYTES + K*POLT0_SIZE_PACKED)
#define CRYPTO_BYTES (L*POLZ_SIZE_PACKED + (OMEGA + K) + (N/8 + 8))
#endif
#ifndef POLY_H
#define POLY_H
//#include <stdint.h>
//#include "params.h"
//#include "fips202.h"
typedef struct {
uint32_t coeffs[N];
} poly __attribute__((aligned(32)));
void poly_reduce(poly *a);
void poly_csubq(poly *a);
void poly_freeze(poly *a);
void poly_add(poly *c, const poly *a, const poly *b);
void poly_sub(poly *c, const poly *a, const poly *b);
void poly_neg(poly *a);
void poly_shiftl(poly *a, uint32_t k);
void poly_ntt(poly *a);
void poly_invntt_montgomery(poly *a);
void poly_pointwise_invmontgomery(poly *c, const poly *a, const poly *b);
void poly_power2round(poly *a1, poly *a0, const poly *a);
void poly_decompose(poly *a1, poly *a0, const poly *a);
uint32_t poly_make_hint(poly *h, const poly *a, const poly *b);
void poly_use_hint(poly *a, const poly *b, const poly *h);
int poly_chknorm(const poly *a, uint32_t B);
void poly_uniform(poly *a, const uint8_t *buf);
void poly_uniform_eta(poly *a,
const uint8_t seed[SEEDBYTES],
uint8_t nonce);
void poly_uniform_gamma1m1(poly *a,
const uint8_t seed[SEEDBYTES + CRHBYTES],
uint16_t nonce);
void polyeta_pack(uint8_t *r, const poly *a);
void polyeta_unpack(poly *r, const uint8_t *a);
void polyt1_pack(uint8_t *r, const poly *a);
void polyt1_unpack(poly *r, const uint8_t *a);
void polyt0_pack(uint8_t *r, const poly *a);
void polyt0_unpack(poly *r, const uint8_t *a);
void polyz_pack(uint8_t *r, const poly *a);
void polyz_unpack(poly *r, const uint8_t *a);
void polyw1_pack(uint8_t *r, const poly *a);
#endif
#ifndef POLYVEC_H
#define POLYVEC_H
//#include <stdint.h>
//#include "params.h"
//#include "poly.h"
/* Vectors of polynomials of length L */
typedef struct {
poly vec[L];
} polyvecl;
void polyvecl_freeze(polyvecl *v);
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v);
void polyvecl_ntt(polyvecl *v);
void polyvecl_pointwise_acc_invmontgomery(poly *w,
const polyvecl *u,
const polyvecl *v);
int polyvecl_chknorm(const polyvecl *v, uint32_t B);
/* Vectors of polynomials of length K */
typedef struct {
poly vec[K];
} polyveck;
void polyveck_reduce(polyveck *v);
void polyveck_csubq(polyveck *v);
void polyveck_freeze(polyveck *v);
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v);
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v);
void polyveck_shiftl(polyveck *v, uint32_t k);
void polyveck_ntt(polyveck *v);
void polyveck_invntt_montgomery(polyveck *v);
int polyveck_chknorm(const polyveck *v, uint32_t B);
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v);
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v);
uint32_t polyveck_make_hint(polyveck *h,
const polyveck *u,
const polyveck *v);
void polyveck_use_hint(polyveck *w, const polyveck *v, const polyveck *h);
#endif
#ifndef NTT_H
#define NTT_H
//#include <stdint.h>
//#include "params.h"
void ntt(uint32_t p[N]);
void invntt_frominvmont(uint32_t p[N]);
#endif
#ifndef PACKING_H
#define PACKING_H
//#include "params.h"
//#include "polyvec.h"
void pack_pk(uint8_t pk[CRYPTO_PUBLICKEYBYTES],
const uint8_t rho[SEEDBYTES], const polyveck *t1);
void pack_sk(uint8_t sk[CRYPTO_SECRETKEYBYTES],
const uint8_t rho[SEEDBYTES],
const uint8_t key[SEEDBYTES],
const uint8_t tr[CRHBYTES],
const polyvecl *s1,
const polyveck *s2,
const polyveck *t0);
void pack_sig(uint8_t sig[CRYPTO_BYTES],
const polyvecl *z, const polyveck *h, const poly *c);
void unpack_pk(uint8_t rho[SEEDBYTES], polyveck *t1,
const uint8_t pk[CRYPTO_PUBLICKEYBYTES]);
void unpack_sk(uint8_t rho[SEEDBYTES],
uint8_t key[SEEDBYTES],
uint8_t tr[CRHBYTES],
polyvecl *s1,
polyveck *s2,
polyveck *t0,
const uint8_t sk[CRYPTO_SECRETKEYBYTES]);
int unpack_sig(polyvecl *z, polyveck *h, poly *c,
const uint8_t sig[CRYPTO_BYTES]);
#endif
#ifndef REDUCE_H
#define REDUCE_H
//#include <stdint.h>
#define MONT 4193792U // 2^32 % Q
#define QINV 4236238847U // -q^(-1) mod 2^32
/* a <= Q*2^32 => r < 2*Q */
uint32_t montgomery_reduce(uint64_t a);
/* r < 2*Q */
uint32_t reduce32(uint32_t a);
/* a < 2*Q => r < Q */
uint32_t csubq(uint32_t a);
/* r < Q */
uint32_t freeze(uint32_t a);
#endif
#ifndef ROUNDING_H
#define ROUNDING_H
//#include <stdint.h>
uint32_t power2round(const uint32_t a, uint32_t *a0);
uint32_t decompose(uint32_t a, uint32_t *a0);
uint32_t make_hint(const uint32_t a, const uint32_t b);
uint32_t use_hint(const uint32_t a, const uint32_t hint);
#endif
#ifndef SIGN_H
#define SIGN_H
//#include "params.h"
//#include "poly.h"
//#include "polyvec.h"
void expand_mat(polyvecl mat[K], const uint8_t rho[SEEDBYTES]);
void challenge(poly *c, const uint8_t mu[CRHBYTES],
const polyveck *w1);
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk);
int crypto_sign(uint8_t *sm, int32_t *smlen,
const uint8_t *msg, int32_t len,
const uint8_t *sk);
int crypto_sign_open(uint8_t *m, int32_t *mlen,
const uint8_t *sm, int32_t smlen,
const uint8_t *pk);
#endif
#ifndef API_H
#define API_H
#ifndef MODE
#define MODE 3
#endif
#if MODE == 0
#if CRYPTO_PUBLICKEYBYTES -896U
CRYPTO_PUBLICKEYBYTES size error
#endif
#if CRYPTO_SECRETKEYBYTES -2096U
CRYPTO_SECRETKEYBYTES size error
#endif
#if CRYPTO_BYTES -1387U
CRYPTO_BYTES size error
#endif
#elif MODE == 1
#if CRYPTO_PUBLICKEYBYTES -1184U
CRYPTO_PUBLICKEYBYTES size error
#endif
#if CRYPTO_SECRETKEYBYTES -2800U
CRYPTO_SECRETKEYBYTES size error
#endif
#if CRYPTO_BYTES -2044U
CRYPTO_BYTES size error
#endif
#elif MODE == 2
#if CRYPTO_PUBLICKEYBYTES -1472U
CRYPTO_PUBLICKEYBYTES size error
#endif
#if CRYPTO_SECRETKEYBYTES -3504U
CRYPTO_SECRETKEYBYTES size error
#endif
#if CRYPTO_BYTES -2701U
CRYPTO_BYTES size error
#endif
#elif MODE == 3
#if CRYPTO_PUBLICKEYBYTES -1760U
CRYPTO_PUBLICKEYBYTES size error
#endif
#if CRYPTO_SECRETKEYBYTES -3856U
CRYPTO_SECRETKEYBYTES size error
#endif
#if CRYPTO_BYTES -3366U
CRYPTO_BYTES size error
#endif
#endif
#define CRYPTO_ALGNAME "Dilithium"
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk);
int crypto_sign(uint8_t *sm, int32_t *smlen,
const uint8_t *msg, int32_t len,
const uint8_t *sk);
int crypto_sign_open(uint8_t *m, int32_t *mlen,
const uint8_t *sm, int32_t smlen,
const uint8_t *pk);
#endif

View File

@@ -124,9 +124,9 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
//int height = it->first.blockHeight;
if ( CCduration(numblocks,it->first.txhash) > 0 && numblocks > 3 )
{
//fprintf(stderr,"would return error %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks);
return eval->Invalid("faucet is only for brand new addresses");
}
//fprintf(stderr,"txid %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks);
}
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )

View File

@@ -1,2 +1,2 @@
#!/bin/sh
gcc -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o ../libcc.so cclib.cpp
gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o ../libcc.so cclib.cpp

View File

@@ -3,10 +3,14 @@ cd rogue;
if [ "$HOST" = "x86_64-w64-mingw32" ]; then
echo building rogue.exe...
./configure --host=x86_64-w64-mingw32
mkdir ncurses && cd ncurses
echo $PWD
wget https://invisible-island.net/datafiles/release/mingw32.zip
unzip mingw32.zip && delete mingw32.zip
unzip mingw32.zip && rm mingw32.zip
echo lib archive cleaned
cd ..
echo $PWD
if make -f Makefile_win "$@"; then
echo rogue.exe build SUCCESSFUL
cd ..

634
src/cc/musig.cpp Executable file → Normal file
View File

@@ -14,48 +14,168 @@
******************************************************************************/
/* first make a combined pk:
./c cclib combine 18 \"[%2202aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848%22,%22039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22]\"
./komodo-cli -ac_name=MUSIG cclib combine 18 '["02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28","0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4"]'
{
"pkhash": "5be117f3c5ce87e7dc6882c24b8231e0652ee82054bf7b9f94aef1f45e055cba",
"combined_pk": "032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b",
"result": "success"
"pkhash": "5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",
"combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b",
"result": "success"
}
*/
/* second, send 0.777 coins to the combined_pk
./c cclib send 18 \"[%22032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b%22,0.777]\"
the combined_pk and pkhash will be needed for various other rpc calls
second, send 1 coin to the combined_pk
./komodo-cli -ac_name=MUSIG cclib send 18 '["03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b",1]'
{
"hex": "0400008085202f8901bf7afcbbab7a5e1ba20c8010325e199305afa7d15b4bc86a589a512201d39924000000004847304402203e0cff8aaa831dd990afd979bbc0a648316f77407cb5e02780d18e0670f5172a0220283d5c52d0406b10c508cc2b19dd6dbe2420e7c5cf431a1d41072d0eec28edb901ffffffff03b0c2a10400000000302ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cca91e223700000000232102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac0000000000000000266a24127821032ddac56613cd0667b589bd7f32b665e2d2ce0247e337a5a0bca6c72e3d9d057b00000000900000000000000000000000000000",
"txid": "cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be",
"result": "success"
"hex": "0400008085202f8901a980664dffc810725a79ffb89ac48be4c7b6bade9b789732fcf871acf8e81a2e010000006a47304402207e52763661ecd2c34a65d6623950be11794825db71576dc11894c606ddc317800220028fef46dc20630d0fdf22647b5d4ff0f1c47cf75f48702d0a91d5589eff99d001210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ffffffff031008f60500000000302ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cce09aa4350000000023210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac0000000000000000266a2412782103f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b00000000920500000000000000000000000000",
"txid": "5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c",
"result": "success"
}
sendrawtransaction of the above hex.
./komodo-cli -ac_name=MUSIG getrawtransaction 5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c 1
"vout": [
{
"value": 1.00010000,
"valueSat": 100010000,
"n": 0,
"scriptPubKey": {
"asm": "a22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401 OP_CHECKCRYPTOCONDITION",
"hex": "2ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cc",
"reqSigs": 1,
"type": "cryptocondition",
"addresses": [
"RKWS7jxyjPX9iaJttk8iMKf1AumanKypez"
]
}
},
{
"value": 8.99980000,
"valueSat": 899980000,
"n": 1,
"scriptPubKey": {
"asm": "0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4 OP_CHECKSIG",
"hex": "210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac",
"reqSigs": 1,
"type": "pubkey",
"addresses": [
"RVQjvGdRbYLJ49bfH4SAFseipvwE3UdoDw"
]
}
script: 210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac
sendtxid: 5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c
get the msg we need to sign:
./komodo-cli -ac_name=MUSIG cclib calcmsg 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac"]'
{
"value": 0.77710000,
"valueZat": 77710000,
"n": 0,
"scriptPubKey": {
"asm": "a22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401 OP_CHECKCRYPTOCONDITION",
"hex": "2ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cc",
"reqSigs": 1,
"type": "cryptocondition",
"addresses": [
"RKWS7jxyjPX9iaJttk8iMKf1AumanKypez"
]
"msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75",
"result": "success"
}
change script: 2102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac
sendtxid: cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be
the "msg" is what needs to be signed to create a valid spend
broadcast sendtxid and wait for it to be confirmed. then get the msg we need to sign:
./c cclib calcmsg 18 \"[%22cb5309ed249da95e2b5696eb763a8736e2fff1d14922ada737b931494ca3d2be%22,%222102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac%22]\"
now on each signing node, a session needs to be created:
5 args: ind, numsigners, combined_pk, pkhash, message to be signed
on node with pubkey: 02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28
./komodo-cli -ac_name=MUSIG cclib session 18 '[0,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]'
{
"result": "success",
"msg": "63b799913d4c9487f321b32d6ae8614f653f38e0b50d4df4bc1d36339ea18485"
"myind": 0,
"numsigners": 2,
"commitment": "bbea1f2562eca01b9a1393c5dc188bdd44551aebf684f4459930f59dde01f7ae",
"result": "success"
}
on node with pubkey: 0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4
./komodo-cli -ac_name=MUSIG cclib session 18 '[1,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]'
{
"myind": 1,
"numsigners": 2,
"commitment": "c2291acb747a75b1a40014d8eb0cc90a1360f74d413f65f78e20a7de45eda851",
"result": "success"
}
now we need to get the commitment from each node to the other one. the session already put the commitment for each node into the global struct. Keep in mind there is a single global struct with session unique to each cclib session call. that means no restarting any deamon in the middle of the process on any of the nodes and only call cclib session a single time. this is an artificial restriction just to simplify the initial implementation of musig
./komodo-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","c2291acb747a75b1a40014d8eb0cc90a1360f74d413f65f78e20a7de45eda851"]'
{
"added_index": 1,
"myind": 0,
"nonce": "02fec7a9310c959a0a97b86bc3f8c30d392d1fb51793915898c568f73f1f70476b",
"result": "success"
}
./komodo-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"d242cff13fa8c9b83248e4219fda459ada146b885f2171481f1b0f66c66d94ad"]'
{
"added_index": 0,
"myind": 1,
"nonce": "039365deaaaea089d509ba4c9f846de2baf4aa04cf6b26fa2c1cd818553e47f80c",
"result": "success"
}
Now exchange the revealed nonces to each node:
./komodo-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","039365deaaaea089d509ba4c9f846de2baf4aa04cf6b26fa2c1cd818553e47f80c"]'
{
"added_index": 1,
"myind": 0,
"partialsig": "1d65c09cd9bffe4f0604227e66cd7cd221480bbb08262fe885563a9df7cf8f5b",
"result": "success"
}
./komodo-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"02fec7a9310c959a0a97b86bc3f8c30d392d1fb51793915898c568f73f1f70476b"]'
{
"added_index": 0,
"myind": 1,
"partialsig": "4a3795e6801b355102c617390cf5a462061e082e35dc2ed8f8b1fab54cc0769e",
"result": "success"
}
Almost there! final step is to exchange the partial sigs between signers
./komodo-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","4a3795e6801b355102c617390cf5a462061e082e35dc2ed8f8b1fab54cc0769e"]'
{
"added_index": 1,
"result": "success",
"combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"
}
./komodo-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"1d65c09cd9bffe4f0604227e66cd7cd221480bbb08262fe885563a9df7cf8f5b"]'
{
"added_index": 0,
"result": "success",
"combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"
}
Notice both nodes generated the same combined signature!
Now for a sanity test, we can use the verify call to make sure this sig will work with the msg needed for the spend:
./komodo-cli -ac_name=MUSIG cclib verify 18 '["f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75","03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]'
{
"msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75",
"combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b",
"combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9",
"result": "success"
}
and finally the spend: sendtxid, scriptPubKey, musig
./komodo-cli -ac_name=MUSIG cclib spend 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]'
{
"scriptpubkey": "210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac",
"msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75",
"combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b",
"combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9",
"hex": "0400008085202f89014c821930f9eb360daaf1a1e12d5a82998b63884e8db4130421ee53a13740e75c000000007b4c79a276a072a26ba067a5658021032d29d6545a2aafad795d9cf50912ecade549137
163934dfb2895ebc0e211ce8a81409671a60db89b3bc58966f3acc80194479b1a43d868e95a11ebc5609646d18710341a8ff92a7817571980307f5d660cc00a2735ac6333e0a7191243f1263f1959a100af03800112
a10001ffffffff0200e1f5050000000023210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac0000000000000000686a4c6512792103f016c348437c7422eed92d865aa9789614f
75327cada463eefc566126b54785b40a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f900000000a805
00000000000000000000000000",
"txid": "910635bf69a047fc90567a83ff12e47b753f470658b6d0855ec96e07e7349a8a",
"result": "success"
}
*/
@@ -74,20 +194,81 @@ struct secp256k1_context_struct {
secp256k1_callback error_callback;
};
extern "C" int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n);
extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *msg32, const secp256k1_pubkey *pk);
extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64);
extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys);
//#include "../secp256k1/include/secp256k1.h"
//#include "../secp256k1/include/secp256k1_schnorrsig.h"
#include "../secp256k1/include/secp256k1_musig.h"
extern "C" int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n);
extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *msg32, const secp256k1_pubkey *pk);
extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64);
extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys);
extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, unsigned char *nonce_commitment32, const unsigned char *session_id32, const unsigned char *msg32, const secp256k1_pubkey *combined_pk, const unsigned char *pk_hash32, size_t n_signers, size_t my_index, const unsigned char *seckey);
extern "C" int secp256k1_schnorrsig_serialize(const secp256k1_context* ctx, unsigned char *out64, const secp256k1_schnorrsig* sig);
#define MUSIG_PREVN 0 // for now, just use vout0 for the musig output
#define MUSIG_TXFEE 10000
struct musig_info
{
secp256k1_musig_session session;
secp256k1_pubkey combined_pk;
uint8_t *nonce_commitments,**commitment_ptrs; // 32*N_SIGNERS
secp256k1_musig_session_signer_data *signer_data; //[N_SIGNERS];
secp256k1_pubkey *nonces; //[N_SIGNERS];
secp256k1_musig_partial_signature *partial_sig; //[N_SIGNERS];
int32_t myind,num,numcommits,numnonces,numpartials;
uint8_t msg[32],pkhash[32],combpk[33];
};
std::vector <struct musig_info *> MUSIG;
struct musig_info *musig_infocreate(int32_t myind,int32_t num)
{
int32_t i; struct musig_info *mp = (struct musig_info *)calloc(1,sizeof(*mp));
mp->myind = myind, mp->num = num;
mp->nonce_commitments = (uint8_t *)calloc(num,32);
mp->commitment_ptrs = (uint8_t **)calloc(num,sizeof(*mp->commitment_ptrs));
for (i=0; i<num; i++)
mp->commitment_ptrs[i] = &mp->nonce_commitments[i*32];
mp->signer_data = (secp256k1_musig_session_signer_data *)calloc(num,sizeof(*mp->signer_data));
mp->nonces = (secp256k1_pubkey *)calloc(num,sizeof(*mp->nonces));
mp->partial_sig = (secp256k1_musig_partial_signature *)calloc(num,sizeof(*mp->partial_sig));
return(mp);
}
void musig_infofree(struct musig_info *mp)
{
if ( mp->partial_sig != 0 )
{
GetRandBytes((uint8_t *)mp->partial_sig,mp->num*sizeof(*mp->partial_sig));
free(mp->partial_sig);
}
if ( mp->nonces != 0 )
{
GetRandBytes((uint8_t *)mp->nonces,mp->num*sizeof(*mp->nonces));
free(mp->nonces);
}
if ( mp->signer_data != 0 )
{
GetRandBytes((uint8_t *)mp->signer_data,mp->num*sizeof(*mp->signer_data));
free(mp->signer_data);
}
if ( mp->nonce_commitments != 0 )
{
GetRandBytes((uint8_t *)mp->nonce_commitments,mp->num*32);
free(mp->nonce_commitments);
}
if ( mp->commitment_ptrs != 0 )
{
GetRandBytes((uint8_t *)mp->commitment_ptrs,mp->num*sizeof(*mp->commitment_ptrs));
free(mp->commitment_ptrs);
}
GetRandBytes((uint8_t *)mp,sizeof(*mp));
free(mp);
}
CScript musig_sendopret(uint8_t funcid,CPubKey pk)
{
CScript opret; uint8_t evalcode = EVAL_MUSIG;
@@ -124,6 +305,17 @@ uint8_t musig_spendopretdecode(CPubKey &pk,std::vector<uint8_t> &musig64,CScript
return(0);
}
int32_t musig_parsepubkey(secp256k1_context *ctx,secp256k1_pubkey &spk,cJSON *item)
{
char *hexstr;
if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == 66 )
{
CPubKey pk(ParseHex(hexstr));
if ( secp256k1_ec_pubkey_parse(ctx,&spk,pk.begin(),33) > 0 )
return(1);
} else return(-1);
}
int32_t musig_msghash(uint8_t *msg,uint256 prevhash,int32_t prevn,CTxOut vout,CPubKey pk)
{
CScript data; uint256 hash; int32_t len = 0;
@@ -151,7 +343,7 @@ int32_t musig_prevoutmsg(uint8_t *msg,uint256 sendtxid,CScript scriptPubKey)
UniValue musig_calcmsg(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ); uint256 sendtxid; int32_t i; uint8_t msg[32]; char *scriptstr,str[65]; int32_t n;
UniValue result(UniValue::VOBJ); uint256 sendtxid; int32_t i,zeros=0; uint8_t msg[32]; char *scriptstr,str[65]; int32_t n;
if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 )
{
if ( n == 2 )
@@ -160,14 +352,23 @@ UniValue musig_calcmsg(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
scriptstr = jstr(jitem(params,1),0);
if ( is_hexstr(scriptstr,0) != 0 )
{
CScript scriptPubKey(ParseHex(scriptstr));
CScript scriptPubKey;
scriptPubKey.resize(strlen(scriptstr)/2);
decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr);
musig_prevoutmsg(msg,sendtxid,scriptPubKey);
result.push_back(Pair("result","success"));
for (i=0; i<32; i++)
{
sprintf(&str[i<<1],"%02x",msg[i]);
if ( msg[i] == 0 )
zeros++;
}
str[64] = 0;
result.push_back(Pair("msg",str));
return(result);
if ( zeros != 32 )
{
result.push_back(Pair("msg",str));
result.push_back(Pair("result","success"));
return(result);
} else return(cclib_error(result,"null result, make sure params are sendtxid, scriptPubKey"));
} else return(cclib_error(result,"script is not hex"));
} else return(cclib_error(result,"need exactly 2 parameters: sendtxid, scriptPubKey"));
} else return(cclib_error(result,"couldnt parse params"));
@@ -185,13 +386,9 @@ UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
//fprintf(stderr,"n.%d args.(%s)\n",n,jprint(params,0));
for (i=0; i<n; i++)
{
if ( (hexstr= jstr(jitem(params,i),0)) != 0 && is_hexstr(hexstr,0) == 66 )
{
CPubKey pk(ParseHex(hexstr));
if ( secp256k1_ec_pubkey_parse(ctx,&spk,pk.begin(),33) > 0 )
pubkeys.push_back(spk);
else return(cclib_error(result,"error parsing pk"));
} else return(cclib_error(result,"all pubkeys must be 33 bytes hexdata"));
if ( musig_parsepubkey(ctx,spk,jitem(params,i)) < 0 )
return(cclib_error(result,"error parsing pk"));
pubkeys.push_back(spk);
}
if ( secp256k1_musig_pubkey_combine(ctx,NULL,&combined_pk,pkhash,&pubkeys[0],n) > 0 )
{
@@ -215,44 +412,319 @@ UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
return(result);
static secp256k1_context *ctx;
UniValue result(UniValue::VOBJ); int32_t i,n,myind,num,musiglocation; char *pkstr,*pkhashstr,*msgstr; uint8_t session[32],msg[32],pkhash[32],privkey[32],pub33[33]; CPubKey pk; char str[67];
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 5 )
{
myind = juint(jitem(params,0),0);
num = juint(jitem(params,1),0);
if ( myind < 0 || myind >= num || num <= 0 )
return(cclib_error(result,"illegal myindex and numsigners"));
if ( n > 5 )
musiglocation = juint(jitem(params,5),0);
else if ( n == 5 )
musiglocation = 0;
//printf("number of params.%i musiglocation.%i\n",n,musiglocation);
if ( MUSIG.size() > musiglocation )
{
for (int i = 0; i < MUSIG.size()-1; i++)
musig_infofree(MUSIG[i]);
MUSIG.clear();
}
struct musig_info *temp_musig = musig_infocreate(myind,num);
MUSIG.push_back(temp_musig);
if ( musig_parsepubkey(ctx,MUSIG[musiglocation]->combined_pk,jitem(params,2)) < 0 )
return(cclib_error(result,"error parsing combined_pubkey"));
else if ( cclib_parsehash(MUSIG[musiglocation]->pkhash,jitem(params,3),32) < 0 )
return(cclib_error(result,"error parsing pkhash"));
else if ( cclib_parsehash(MUSIG[musiglocation]->msg,jitem(params,4),32) < 0 )
return(cclib_error(result,"error parsing msg"));
Myprivkey(privkey);
GetRandBytes(session,32);
/** Initializes a signing session for a signer
*
* Returns: 1: session is successfully initialized
* 0: session could not be initialized: secret key or secret nonce overflow
* Args: ctx: pointer to a context object, initialized for signing (cannot
* be NULL)
* Out: session: the session structure to initialize (cannot be NULL)
* signers: an array of signers' data to be initialized. Array length must
* equal to `n_signers` (cannot be NULL)
* nonce_commitment32: filled with a 32-byte commitment to the generated nonce
* (cannot be NULL)
* In: session_id32: a *unique* 32-byte ID to assign to this session (cannot be
* NULL). If a non-unique session_id32 was given then a partial
* signature will LEAK THE SECRET KEY.
* msg32: the 32-byte message to be signed. Shouldn't be NULL unless you
* require sharing public nonces before the message is known
* because it reduces nonce misuse resistance. If NULL, must be
* set with `musig_session_set_msg` before signing and verifying.
* combined_pk: the combined public key of all signers (cannot be NULL)
* pk_hash32: the 32-byte hash of the signers' individual keys (cannot be
* NULL)
* n_signers: length of signers array. Number of signers participating in
* the MuSig. Must be greater than 0 and at most 2^32 - 1.
* my_index: index of this signer in the signers array
* seckey: the signer's 32-byte secret key (cannot be NULL)
*/
//fprintf(stderr, "SESSION: struct_size.%li using struct %i\n",MUSIG.size(), musiglocation);
if ( secp256k1_musig_session_initialize(ctx,&MUSIG[musiglocation]->session,MUSIG[musiglocation]->signer_data, &MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind * 32],session,MUSIG[musiglocation]->msg,&MUSIG[musiglocation]->combined_pk,MUSIG[musiglocation]->pkhash,MUSIG[musiglocation]->num,MUSIG[musiglocation]->myind,privkey) > 0 )
{
memset(session,0,sizeof(session));
result.push_back(Pair("myind",(int64_t)myind));
result.push_back(Pair("numsigners",(int64_t)num));
for (i=0; i<32; i++)
sprintf(&str[i<<1],"%02x",MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind*32 + i]);
str[64] = 0;
if ( n == 5 )
MUSIG[musiglocation]->numcommits = 1;
result.push_back(Pair("commitment",str));
result.push_back(Pair("result","success"));
return(result);
}
else
{
memset(session,0,sizeof(session));
return(cclib_error(result,"couldnt initialize session"));
}
} else return(cclib_error(result,"wrong number of params, need 5: myindex, numsigners, combined_pk, pkhash, msg32"));
}
UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
return(result);
static secp256k1_context *ctx;
size_t clen = CPubKey::PUBLIC_KEY_SIZE;
UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32]; CPubKey pk; char str[67];
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 )
{
if ( n > 3 )
myind = juint(jitem(params,3),0);
else if ( n == 3 )
myind = 0;
if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 )
return(cclib_error(result,"error parsing pkhash"));
else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 )
return(cclib_error(result,"pkhash doesnt match session pkhash"));
else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num )
return(cclib_error(result,"illegal ind for session"));
else if ( cclib_parsehash(&MUSIG[myind]->nonce_commitments[ind*32],jitem(params,2),32) < 0 )
return(cclib_error(result,"error parsing commitment"));
/** Gets the signer's public nonce given a list of all signers' data with commitments
*
* Returns: 1: public nonce is written in nonce
* 0: signer data is missing commitments or session isn't initialized
* for signing
* Args: ctx: pointer to a context object (cannot be NULL)
* session: the signing session to get the nonce from (cannot be NULL)
* signers: an array of signers' data initialized with
* `musig_session_initialize`. Array length must equal to
* `n_commitments` (cannot be NULL)
* Out: nonce: the nonce (cannot be NULL)
* In: commitments: array of 32-byte nonce commitments (cannot be NULL)
* n_commitments: the length of commitments and signers array. Must be the total
* number of signers participating in the MuSig.
*/
result.push_back(Pair("added_index",ind));
//fprintf(stderr, "COMMIT: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind);
MUSIG[myind]->numcommits++;
if ( MUSIG[myind]->numcommits >= MUSIG[myind]->num && secp256k1_musig_session_get_public_nonce(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,&MUSIG[myind]->nonces[MUSIG[myind]->myind],MUSIG[myind]->commitment_ptrs,MUSIG[myind]->num) > 0 )
{
if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG[myind]->nonces[MUSIG[myind]->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 )
{
for (i=0; i<33; i++)
sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]);
str[66] = 0;
if ( n == 5 )
MUSIG[myind]->numnonces = 1;
result.push_back(Pair("myind",MUSIG[myind]->myind));
result.push_back(Pair("nonce",str));
result.push_back(Pair("result","success"));
} else return(cclib_error(result,"error serializing nonce (pubkey)"));
}
else
{
result.push_back(Pair("status","not enough commitments"));
result.push_back(Pair("result","success"));
}
return(result);
} else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, commitment"));
}
UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
return(result);
static secp256k1_context *ctx;
UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32],psig[32]; CPubKey pk; char str[67];
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 )
{
if ( n > 3 )
myind = juint(jitem(params,3),0);
else if ( n == 3 )
myind = 0;
if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 )
return(cclib_error(result,"error parsing pkhash"));
else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 )
return(cclib_error(result,"pkhash doesnt match session pkhash"));
else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num )
return(cclib_error(result,"illegal ind for session"));
else if ( musig_parsepubkey(ctx,MUSIG[myind]->nonces[ind],jitem(params,2)) < 0 )
return(cclib_error(result,"error parsing nonce"));
result.push_back(Pair("added_index",ind));
/** Checks a signer's public nonce against a commitment to said nonce, and update
* data structure if they match
*
* Returns: 1: commitment was valid, data structure updated
* 0: commitment was invalid, nothing happened
* Args: ctx: pointer to a context object (cannot be NULL)
* signer: pointer to the signer data to update (cannot be NULL). Must have
* been used with `musig_session_get_public_nonce` or initialized
* with `musig_session_initialize_verifier`.
* In: nonce: signer's alleged public nonce (cannot be NULL)
*/
MUSIG[myind]->numnonces++;
//fprintf(stderr, "NONCE: struct_size.%li using_struct.%i added_index.%i numnounces.%i num.%i\n",MUSIG.size(), myind, ind, MUSIG[myind]->numnonces, MUSIG[myind]->num);
if ( MUSIG[myind]->numnonces < MUSIG[myind]->num )
{
result.push_back(Pair("status","not enough nonces"));
result.push_back(Pair("result","success"));
return(result);
}
for (i=0; i<MUSIG[myind]->num; i++)
{
if ( secp256k1_musig_set_nonce(ctx,&MUSIG[myind]->signer_data[i],&MUSIG[myind]->nonces[i]) == 0 )
return(cclib_error(result,"error setting nonce"));
}
/** Updates a session with the combined public nonce of all signers. The combined
* public nonce is the sum of every signer's public nonce.
*
* Returns: 1: nonces are successfully combined
* 0: a signer's nonce is missing
* Args: ctx: pointer to a context object (cannot be NULL)
* session: session to update with the combined public nonce (cannot be
* NULL)
* signers: an array of signers' data, which must have had public nonces
* set with `musig_set_nonce`. Array length must equal to `n_signers`
* (cannot be NULL)
* n_signers: the length of the signers array. Must be the total number of
* signers participating in the MuSig.
* Out: nonce_is_negated: a pointer to an integer that indicates if the combined
* public nonce had to be negated.
* adaptor: point to add to the combined public nonce. If NULL, nothing is
* added to the combined nonce.
*/
if ( secp256k1_musig_session_combine_nonces(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,MUSIG[myind]->num,NULL,NULL) > 0 )
{
if ( secp256k1_musig_partial_sign(ctx,&MUSIG[myind]->session,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 )
{
if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 )
{
for (i=0; i<32; i++)
sprintf(&str[i<<1],"%02x",psig[i]);
str[64] = 0;
result.push_back(Pair("myind",MUSIG[myind]->myind));
result.push_back(Pair("partialsig",str));
result.push_back(Pair("result","success"));
if ( n == 5 )
MUSIG[myind]->numpartials = 1;
return(result);
} else return(cclib_error(result,"error serializing partial sig"));
} else return(cclib_error(result,"error making partial sig"));
} else return(cclib_error(result,"error combining nonces"));
} else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, nonce"));
}
UniValue musig_partialsign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
return(result);
}
UniValue musig_sigcombine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
return(result);
static secp256k1_context *ctx;
UniValue result(UniValue::VOBJ); int32_t i,ind,n,myind; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig;
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 )
{
if ( n > 3 )
myind = juint(jitem(params,3),0);
else if ( n == 3 )
myind = 0;
if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 )
return(cclib_error(result,"error parsing pkhash"));
else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 )
return(cclib_error(result,"pkhash doesnt match session pkhash"));
else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num )
return(cclib_error(result,"illegal ind for session"));
else if ( cclib_parsehash(psig,jitem(params,2),32) < 0 )
return(cclib_error(result,"error parsing psig"));
else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG[myind]->partial_sig[ind],psig) == 0 )
return(cclib_error(result,"error parsing partialsig"));
result.push_back(Pair("added_index",ind));
//fprintf(stderr, "SIG: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind);
MUSIG[myind]->numpartials++;
if ( MUSIG[myind]->numpartials >= MUSIG[myind]->num && secp256k1_musig_partial_sig_combine(ctx,&MUSIG[myind]->session,&sig,MUSIG[myind]->partial_sig,MUSIG[myind]->num) > 0 )
{
if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 )
{
result.push_back(Pair("result","success"));
for (i=0; i<64; i++)
sprintf(&str[i<<1],"%02x",out64[i]);
str[128] = 0;
result.push_back(Pair("combinedsig",str));
} else return(cclib_error(result,"error serializing combinedsig"));
}
else
{
if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 )
{
result.push_back(Pair("myind",ind));
for (i=0; i<32; i++)
sprintf(&str[i<<1],"%02x",psig[i]);
str[64] = 0;
result.push_back(Pair("partialsig",str));
result.push_back(Pair("result","success"));
result.push_back(Pair("status","need more partialsigs"));
} else return(cclib_error(result,"error generating my partialsig"));
}
return(result);
} else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, partialsig"));
}
//int testmain(void);
UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
return(result);
static secp256k1_context *ctx;
UniValue result(UniValue::VOBJ); int32_t i,n; uint8_t msg[32],musig64[64]; secp256k1_pubkey combined_pk; secp256k1_schnorrsig musig; char str[129];
//testmain();
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 )
{
if ( cclib_parsehash(msg,jitem(params,0),32) < 0 )
return(cclib_error(result,"error parsing pkhash"));
else if ( musig_parsepubkey(ctx,combined_pk,jitem(params,1)) < 0 )
return(cclib_error(result,"error parsing combined_pk"));
else if ( cclib_parsehash(musig64,jitem(params,2),64) < 0 )
return(cclib_error(result,"error parsing musig64"));
for (i=0; i<32; i++)
sprintf(&str[i*2],"%02x",msg[i]);
str[64] = 0;
result.push_back(Pair("msg",str));
result.push_back(Pair("combined_pk",jstr(jitem(params,1),0)));
for (i=0; i<64; i++)
sprintf(&str[i*2],"%02x",musig64[i]);
str[128] = 0;
result.push_back(Pair("combinedsig",str));
if ( secp256k1_schnorrsig_parse(ctx,&musig,&musig64[0]) > 0 )
{
if ( secp256k1_schnorrsig_verify(ctx,&musig,msg,&combined_pk) > 0 )
{
result.push_back(Pair("result","success"));
return(result);
} else return(cclib_error(result,"musig didnt verify"));
} else return(cclib_error(result,"couldnt parse musig64"));
} else return(cclib_error(result,"wrong number of params, need 3: msg, combined_pk, combinedsig"));
}
// helpers for rpc calls that generate/validate onchain tx
@@ -302,7 +774,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
static secp256k1_context *ctx;
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,pk; secp256k1_pubkey combined_pk; char *scriptstr,*musigstr; uint8_t msg[32]; CTransaction vintx; uint256 prevhash,hashBlock; int32_t n,numvouts; CTxOut vout; secp256k1_schnorrsig musig;
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,pk; secp256k1_pubkey combined_pk; char *scriptstr,*musigstr; uint8_t msg[32]; CTransaction vintx; uint256 prevhash,hashBlock; int32_t i,n,numvouts; char str[129]; CTxOut vout; secp256k1_schnorrsig musig;
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 )
@@ -312,13 +784,15 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
prevhash = juint256(jitem(params,0));
scriptstr = jstr(jitem(params,1),0);
musigstr = jstr(jitem(params,2),0);
if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) != 128 )
if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) == 128 )
{
if ( txfee == 0 )
txfee = MUSIG_TXFEE;
mypk = pubkey2pk(Mypubkey());
std::vector<uint8_t> musig64(ParseHex(musigstr));
CScript scriptPubKey(ParseHex(scriptstr));
CScript scriptPubKey;
scriptPubKey.resize(strlen(scriptstr)/2);
decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr);
if ( myGetTransaction(prevhash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 )
{
vout.nValue = vintx.vout[0].nValue - txfee;
@@ -329,8 +803,24 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
secp256k1_ec_pubkey_parse(ctx,&combined_pk,pk.begin(),33) > 0 )
{
musig_prevoutmsg(msg,prevhash,vout.scriptPubKey);
{
for (i=0; i<32; i++)
sprintf(&str[i*2],"%02x",msg[i]);
str[64] = 0;
result.push_back(Pair("msg",str));
for (i=0; i<33; i++)
sprintf(&str[i*2],"%02x",((uint8_t *)pk.begin())[i]);
str[66] = 0;
result.push_back(Pair("combined_pk",str));
for (i=0; i<64; i++)
sprintf(&str[i*2],"%02x",musig64[i]);
str[128] = 0;
result.push_back(Pair("combinedsig",str));
}
if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) )
{
return(cclib_error(result,"musig didnt validate"));
}
mtx.vin.push_back(CTxIn(prevhash,MUSIG_PREVN));
mtx.vout.push_back(vout);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,musig_spendopret('y',pk,musig64));
@@ -339,7 +829,7 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
} else return(cclib_error(result,"couldnt decode send opret"));
} else return(cclib_error(result,"couldnt find vin0"));
} else return(cclib_error(result,"script or musig is not hex"));
} else return(cclib_error(result,"need to have exactly 3 params prevhash, scriptPubKey, musig"));
} else return(cclib_error(result,"need to have exactly 3 params sendtxid, scriptPubKey, musig"));
} else return(cclib_error(result,"params parse error"));
}

View File

@@ -26,10 +26,10 @@ O=o
CC = x86_64-w64-mingw32-gcc
#CFLAGS=-O2
CFLAGS= -g -O2 -I./ncurses/include
CFLAGS= -g -O2 -I./ncurses/include -I./ncurses/include/ncursesw -I../../../depends/x86_64-w64-mingw32/include
#LIBS=-lcurses
LIBS = -L./ncurses/lib -lncursesw
LIBS = -L./ncurses/lib -lncursesw -lcurl
#RM=rm -f
RM = rm -f

View File

@@ -30,7 +30,7 @@ extern char Gametxidstr[67];
#define SATOSHIDEN ((uint64_t)100000000L)
#define dstr(x) ((double)(x) / SATOSHIDEN)
#define KOMODO_ASSETCHAIN_MAXLEN 65
char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],IPADDRESS[100];
#ifndef _BITS256
#define _BITS256
@@ -41,7 +41,11 @@ typedef union _bits256 bits256;
double OS_milliseconds()
{
struct timeval tv; double millis;
#ifdef __MINGW32__
mingw_gettimeofday(&tv,NULL);
#else
gettimeofday(&tv,NULL);
#endif
millis = ((double)tv.tv_sec * 1000. + (double)tv.tv_usec / 1000.);
//printf("tv_sec.%ld usec.%d %f\n",tv.tv_sec,tv.tv_usec,millis);
return(millis);
@@ -583,9 +587,9 @@ char *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char *
return(chunk.memory);
}
uint16_t _komodo_userpass(char *username,char *password,FILE *fp)
uint16_t _komodo_userpass(char *username, char *password, FILE *fp)
{
char *rpcuser,*rpcpassword,*str,line[8192]; uint16_t port = 0;
char *rpcuser,*rpcpassword,*str,*ipaddress,line[8192]; uint16_t port = 0;
rpcuser = rpcpassword = 0;
username[0] = password[0] = 0;
while ( fgets(line,sizeof(line),fp) != 0 )
@@ -602,13 +606,18 @@ uint16_t _komodo_userpass(char *username,char *password,FILE *fp)
port = atoi(parse_conf_line(str,(char *)"rpcport"));
//fprintf(stderr,"rpcport.%u in file\n",port);
}
else if ( (str= strstr(line,(char *)"ipaddress")) != 0 )
{
ipaddress = parse_conf_line(str,(char *)"ipaddress");
strcpy(IPADDRESS,ipaddress);
}
}
if ( rpcuser != 0 && rpcpassword != 0 )
{
strcpy(username,rpcuser);
strcpy(password,rpcpassword);
}
//printf("rpcuser.(%s) rpcpassword.(%s) KMDUSERPASS.(%s) %u\n",rpcuser,rpcpassword,KMDUSERPASS,port);
//printf("rpcuser.(%s) rpcpassword.(%s) %u ipaddress.%s\n",rpcuser,rpcpassword,port,ipaddress);
if ( rpcuser != 0 )
free(rpcuser);
if ( rpcpassword != 0 )
@@ -688,7 +697,7 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port)
params = (char *)"[]";
if ( strlen(params) < sizeof(postdata)-128 )
{
sprintf(url,(char *)"http://127.0.0.1:%u",port);
sprintf(url,(char *)"http://%s:%u",IPADDRESS,port);
sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params);
//printf("[%s] (%s) postdata.(%s) params.(%s) USERPASS.(%s)\n",ASSETCHAINS_SYMBOL,url,postdata,params,USERPASS);
retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params);
@@ -715,12 +724,21 @@ void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_
}
else
{
static FILE *fp;
if ( fp == 0 )
fp = fopen("keystrokes.log","a");
sprintf(params,"[\"keystrokes\",\"17\",\"[%%22%s%%22,%%22%s%%22]\"]",Gametxidstr,hexstr);
if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,ROGUE_PORT)) != 0 )
{
//fprintf(stderr,"KEYSTROKES.(%s)\n",retstr);
if ( fp != 0 )
{
fprintf(fp,"%s\n",params);
fprintf(fp,"%s\n",retstr);
fflush(fp);
}
free(retstr);
}
sleep(1);
}
}
}
@@ -794,7 +812,9 @@ int main(int argc, char **argv, char **envp)
}
ASSETCHAINS_SYMBOL[j++] = 0;
ROGUE_PORT = komodo_userpass(userpass,ASSETCHAINS_SYMBOL);
printf("ASSETCHAINS_SYMBOL.(%s) port.%u (%s)\n",ASSETCHAINS_SYMBOL,ROGUE_PORT,USERPASS); sleep(1);
if ( IPADDRESS[0] == 0 )
strcpy(IPADDRESS,"127.0.0.1");
printf("ASSETCHAINS_SYMBOL.(%s) port.%u (%s) IPADDRESS.%s \n",ASSETCHAINS_SYMBOL,ROGUE_PORT,USERPASS,IPADDRESS); sleep(1);
if ( argc == 2 && (fp=fopen(argv[1],"rb")) == 0 )
{
seed = atol(argv[1]);
@@ -813,5 +833,3 @@ int main(int argc, char **argv, char **envp)
return(rogue(argc,argv,envp));
}
}

View File

@@ -705,7 +705,9 @@ md_erasechar()
#elif defined(VERASE)
return(_tty.c_cc[VERASE]); /* process erase character */
#else
#ifndef __MINGW32__
return(_tty.sg_erase); /* process erase character */
#endif
#endif
}
@@ -717,7 +719,9 @@ md_killchar()
#elif defined(VKILL)
return(_tty.c_cc[VKILL]);
#else
#ifndef __MINGW32__
return(_tty.sg_kill);
#endif
#endif
}

View File

@@ -560,13 +560,15 @@ playit(struct rogue_state *rs)
}
else
{
if ( rs->needflush != 0 && rs->num > 8000 )
if ( rs->needflush != 0 && rs->num > 1000 )
{
if ( flushkeystrokes(rs) == 0 )
rs->needflush = 0;
}
}
}
if ( rs->guiflag != 0 )
flushkeystrokes(rs);
endit(0);
}

View File

@@ -1432,7 +1432,7 @@ rs_write_object(struct rogue_state *rs,FILE *savef, THING *o)
if ( o->_o._o_packch != 0 )
{
item = &rs->P.roguepack[rs->P.packsize];
if ( 0 && pstats.s_hpt <= 0 )
if ( 1 && pstats.s_hpt <= 0 )
{
//fprintf(stderr,"KILLED\n");
rs->P.gold = -1;

View File

@@ -472,12 +472,25 @@ int32_t rogue_playerdata(struct CCcontract_info *cp,uint256 &origplayergame,uint
int32_t rogue_playerdataspend(CMutableTransaction &mtx,uint256 playertxid,int32_t vout,uint256 origplayergame)
{
int64_t txfee = 10000;
int64_t txfee = 10000; CTransaction tx; uint256 hashBlock;
if ( CCgettxout(playertxid,vout,1) == 1 ) // not sure if this is enough validation
{
mtx.vin.push_back(CTxIn(playertxid,vout,CScript()));
return(0);
} else return(-1);
}
else
{
vout = 0;
if ( myGetTransaction(playertxid,tx,hashBlock) != 0 && tx.vout[vout].nValue == 1 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( CCgettxout(playertxid,vout,1) == 1 ) // not sure if this is enough validation
{
mtx.vin.push_back(CTxIn(playertxid,vout,CScript()));
return(0);
}
}
return(-1);
}
}
int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **keystrokesp,int32_t &numkeys,int32_t &regslot,std::vector<uint8_t> &playerdata,uint256 &batontxid,int32_t &batonvout,int64_t &batonvalue,int32_t &batonht,uint256 gametxid,CTransaction gametx,int32_t maxplayers,char *destaddr,int32_t &numplayers,std::string &symbol,std::string &pname)
@@ -505,7 +518,7 @@ int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **ke
}
if ( matches == 1 )
{
if ( myIsutxo_spent(spenttxid,gametxid,maxplayers+i+1) < 0 )
if ( 1 || myIsutxo_spent(spenttxid,gametxid,maxplayers+i+1) < 0 )
{
numvouts = matchtx.vout.size();
//fprintf(stderr,"matchtxid.%s matches.%d numvouts.%d\n",matchtx.GetHash().GetHex().c_str(),matches,numvouts);
@@ -532,6 +545,7 @@ int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **ke
return(-2);
}
txid = spenttxid;
//fprintf(stderr,"next txid.%s/v%d\n",txid.GetHex().c_str(),spentvini);
if ( spentvini != 0 )
return(-3);
if ( keystrokesp != 0 && myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() >= 2 )
@@ -575,7 +589,7 @@ int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **ke
else
{
fprintf(stderr,"already played\n");
return(-5);
return(-6);
}
}
return(-1);
@@ -833,12 +847,14 @@ UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
} else return(cclib_error(result,"couldnt reparse params"));
}
char *rogue_extractgame(char *str,int32_t *numkeysp,std::vector<uint8_t> &newdata,uint64_t &seed,uint256 &playertxid,struct CCcontract_info *cp,uint256 gametxid,char *rogueaddr)
char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vector<uint8_t> &newdata,uint64_t &seed,uint256 &playertxid,struct CCcontract_info *cp,uint256 gametxid,char *rogueaddr)
{
CPubKey roguepk; int32_t i,num,maxplayers,gameheight,batonht,batonvout,numplayers,regslot,numkeys,err; std::string symbol,pname; CTransaction gametx; int64_t buyin,batonvalue; char fname[64],*keystrokes = 0; std::vector<uint8_t> playerdata; uint256 batontxid; FILE *fp; uint8_t newplayer[10000]; struct rogue_player P,endP;
roguepk = GetUnspendable(cp,0);
*numkeysp = 0;
seed = 0;
num = numkeys = 0;
playertxid = zeroid;
if ( (err= rogue_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0)) == 0 )
{
if ( rogue_findbaton(cp,playertxid,&keystrokes,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,rogueaddr,numplayers,symbol,pname) == 0 )
@@ -852,21 +868,24 @@ char *rogue_extractgame(char *str,int32_t *numkeysp,std::vector<uint8_t> &newdat
for (i=0; i<playerdata.size(); i++)
((uint8_t *)&P)[i] = playerdata[i];
}
if ( keystrokes != 0 )
if ( keystrokes != 0 && numkeys != 0 )
{
sprintf(fname,"rogue.%llu.0",(long long)seed);
if ( (fp= fopen(fname,"wb")) != 0 )
if ( makefiles != 0 )
{
if ( fwrite(keystrokes,1,numkeys,fp) != numkeys )
fprintf(stderr,"error writing %s\n",fname);
fclose(fp);
}
sprintf(fname,"rogue.%llu.player",(long long)seed);
if ( (fp= fopen(fname,"wb")) != 0 )
{
if ( fwrite(&playerdata[0],1,(int32_t)playerdata.size(),fp) != playerdata.size() )
fprintf(stderr,"error writing %s\n",fname);
fclose(fp);
sprintf(fname,"rogue.%llu.0",(long long)seed);
if ( (fp= fopen(fname,"wb")) != 0 )
{
if ( fwrite(keystrokes,1,numkeys,fp) != numkeys )
fprintf(stderr,"error writing %s\n",fname);
fclose(fp);
}
sprintf(fname,"rogue.%llu.player",(long long)seed);
if ( (fp= fopen(fname,"wb")) != 0 )
{
if ( fwrite(&playerdata[0],1,(int32_t)playerdata.size(),fp) != playerdata.size() )
fprintf(stderr,"error writing %s\n",fname);
fclose(fp);
}
}
num = rogue_replay2(newplayer,seed,keystrokes,numkeys,playerdata.size()==0?0:&P,0);
newdata.resize(num);
@@ -877,16 +896,34 @@ char *rogue_extractgame(char *str,int32_t *numkeysp,std::vector<uint8_t> &newdat
}
if ( endP.gold <= 0 || endP.hitpoints <= 0 || (endP.strength&0xffff) <= 0 || endP.level <= 0 || endP.experience <= 0 || endP.dungeonlevel <= 0 )
{
fprintf(stderr,"zero value character was killed -> no playerdata\n");
//fprintf(stderr,"zero value character was killed -> no playerdata\n");
newdata.resize(0);
//P.gold = (P.gold * 8) / 10;
if ( keystrokes != 0 )
{
free(keystrokes);
keystrokes = 0;
*numkeysp = 0;
}
}
else
{
sprintf(str,"extracted $$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",endP.gold,endP.hitpoints,endP.strength&0xffff,endP.strength>>16,endP.level,endP.experience,endP.dungeonlevel);
fprintf(stderr,"%s\n",str);
*numkeysp = numkeys;
return(keystrokes);
}
sprintf(str,"extracted $$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",endP.gold,endP.hitpoints,endP.strength&0xffff,endP.strength>>16,endP.level,endP.experience,endP.dungeonlevel);
fprintf(stderr,"%s\n",str);
} else num = 0;
} else fprintf(stderr,"extractgame: couldnt find baton\n");
}
else
{
fprintf(stderr,"extractgame: couldnt find baton keystrokes.%p\n",keystrokes);
if ( keystrokes != 0 )
free(keystrokes), keystrokes = 0;
}
} else fprintf(stderr,"extractgame: invalid game\n");
*numkeysp = numkeys;
return(keystrokes);
//fprintf(stderr,"extract %s\n",gametxid.GetHex().c_str());
return(0);
}
UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
@@ -914,7 +951,7 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
result.push_back(Pair("rogueaddr",rogueaddr));
str[0] = 0;
if ( (keystrokes= rogue_extractgame(str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 )
if ( (keystrokes= rogue_extractgame(1,str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 )
{
result.push_back(Pair("status","success"));
flag = 1;
@@ -933,6 +970,77 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
return(result);
}
int32_t rogue_playerdata_validate(int64_t *cashoutp,uint256 &playertxid,struct CCcontract_info *cp,std::vector<uint8_t> playerdata,uint256 gametxid,CPubKey pk)
{
static uint32_t good,bad; static uint256 prevgame;
char str[512],*keystrokes,rogueaddr[64],str2[67]; int32_t i,dungeonlevel,numkeys; std::vector<uint8_t> newdata; uint64_t seed,mult = 10; CPubKey roguepk; struct rogue_player P;
*cashoutp = 0;
roguepk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
//fprintf(stderr,"call extractgame\n");
if ( (keystrokes= rogue_extractgame(0,str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 )
{
//fprintf(stderr,"numkeys.%d rogue_extractgame %s\n",numkeys,gametxid.GetHex().c_str());
free(keystrokes);
//fprintf(stderr,"extracted.(%s)\n",str);
for (i=0; i<playerdata.size(); i++)
((uint8_t *)&P)[i] = playerdata[i];
if ( P.amulet != 0 )
mult *= 5;
dungeonlevel = P.dungeonlevel;
if ( P.amulet != 0 && dungeonlevel < 21 )
dungeonlevel = 21;
*cashoutp = (uint64_t)P.gold * P.gold * mult * dungeonlevel;
if ( newdata == playerdata )
{
if ( gametxid != prevgame )
{
prevgame = gametxid;
good++;
fprintf(stderr,"%s good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
}
return(0);
}
newdata[10] = newdata[11] = playerdata[10] = playerdata[11] = 0;
if ( newdata == playerdata )
{
if ( gametxid != prevgame )
{
prevgame = gametxid;
good++;
fprintf(stderr,"%s matched after clearing maxstrength good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
}
return(0);
}
if ( P.gold <= 0 || P.hitpoints <= 0 || (P.strength&0xffff) <= 0 || P.level <= 0 || P.experience <= 0 || P.dungeonlevel <= 0 )
{
//P.gold = (P.gold * 8) / 10;
//for (i=0; i<playerdata.size(); i++)
// playerdata[i] = ((uint8_t *)&P)[i];
if ( newdata.size() == 0 )
{
if ( gametxid != prevgame )
{
prevgame = gametxid;
good++;
fprintf(stderr,"zero value character was killed -> no playerdata, good.%d bad.%d\n",good,bad);
}
*cashoutp = 0;
return(0);
}
}
if ( gametxid != prevgame )
{
prevgame = gametxid;
bad++;
fprintf(stderr,"%s playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",gametxid.GetHex().c_str(),P.gold,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel);
fprintf(stderr,"newdata[%d] != playerdata[%d], numkeys.%d %s pub.%s playertxid.%s good.%d bad.%d\n",(int32_t)newdata.size(),(int32_t)playerdata.size(),numkeys,rogueaddr,pubkey33_str(str2,(uint8_t *)&pk),playertxid.GetHex().c_str(),good,bad);
}
}
//fprintf(stderr,"no keys rogue_extractgame %s\n",gametxid.GetHex().c_str());
return(-1);
}
UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params,char *method)
{
//vin0 -> highlander vout from creategame TCBOO
@@ -947,7 +1055,7 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
// vout0 -> 1% ingame gold
// get any playerdata, get all keystrokes, replay game and compare final state
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx,symbol,pname; CTransaction gametx; uint64_t seed,mult; int64_t buyin,batonvalue,inputsum,cashout,CCchange=0; int32_t i,err,gameheight,tmp,numplayers,regslot,n,num,numkeys,maxplayers,batonht,batonvout; char myrogueaddr[64],*keystrokes = 0; std::vector<uint8_t> playerdata,newdata,nodata; uint256 batontxid,playertxid,gametxid; CPubKey mypk,roguepk; uint8_t player[10000],mypriv[32],funcid;
UniValue result(UniValue::VOBJ); std::string rawtx,symbol,pname; CTransaction gametx; uint64_t seed,mult; int64_t buyin,batonvalue,inputsum,cashout,CCchange=0; int32_t i,err,gameheight,tmp,numplayers,regslot,n,num,dungeonlevel,numkeys,maxplayers,batonht,batonvout; char myrogueaddr[64],*keystrokes = 0; std::vector<uint8_t> playerdata,newdata,nodata; uint256 batontxid,playertxid,gametxid; CPubKey mypk,roguepk; uint8_t player[10000],mypriv[32],funcid;
struct CCcontract_info *cpTokens, tokensC;
if ( txfee == 0 )
@@ -961,12 +1069,12 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
if ( strcmp(method,"bailout") == 0 )
{
funcid = 'Q';
mult = 100000;
mult = 10; //100000;
}
else
{
funcid = 'H';
mult = 200000;
mult = 20; //200000;
}
if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 )
{
@@ -991,7 +1099,7 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
{
num = rogue_replay2(player,seed,keystrokes,numkeys,playerdata.size()==0?0:&P,0);
if ( keystrokes != 0 )
free(keystrokes);
free(keystrokes), keystrokes = 0;
} else num = 0;
mtx.vin.push_back(CTxIn(batontxid,batonvout,CScript()));
mtx.vin.push_back(CTxIn(gametxid,1+maxplayers+regslot,CScript()));
@@ -1005,22 +1113,26 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
newdata[i] = player[i];
((uint8_t *)&P)[i] = player[i];
}
if ( 0 && (P.gold <= 0 || P.hitpoints <= 0 || (P.strength&0xffff) <= 0 || P.level <= 0 || P.experience <= 0 || P.dungeonlevel <= 0) )
if ( (P.gold <= 0 || P.hitpoints <= 0 || (P.strength&0xffff) <= 0 || P.level <= 0 || P.experience <= 0 || P.dungeonlevel <= 0) )
{
fprintf(stderr,"zero value character was killed -> no playerdata\n");
//fprintf(stderr,"zero value character was killed -> no playerdata\n");
newdata.resize(0);
//P.gold = (P.gold * 8) / 10;
}
else
{
if ( maxplayers == 1 )
mult /= 2;
//if ( maxplayers == 1 )
// mult /= 2;
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, txfee, GetUnspendable(cpTokens,NULL))); // marker to token cc addr, burnable and validated
mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode,1,mypk));
fprintf(stderr,"\nextracted $$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d n.%d amulet.%d\n",P.gold,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel,n,P.amulet);
if ( P.amulet != 0 )
mult *= 5;
cashout = (uint64_t)P.gold * mult;
dungeonlevel = P.dungeonlevel;
if ( P.amulet != 0 && dungeonlevel < 21 )
dungeonlevel = 21;
cashout = (uint64_t)P.gold * P.gold * mult * dungeonlevel;
fprintf(stderr,"\nextracted $$$gold.%d -> %.8f ROGUE hp.%d strength.%d/%d level.%d exp.%d dl.%d n.%d amulet.%d\n",P.gold,(double)cashout/COIN,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel,n,P.amulet);
if ( funcid == 'H' && maxplayers > 1 )
{
if ( (numplayers != maxplayers || (numplayers - rogue_playersalive(tmp,gametxid,maxplayers)) > 1) && P.amulet == 0 )
@@ -1036,7 +1148,6 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
}
}
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange + (batonvalue-3*txfee),roguepk));
Myprivkey(mypriv);
CCaddr1of2set(cp,roguepk,mypk,mypriv,myrogueaddr);
CScript opret;
@@ -1230,53 +1341,14 @@ UniValue rogue_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
return(result);
}
int32_t rogue_playerdata_validate(uint256 &playertxid,struct CCcontract_info *cp,std::vector<uint8_t> playerdata,uint256 gametxid,CPubKey pk)
{
static uint32_t good,bad; static uint256 prevgame;
char str[512],*keystrokes,rogueaddr[64],str2[67]; int32_t i,numkeys; std::vector<uint8_t> newdata; uint64_t seed; CPubKey roguepk; struct rogue_player P;
if ( gametxid == prevgame )
return(0);
prevgame = gametxid;
roguepk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
//fprintf(stderr,"call extractgame\n");
if ( (keystrokes= rogue_extractgame(str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 )
{
free(keystrokes);
//fprintf(stderr,"extracted.(%s)\n",str);
if ( newdata == playerdata )
{
good++;
fprintf(stderr,"%s good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
return(0);
}
newdata[10] = newdata[11] = playerdata[10] = playerdata[11] = 0;
if ( newdata == playerdata )
{
good++;
fprintf(stderr,"%s matched after clearing maxstrength good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
return(0);
}
bad++;
for (i=0; i<playerdata.size(); i++)
((uint8_t *)&P)[i] = playerdata[i];
if ( P.gold <= 0 || P.hitpoints <= 0 || (P.strength&0xffff) <= 0 || P.level <= 0 || P.experience <= 0 || P.dungeonlevel <= 0 )
{
fprintf(stderr,"zero value character was killed -> no playerdata\n");
}
fprintf(stderr,"%s playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",gametxid.GetHex().c_str(),P.gold,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel);
fprintf(stderr,"newdata[%d] != playerdata[%d], numkeys.%d %s pub.%s playertxid.%s good.%d bad.%d\n",(int32_t)newdata.size(),(int32_t)playerdata.size(),numkeys,rogueaddr,pubkey33_str(str2,(uint8_t *)&pk),playertxid.GetHex().c_str(),good,bad);
}
return(-1);
}
bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
{
CScript scriptPubKey; std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid; int32_t i,maxplayers,decoded=0,regslot,ind,err,dispflag,gameheight,score,numvouts; CTransaction vintx,gametx; CPubKey pk; uint256 hashBlock,gametxid,tokenid,batontxid,playertxid,ptxid; int64_t buyin; std::vector<uint8_t> playerdata,keystrokes; std::string symbol,pname;
CScript scriptPubKey; std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid,tokentx=0; int32_t i,maxplayers,decoded=0,regslot,ind,err,dispflag,gameheight,score,numvouts; CTransaction vintx,gametx; CPubKey pk; uint256 hashBlock,gametxid,txid,tokenid,batontxid,playertxid,ptxid; int64_t buyin,cashout; std::vector<uint8_t> playerdata,keystrokes; std::string symbol,pname;
if ( strcmp(ASSETCHAINS_SYMBOL,"ROGUE") == 0 && height < 21274 )
return(true);
if ( (numvouts= tx.vout.size()) > 1 )
{
txid = tx.GetHash();
scriptPubKey = tx.vout[numvouts-1].scriptPubKey;
GetOpReturnData(scriptPubKey,vopret);
if ( vopret.size() > 2 )
@@ -1285,6 +1357,7 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
funcid = script[1];
if ( (e= script[0]) == EVAL_TOKENS )
{
tokentx = 1;
if ( (funcid= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,scriptPubKey)) == 0 )
{
if ( (funcid= rogue_registeropretdecode(gametxid,tokenid,playertxid,scriptPubKey)) == 0 )
@@ -1357,10 +1430,14 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
// verify pk belongs to this tx
if ( playerdata.size() > 0 )
{
if ( rogue_playerdata_validate(ptxid,cp,playerdata,gametxid,pk) < 0 )
if ( rogue_playerdata_validate(&cashout,ptxid,cp,playerdata,gametxid,pk) < 0 )
{
//fprintf(stderr,"ht.%d gametxid.%s player.%s invalid playerdata[%d]\n",height,gametxid.GetHex().c_str(),ptxid.GetHex().c_str(),(int32_t)playerdata.size());
} //else fprintf(stderr,"ht.%d playertxid.%s validated\n",height,ptxid.GetHex().c_str());
fprintf(stderr,"ht.%d gametxid.%s player.%s invalid playerdata[%d]\n",height,gametxid.GetHex().c_str(),ptxid.GetHex().c_str(),(int32_t)playerdata.size());
}
if ( funcid == 'H' )
cashout *= 2;
if ( tx.vout.size() > 3 ) // orig of 't' has 0 cashout
fprintf(stderr,"ht.%d txid.%s cashout %.8f vs vout2 %.8f\n",height,txid.GetHex().c_str(),(double)cashout/COIN,(double)tx.vout[2].nValue/COIN);
}
if ( funcid == 'Q' )
{

0
src/komodo_cJSON.c Executable file → Normal file
View File

0
src/komodo_cJSON.h Executable file → Normal file
View File

0
src/komodo_jumblr.h Executable file → Normal file
View File

200
src/musigtest.py Executable file
View File

@@ -0,0 +1,200 @@
#!/usr/bin/env python3
import platform
import os
import re
import json
import random
import base58
import binascii
import hashlib
import sys
import time
from slickrpc import Proxy
# fucntion to define rpc_connection
def def_credentials(chain):
rpcport = '';
operating_system = platform.system()
if operating_system == 'Darwin':
ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo'
elif operating_system == 'Linux':
ac_dir = os.environ['HOME'] + '/.komodo'
elif operating_system == 'Windows':
ac_dir = '%s/komodo/' % os.environ['APPDATA']
if chain == 'KMD':
coin_config_file = str(ac_dir + '/komodo.conf')
else:
coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf')
with open(coin_config_file, 'r') as f:
for line in f:
l = line.rstrip()
if re.search('rpcuser', l):
rpcuser = l.replace('rpcuser=', '')
elif re.search('rpcpassword', l):
rpcpassword = l.replace('rpcpassword=', '')
elif re.search('rpcport', l):
rpcport = l.replace('rpcport=', '')
if len(rpcport) == 0:
if chain == 'KMD':
rpcport = 7771
else:
print("rpcport not in conf file, exiting")
print("check " + coin_config_file)
exit(1)
return (Proxy("http://%s:%s@127.0.0.1:%d" % (rpcuser, rpcpassword, int(rpcport))))
# generate address, validate address, dump private key
def genvaldump(rpc_connection):
# get new address
address = rpc_connection.getnewaddress()
# validate address
validateaddress_result = rpc_connection.validateaddress(address)
pubkey = validateaddress_result['pubkey']
address = validateaddress_result['address']
# dump private key for the address
privkey = rpc_connection.dumpprivkey(address)
# function output
output = [pubkey, privkey, address]
return(output)
CHAIN = 'MUSIG' #sys.argv[1]
rpc = def_credentials(CHAIN)
pubkeys = []
address_info = []
ret = input('Do you want to generate new pubkeys? ').lower()
if ret.startswith('y'):
numpks = int(input('Enter number of pubkeys to combine: '))
if os.path.isfile("list.json"):
print('Already have list.json, move it if you would like to generate a new set.')
sys.exit(0)
while len(address_info) < numpks:
addressinfo = genvaldump(rpc)
address_info.append(addressinfo)
f = open("list.json", "w+")
f.write(json.dumps(address_info))
else:
if os.path.isfile("list.json"):
with open('list.json') as list:
address_info = json.load(list)
else:
sys.exit('No list.json you need to create new pubkeys!')
for addressinfo in address_info:
pubkeys.append(addressinfo[0])
ret = rpc.setpubkey(pubkeys[0])
ret = rpc.cclib("combine", "18", str(pubkeys))
pkhash = str(ret['pkhash'])
combinedpk = str(ret['combined_pk'])
print('Your combined pubkey is: ' + combinedpk)
print('Your pkhash is: ' + pkhash)
amount = float(input('Enter amount to send: '))
if amount == 0:
sys.exit('Cannot send 0 coins. Exiting.')
tmp = str([combinedpk, amount])
hex = rpc.cclib("send", "18", tmp)['hex']
senttxid = rpc.sendrawtransaction(hex)
print('Your senttxid is: ' + senttxid)
print("Waiting for tx to be confirmed")
while True:
confirmed = int(rpc.gettransaction(senttxid)["confirmations"])
if not confirmed:
time.sleep(10)
else:
print('SentTX confirmed')
break
scriptPubKey = rpc.getrawtransaction(senttxid,1)['vout'][1]['scriptPubKey']['hex']
print('Your scriptPubKey is: ' + scriptPubKey)
tmp = str([senttxid, scriptPubKey])
msg = rpc.cclib("calcmsg", "18", tmp)['msg']
print('Your msg is: ' + msg)
i = 0;
commitments = []
for pubkey in pubkeys:
ret = rpc.setpubkey(pubkey)
tmp = str([i, len(pubkeys), combinedpk, pkhash, msg, i])
commitments.append(rpc.cclib("session", "18", tmp)['commitment'])
i = i + 1
print("Created commitments sucessfully... Sending to all signers.")
i = 0
nonces = []
for pubkey in pubkeys:
ret = rpc.setpubkey(pubkey)
n = 0
for commitment in commitments:
tmp = str([pkhash, n, commitment, i])
ret = rpc.cclib("commit", "18", tmp)
try:
nonces.append(ret['nonce'])
except:
x = 1
n = n + 1
i = i + 1
print("Created nounce's sucessfully... Sending to all signers.")
i = 0
partialsigs = []
for pubkey in pubkeys:
ret = rpc.setpubkey(pubkey)
n = 0
for nonce in nonces:
tmp = str([pkhash, n, nonce, i])
ret = rpc.cclib("nonce", "18", tmp)
try:
partialsigs.append(ret['partialsig'])
except:
x = 1
n = n + 1
i = i + 1
print("Created partial sigs sucessfully... Sending to all signers.")
i = 0
combinedsigs = []
for pubkey in pubkeys:
ret = rpc.setpubkey(pubkey)
n = 0
for partialsig in partialsigs:
tmp = str([pkhash, n, partialsig, i])
ret = rpc.cclib("partialsig", "18", tmp)
try:
combinedsigs.append(ret['combinedsig'])
except:
x = 1
n = n + 1
i = i + 1
print("Created combined sigs sucessfully... Verifying.")
tmp = str([msg, combinedpk, combinedsigs[0]])
ret = rpc.cclib("verify", "18", tmp)
if ret['result'] != "success":
print(ret)
sys.exit('Could not verify signature.')
print('Verified... Attempting to send.')
tmp = str([senttxid, scriptPubKey, combinedsigs[0]])
ret = rpc.cclib("spend", "18", tmp)
if ret['result'] != "success":
print(ret)
sys.exit('Could not create spend transaction.')
try:
ret = rpc.sendrawtransaction(ret['hex'])
except:
sys.exit('Could not send transaction.')
print('Spent txid: ' + ret)

View File

@@ -132,7 +132,12 @@ typedef struct {
* key (cannot be NULL)
* n_pubkeys: length of pubkeys array
*/
SECP256K1_API int secp256k1_musig_pubkey_combine(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_pubkey_combine(
const secp256k1_context* ctx,
secp256k1_scratch_space *scratch,
secp256k1_pubkey *combined_pk,
@@ -167,7 +172,12 @@ SECP256K1_API int secp256k1_musig_pubkey_combine(
* my_index: index of this signer in the signers array
* seckey: the signer's 32-byte secret key (cannot be NULL)
*/
SECP256K1_API int secp256k1_musig_session_initialize(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_session_initialize(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
secp256k1_musig_session_signer_data *signers,
@@ -196,7 +206,12 @@ SECP256K1_API int secp256k1_musig_session_initialize(
* n_commitments: the length of commitments and signers array. Must be the total
* number of signers participating in the MuSig.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_public_nonce(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_public_nonce(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
secp256k1_musig_session_signer_data *signers,
@@ -225,7 +240,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_publi
* participating in the MuSig. Must be greater than 0 and at most
* 2^32 - 1.
*/
SECP256K1_API int secp256k1_musig_session_initialize_verifier(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_session_initialize_verifier(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
secp256k1_musig_session_signer_data *signers,
@@ -247,7 +267,12 @@ SECP256K1_API int secp256k1_musig_session_initialize_verifier(
* with `musig_session_initialize_verifier`.
* In: nonce: signer's alleged public nonce (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce(
const secp256k1_context* ctx,
secp256k1_musig_session_signer_data *signer,
const secp256k1_pubkey *nonce
@@ -271,7 +296,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce(
* adaptor: point to add to the combined public nonce. If NULL, nothing is
* added to the combined nonce.
*/
SECP256K1_API int secp256k1_musig_session_combine_nonces(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_session_combine_nonces(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
const secp256k1_musig_session_signer_data *signers,
@@ -288,7 +318,12 @@ SECP256K1_API int secp256k1_musig_session_combine_nonces(
* session: the session structure to update with the message (cannot be NULL)
* In: msg32: the 32-byte message to be signed (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_set_msg(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_set_msg(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
const unsigned char *msg32
@@ -301,7 +336,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_set_msg(
* Out: out32: pointer to a 32-byte array to store the serialized signature
* In: sig: pointer to the signature
*/
SECP256K1_API int secp256k1_musig_partial_signature_serialize(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_partial_signature_serialize(
const secp256k1_context* ctx,
unsigned char *out32,
const secp256k1_musig_partial_signature* sig
@@ -318,7 +358,12 @@ SECP256K1_API int secp256k1_musig_partial_signature_serialize(
* encoded numbers are out of range, signature verification with it is
* guaranteed to fail for every message and public key.
*/
SECP256K1_API int secp256k1_musig_partial_signature_parse(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_partial_signature_parse(
const secp256k1_context* ctx,
secp256k1_musig_partial_signature* sig,
const unsigned char *in32
@@ -333,7 +378,12 @@ SECP256K1_API int secp256k1_musig_partial_signature_parse(
* computed (cannot be NULL)
* Out: partial_sig: partial signature (cannot be NULL)
*/
SECP256K1_API int secp256k1_musig_partial_sign(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_partial_sign(
const secp256k1_context* ctx,
const secp256k1_musig_session *session,
secp256k1_musig_partial_signature *partial_sig
@@ -356,7 +406,12 @@ SECP256K1_API int secp256k1_musig_partial_sign(
* In: partial_sig: signature to verify (cannot be NULL)
* pubkey: public key of the signer who produced the signature (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
const secp256k1_context* ctx,
const secp256k1_musig_session *session,
const secp256k1_musig_session_signer_data *signer,
@@ -376,7 +431,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verif
* In: partial_sigs: array of partial signatures to combine (cannot be NULL)
* n_sigs: number of signatures in the partial_sigs array
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combine(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combine(
const secp256k1_context* ctx,
const secp256k1_musig_session *session,
secp256k1_schnorrsig *sig,
@@ -396,7 +456,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combi
* be NULL)
* nonce_is_negated: the `nonce_is_negated` output of `musig_session_combine_nonces`
*/
SECP256K1_API int secp256k1_musig_partial_sig_adapt(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_musig_partial_sig_adapt(
const secp256k1_context* ctx,
secp256k1_musig_partial_signature *adaptor_sig,
const secp256k1_musig_partial_signature *partial_sig,
@@ -419,7 +484,12 @@ SECP256K1_API int secp256k1_musig_partial_sig_adapt(
* n_partial_sigs: number of elements in partial_sigs array
* nonce_is_negated: the `nonce_is_negated` output of `musig_session_combine_nonces`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_secret_adaptor(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_secret_adaptor(
const secp256k1_context* ctx,
unsigned char *sec_adaptor32,
const secp256k1_schnorrsig *sig,

View File

@@ -28,7 +28,12 @@ typedef struct {
*
* See secp256k1_schnorrsig_parse for details about the encoding.
*/
SECP256K1_API int secp256k1_schnorrsig_serialize(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_schnorrsig_serialize(
const secp256k1_context* ctx,
unsigned char *out64,
const secp256k1_schnorrsig* sig
@@ -50,7 +55,12 @@ SECP256K1_API int secp256k1_schnorrsig_serialize(
* encoded numbers are out of range, signature validation with it is
* guaranteed to fail for every message and public key.
*/
SECP256K1_API int secp256k1_schnorrsig_parse(
#ifdef __cplusplus
extern "C"
#else
SECP256K1_API
#endif
int secp256k1_schnorrsig_parse(
const secp256k1_context* ctx,
secp256k1_schnorrsig* sig,
const unsigned char *in64

View File

@@ -9,11 +9,11 @@
* Additionally, see the documentation in include/secp256k1_musig.h.
*/
#include <stdio.h>
/*#include <stdio.h>
#include <assert.h>
#include <secp256k1.h>
#include <secp256k1_schnorrsig.h>
#include <secp256k1_musig.h>
#include <secp256k1_musig.h>*/
/* Number of public keys involved in creating the aggregate signature */
#define N_SIGNERS 3
@@ -122,43 +122,43 @@ int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp25
return secp256k1_musig_partial_sig_combine(ctx, &musig_session[0], sig, partial_sig, N_SIGNERS);
}
int main(void) {
int testmain(void) {
secp256k1_context* ctx;
int i;
unsigned char seckeys[N_SIGNERS][32];
secp256k1_pubkey pubkeys[N_SIGNERS];
secp256k1_pubkey combined_pk;
unsigned char msg[32] = "this_could_be_the_hash_of_a_msg!";
unsigned char msg[32] = "this_could_be_the_hash_of_a_msg";
secp256k1_schnorrsig sig;
/* Create a context for signing and verification */
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
printf("Creating key pairs......");
fprintf(stderr,"Creating key pairs......");
for (i = 0; i < N_SIGNERS; i++) {
if (!create_key(ctx, seckeys[i], &pubkeys[i])) {
printf("FAILED\n");
fprintf(stderr,"FAILED\n");
return 1;
}
}
printf("ok\n");
printf("Combining public keys...");
fprintf(stderr,"ok\n");
fprintf(stderr,"Combining public keys...");
if (!secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk, NULL, pubkeys, N_SIGNERS)) {
printf("FAILED\n");
fprintf(stderr,"FAILED\n");
return 1;
}
printf("ok\n");
printf("Signing message.........");
fprintf(stderr,"ok\n");
fprintf(stderr,"Signing message.........");
if (!sign(ctx, seckeys, pubkeys, msg, &sig)) {
printf("FAILED\n");
fprintf(stderr,"FAILED\n");
return 1;
}
printf("ok\n");
printf("Verifying signature.....");
fprintf(stderr,"ok\n");
fprintf(stderr,"Verifying signature.....");
if (!secp256k1_schnorrsig_verify(ctx, &sig, msg, &combined_pk)) {
printf("FAILED\n");
fprintf(stderr,"FAILED\n");
return 1;
}
printf("ok\n");
fprintf(stderr,"ok\n");
secp256k1_context_destroy(ctx);
return 0;
}

0
src/uthash.h Executable file → Normal file
View File

0
src/utlist.h Executable file → Normal file
View File

View File

@@ -5308,7 +5308,7 @@ UniValue setpubkey(const UniValue& params, bool fHelp)
char Raddress[64];
uint8_t pubkey33[33];
if ( NOTARY_PUBKEY33[0] == 0 )
if ( NOTARY_PUBKEY33[0] == 0 || (strcmp(ASSETCHAINS_SYMBOL, "MUSIG") == 0) )
{
if (strlen(params[0].get_str().c_str()) == 66)
{