X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fkey.h;h=c0fce18bf3c5e62a15b1554c701ae9ba4b1393e9;hb=acd6501610817eee0bd1c8ea9c591f043affbaec;hp=c973d6eb82f9fd769da91329775bf83e736cb951;hpb=e94010b2395694d56dd62a2cb956a40ef801a191;p=novacoin.git diff --git a/src/key.h b/src/key.h index c973d6e..c0fce18 100644 --- a/src/key.h +++ b/src/key.h @@ -31,6 +31,41 @@ // see www.keylength.com // script supports up to 75 for single byte push +int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) +{ + int ok = 0; + BN_CTX *ctx = NULL; + EC_POINT *pub_key = NULL; + + if (!eckey) return 0; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + pub_key = EC_POINT_new(group); + + if (pub_key == NULL) + goto err; + + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) + goto err; + + EC_KEY_set_private_key(eckey,priv_key); + EC_KEY_set_public_key(eckey,pub_key); + + ok = 1; + +err: + + if (pub_key) + EC_POINT_free(pub_key); + if (ctx != NULL) + BN_CTX_free(ctx); + + return(ok); +} class key_error : public std::runtime_error @@ -42,8 +77,7 @@ public: // secure_allocator is defined in serialize.h typedef std::vector > CPrivKey; - - +typedef std::vector > CSecret; class CKey { @@ -102,6 +136,38 @@ public: return true; } + bool SetSecret(const CSecret& vchSecret) + { + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); + if (vchSecret.size() != 32) + throw key_error("CKey::SetSecret() : secret must be 32 bytes"); + BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new()); + if (bn == NULL) + throw key_error("CKey::SetSecret() : BN_bin2bn failed"); + if (!EC_KEY_regenerate_key(pkey,bn)) + throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); + BN_clear_free(bn); + fSet = true; + return true; + } + + CSecret GetSecret() const + { + CSecret vchRet; + vchRet.resize(32); + const BIGNUM *bn = EC_KEY_get0_private_key(pkey); + int nBytes = BN_num_bytes(bn); + if (bn == NULL) + throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed"); + int n=BN_bn2bin(bn,&vchRet[32 - nBytes]); + if (n != nBytes) + throw key_error("CKey::GetSecret(): BN_bn2bin failed"); + return vchRet; + } + CPrivKey GetPrivKey() const { unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);