예제 #1
0
//Сумма 2-х точек
//a4=A
//a6=B
//a1,a2,a3=0
ec_point ec_point::operator +(ec_point op2){
	ec_curve * ec_singleton = ec_curve::Instance();
	ZZ x3,y3,lambda,nu;
	//Обработка случаев, если среди операндов нуль группы
	if (is_infinity() && op2.is_infinity()) return ec_point(true);
	if (is_infinity()) return ec_point(op2.x,op2.y);
	if (op2.is_infinity()) return ec_point(x,y);

	//Нулей нет, дальше всё по Вейерштрассу
	if ((x==op2.x) && (y==NegateMod(op2.y,ec_singleton->p))) {
		//Если две противоположные точки, результатом будет нуль группы
		return ec_point(true);
		}
	else {
		if (x!=op2.x) { //Если сладываем две разные точки
			lambda = (((op2.y-y)%ec_singleton->p) * InvMod((op2.x-x)%ec_singleton->p,ec_singleton->p))%ec_singleton->p;
			}
		else { //Если удваиваем точку
			lambda = ((3*x*x+ec_singleton->A)%ec_singleton->p * InvMod((2*y)%ec_singleton->p,ec_singleton->p))%ec_singleton->p;
			}
		x3 = (lambda*lambda - x - op2.x)%ec_singleton->p;
		y3 = (lambda*(x-x3)-y)%ec_singleton->p;
		return ec_point(x3,y3);
		}
	}
예제 #2
0
payment_address bidding_address(const ec_point& pubkey)
{
    data_chunk data(pubkey.begin(), pubkey.end());
    payment_address payaddr;
    set_public_key(payaddr, data);
    return payaddr;
}
예제 #3
0
bool verify_public_key_fast(const ec_point& public_key)
{
    if (public_key.size() == ec_compressed_size)
        return public_key[0] == 0x02 || public_key[0] == 0x03;
    if (public_key.size() == ec_uncompressed_size)
        return public_key[0] == 0x04;
    return false;
}
예제 #4
0
bool verify_signature(const ec_point& public_key, hash_digest hash,
    const endorsement& signature)
{
    init.init();
    return 1 == secp256k1_ecdsa_verify(hash.data(), hash.size(),
        signature.data(), signature.size(), public_key.data(),
        public_key.size()
    );
}
예제 #5
0
파일: openssl.cpp 프로젝트: xdv/divvyd
void add_to (EC_GROUP const* group,
             ec_point const& a,
             ec_point& b,
             bn_ctx& ctx)
{
    if (!EC_POINT_add (group, b.get(), a.get(), b.get(), ctx.get()))
    {
        throw std::runtime_error ("EC_POINT_add() failed");
    }
}
예제 #6
0
bool verify_signature(const ec_point& public_key, hash_digest hash,
    const data_chunk& signature)
{
    std::reverse(hash.begin(), hash.end());
    init.init();
    return 1 == secp256k1_ecdsa_verify(
        hash.data(), hash.size(),
        signature.data(), signature.size(),
        public_key.data(), public_key.size()
    );
}
예제 #7
0
int main(int argc, char** argv)
{
    if (argc != 4)
    {
        std::cerr << "Usage: pp_unlock CHUNKFILE BLOCK_HASH PUBKEY"
            << std::endl;
        return -1;
    }
    const std::string chunk_filename = argv[1];
    const data_chunk hash = decode_hex(argv[2]);
    if (hash.empty() || hash.size() != hash_size)
    {
        std::cerr << "pp_unlock: not a valid BLOCK_HASH." << std::endl;
        return -1;
    }
    const ec_point pubkey = decode_hex(argv[3]);
    if (pubkey.empty() || pubkey.size() != ec_compressed_size)
    {
        std::cerr << "pp_unlock: not a valid PUBKEY." << std::endl;
        return -1;
    }
    std::ifstream infile(chunk_filename, std::ifstream::binary);
    infile.seekg(0, std::ifstream::end);
    size_t file_size = infile.tellg();
    BITCOIN_ASSERT(file_size % 16 == 0);
    infile.seekg(0, std::ifstream::beg);
    // Read entire file in.
    data_chunk cipher(file_size);
    // Copy chunk to public chunk file.
    char* data = reinterpret_cast<char*>(cipher.data());
    infile.read(data, file_size);
    infile.close();
    // Get seed.
    payment_address bid_addr = bidding_address(pubkey);
    hash_digest seed = derive_seed(pubkey);
    // Decrypt chunk.
    aes256_context ctx; 
    BITCOIN_ASSERT(seed.size() == 32);
    aes256_init(&ctx, seed.data());
    BITCOIN_ASSERT(cipher.size() % 16 == 0);
    for (size_t i = 0; i < cipher.size(); i += 16)
        aes256_decrypt_ecb(&ctx, cipher.data() + i);
    aes256_done(&ctx);
    // Write out.
    const fs::path new_chunk_filename = (chunk_filename + ".decrypted");
    std::ofstream outfile(new_chunk_filename.native(), std::ifstream::binary);
    char* dec_data = reinterpret_cast<char*>(cipher.data());
    outfile.write(dec_data, cipher.size());
    return 0;
}
예제 #8
0
int generateKeyImage(ec_point &publicKey, ec_secret secret, ec_point &keyImage)
{
    // - keyImage = secret * hash(publicKey) * G

    if (publicKey.size() != EC_COMPRESSED_SIZE)
        return errorN(1, "%s: Invalid publicKey.", __func__);

    BN_CTX_start(bnCtx);
    int rv = 0;
    BIGNUM *bnTmp = BN_CTX_get(bnCtx);
    BIGNUM *bnSec = BN_CTX_get(bnCtx);
    EC_POINT *hG    = NULL;

    if (!(hG = EC_POINT_new(ecGrp))
    && (rv = errorN(1, "%s: EC_POINT_new failed.", __func__)))
        goto End;

    if (hashToEC(&publicKey[0], publicKey.size(), bnTmp, hG)
    && (rv = errorN(1, "%s: hashToEC failed.", __func__)))
        goto End;

    if (!(BN_bin2bn(&secret.e[0], EC_SECRET_SIZE, bnSec))
    && (rv = errorN(1, "%s: BN_bin2bn failed.", __func__)))
        goto End;

    if (!EC_POINT_mul(ecGrp, hG, NULL, hG, bnSec, bnCtx)
    && (rv = errorN(1, "%s: kimg EC_POINT_mul failed.", __func__)))
        goto End;

    try { keyImage.resize(EC_COMPRESSED_SIZE); } catch (std::exception& e)
    {
        LogPrintf("%s: keyImage.resize threw: %s.\n", __func__, e.what());
        rv = 1; goto End;
    }

    if ((!(EC_POINT_point2bn(ecGrp, hG, POINT_CONVERSION_COMPRESSED, bnTmp, bnCtx))
        || BN_num_bytes(bnTmp) != (int) EC_COMPRESSED_SIZE
        || BN_bn2bin(bnTmp, &keyImage[0]) != (int) EC_COMPRESSED_SIZE)
    && (rv = errorN(1, "%s: point -> keyImage failed.", __func__)))
        goto End;

    if (fDebugRingSig)
        LogPrintf("keyImage %s\n", HexStr(keyImage).c_str());

    End:
    EC_POINT_free(hG);
    BN_CTX_end(bnCtx);

    return rv;
};
예제 #9
0
int getOldKeyImage(CPubKey &publicKey, ec_point &keyImage)
{
    // - PublicKey * Hash(PublicKey)
    if (publicKey.size() != EC_COMPRESSED_SIZE)
        return errorN(1, "%s: Invalid publicKey.", __func__);

    int rv = 0;

    uint256 pkHash = publicKey.GetHash();

    BN_CTX_start(bnCtx);
    BIGNUM *bnTmp = BN_CTX_get(bnCtx);
    EC_POINT *ptPk = NULL;

    // Hash to BIGNUM
    if (!BN_bin2bn(pkHash.begin(), EC_SECRET_SIZE, bnTmp)
    && (rv = errorN(1, "%s: BN_bin2bn failed.", __func__)))
        goto End;

    // PublicKey point
    if (!(ptPk = EC_POINT_new(ecGrp))
    && (rv = errorN(1, "%s: EC_POINT_new failed.", __func__)))
        goto End;

    if(!EC_POINT_oct2point(ecGrp, ptPk, publicKey.begin(), EC_COMPRESSED_SIZE, bnCtx)
    && (rv = errorN(1, "%s: EC_POINT_oct2point failed.", __func__)))
        goto End;

    // PublicKey * Hash(PublicKey)
    if (!EC_POINT_mul(ecGrp, ptPk, NULL, ptPk, bnTmp, bnCtx)
    && (rv = errorN(1, "%s: EC_POINT_mul failed.", __func__)))
        goto End;

    try { keyImage.resize(EC_COMPRESSED_SIZE); } catch (std::exception& e)
    {
        LogPrintf("%s: keyImage.resize threw: %s.\n", __func__, e.what());
        rv = 1; goto End;
    }

    // Point to BIGNUM to bin
    if (!(EC_POINT_point2bn(ecGrp, ptPk, POINT_CONVERSION_COMPRESSED, bnTmp, bnCtx))
     ||BN_num_bytes(bnTmp) != (int) EC_COMPRESSED_SIZE
     ||BN_bn2bin(bnTmp, &keyImage[0]) != (int) EC_COMPRESSED_SIZE)
        rv = errorN(1, "%s: point -> keyImage failed.", __func__);

    End:
    EC_POINT_free(ptPk);
    BN_CTX_end(bnCtx);

    return 0;
}
예제 #10
0
int SecretToPublicKey(const ec_secret& secret, ec_point& out)
{
    // -- public key = private * G
    int rv = 0;
    
    EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
    
    if (!ecgrp)
    {
        LogPrintf("SecretToPublicKey(): EC_GROUP_new_by_curve_name failed.\n");
        return 1;
    };

    BIGNUM* bnIn = BN_bin2bn(&secret.e[0], ec_secret_size, BN_new());
    if (!bnIn)
    {
        EC_GROUP_free(ecgrp);
        LogPrintf("SecretToPublicKey(): BN_bin2bn failed\n");
        return 1;
    };
    
    EC_POINT* pub = EC_POINT_new(ecgrp);
    
    
    EC_POINT_mul(ecgrp, pub, bnIn, NULL, NULL, NULL);
    
    BIGNUM* bnOut = EC_POINT_point2bn(ecgrp, pub, POINT_CONVERSION_COMPRESSED, BN_new(), NULL);
    if (!bnOut)
    {
        LogPrintf("SecretToPublicKey(): point2bn failed\n");
        rv = 1;
    } else
    {
        out.resize(ec_compressed_size);
        if (BN_num_bytes(bnOut) != (int) ec_compressed_size
            || BN_bn2bin(bnOut, &out[0]) != (int) ec_compressed_size)
        {
            LogPrintf("SecretToPublicKey(): bnOut incorrect length.\n");
            rv = 1;
        };
        
        BN_free(bnOut);
    };
    
    
    EC_POINT_free(pub);
    BN_free(bnIn);
    EC_GROUP_free(ecgrp);
    
    return rv;
};
예제 #11
0
파일: openssl.cpp 프로젝트: xdv/divvyd
void serialize_ec_point (ec_point const& point, std::uint8_t* ptr)
{
    ec_key key = ec_key_new_secp256k1_compressed();

    if (EC_KEY_set_public_key((EC_KEY*) key.get(), point.get()) <= 0)
    {
        throw std::runtime_error ("EC_KEY_set_public_key() failed");
    }

    int const size = i2o_ECPublicKey ((EC_KEY*) key.get(), &ptr);

    assert (size <= 33);
    (void) size;
}
예제 #12
0
//Функция для использования в бинарном поиске
//Считает одинаковыми точку и обратную ей ( x-координаты совпадают)
//Порядок задаётся сравнением x-координаты точек
//Нуль группы считается меньше любой точки
int ec_compare_bs(ec_point ec1, ec_point ec2) {
	if (!ec1.is_infinity() && !ec2.is_infinity()) {
		if (ec1.x>ec2.x) return 1;
		else if (ec1.x<ec2.x) return -1;
		else if (ec1.x==ec2.x) {
			return 0;
			}
		}
	else if (ec1.is_infinity() && ec2.is_infinity())
		return 0;
	else if (ec1.is_infinity() && !ec2.is_infinity())
		return -1;
	else if (!ec1.is_infinity() && ec2.is_infinity())
		return 1;

	}
예제 #13
0
void tau(ec_point& X) {
ZZ auxQ,auxP;
if (X.get_x()<one_third) {
	auxQ=X.auxQ+1;
	auxP=X.auxP;
	X=X+Q;
	X.auxQ = auxQ%r;
	X.auxP = auxP%r;
	}
else if (X.get_x()>one_third && X.get_x()<two_third) {
	auxQ=2*X.auxQ;
	auxP=2*X.auxP;
	X=X*to_ZZ(2);
	X.auxQ = auxQ%r;
	X.auxP = auxP%r;
	}
else {
	auxQ=X.auxQ+2;
	auxP=X.auxP;
	X=X+Q*to_ZZ(2);
	X.auxQ = auxQ%r;
	X.auxP = auxP%r;
	}
}
예제 #14
0
stealth_address::stealth_address(const binary_type& prefix,
    const ec_point& scan_pubkey, const pubkey_list& spend_pubkeys,
    uint8_t signatures, bool testnet)
{
    // Guard against uncompressed pubkey or junk data.
    if (scan_pubkey.size() != compressed_pubkey_size)
        return;

    // Guard against uncompressed pubkey or junk data.
    for (const auto& spend_pubkey: spend_pubkeys)
        if (spend_pubkey.size() != compressed_pubkey_size)
            return;

    // Apply 'reuse'.
    auto spend_points = spend_pubkeys;
    if (spend_points.empty())
        spend_points.push_back(scan_pubkey);

    // Guard against too many keys.
    auto spend_pubkeys_size = spend_points.size();
    if (spend_pubkeys_size > max_spend_key_count)
        return;

    // Guard against prefix too long.
    auto prefix_number_bits = static_cast<uint8_t>(prefix.size());
    if (prefix_number_bits > max_prefix_bits)
        return;

    // Coerce signatures to a valid range.
    if (signatures == 0 || signatures > spend_pubkeys_size)
        signatures_ = static_cast<uint8_t>(spend_pubkeys_size);
    else
        signatures_ = signatures;

    prefix_ = prefix;
    testnet_ = testnet;
    scan_pubkey_ = scan_pubkey;
    spend_pubkeys_ = spend_points;
    valid_ = true;
}
예제 #15
0
int StealthSecret(ec_secret& secret, ec_point& pubkey, const ec_point& pkSpend, ec_secret& sharedSOut, ec_point& pkOut)
{
    /*
    
    send:
        secret = ephem_secret, pubkey = scan_pubkey
    
    receive:
        secret = scan_secret, pubkey = ephem_pubkey
        c = H(dP)
    
    Q = public scan key (EC point, 33 bytes)
    d = private scan key (integer, 32 bytes)
    R = public spend key
    f = private spend key

    Q = dG  //单次使用的私钥
    R = fG
    
    Sender (has Q and R, not d or f):
    
    P = eG

    c = H(eQ) = H(dP)
    R' = R + cG
    
    
    Recipient gets R' and P
    
    test 0 and infinity?
    */
    
    int rv = 0;
    std::vector<uint8_t> vchOutQ;
    
    BN_CTX* bnCtx   = NULL;
    BIGNUM* bnEphem = NULL;
    BIGNUM* bnQ     = NULL;
    EC_POINT* Q     = NULL;
    BIGNUM* bnOutQ  = NULL;
    BIGNUM* bnc     = NULL;
    EC_POINT* C     = NULL;
    BIGNUM* bnR     = NULL;
    EC_POINT* R     = NULL;
    EC_POINT* Rout  = NULL;
    BIGNUM* bnOutR  = NULL;
    
    EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
    
    if (!ecgrp)
    {
        printf("StealthSecret(): EC_GROUP_new_by_curve_name failed.\n");
        return 1;
    };
    
    if (!(bnCtx = BN_CTX_new()))
    {
        printf("StealthSecret(): BN_CTX_new failed.\n");
        rv = 2;
        goto End;
    };
    
    if (!(bnEphem = BN_bin2bn(&secret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecret(): bnEphem BN_bin2bn failed.\n");
        rv = 3;
        goto End;
    };
    
    if (!(bnQ = BN_bin2bn(&pubkey[0], pubkey.size(), BN_new())))
    {
        printf("StealthSecret(): bnQ BN_bin2bn failed\n");
        rv = 4;
        goto End;
    };
    
    if (!(Q = EC_POINT_bn2point(ecgrp, bnQ, NULL, bnCtx)))
    {
        printf("StealthSecret(): Q EC_POINT_bn2point failed\n");
        rv = 5;
        goto End;
    };
    
    // -- eQ
    // EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
    // EC_POINT_mul calculates the value generator * n + q * m and stores the result in r. The value n may be NULL in which case the result is just q * m. 
    if (!EC_POINT_mul(ecgrp, Q, NULL, Q, bnEphem, bnCtx))
    {
        printf("StealthSecret(): eQ EC_POINT_mul failed\n");
        rv = 6;
        goto End;
    };
    
    if (!(bnOutQ = EC_POINT_point2bn(ecgrp, Q, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx)))
    {
        printf("StealthSecret(): Q EC_POINT_bn2point failed\n");
        rv = 7;
        goto End;
    };
    
    
    vchOutQ.resize(ec_compressed_size);
    if (BN_num_bytes(bnOutQ) != (int) ec_compressed_size
        || BN_bn2bin(bnOutQ, &vchOutQ[0]) != (int) ec_compressed_size)
    {
        printf("StealthSecret(): bnOutQ incorrect length.\n");
        rv = 8;
        goto End;
    };
    
    SHA256(&vchOutQ[0], vchOutQ.size(), &sharedSOut.e[0]);
    
    if (!(bnc = BN_bin2bn(&sharedSOut.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecret(): BN_bin2bn failed\n");
        rv = 9;
        goto End;
    };
    
    // -- cG
    if (!(C = EC_POINT_new(ecgrp)))
    {
        printf("StealthSecret(): C EC_POINT_new failed\n");
        rv = 10;
        goto End;
    };
    
    if (!EC_POINT_mul(ecgrp, C, bnc, NULL, NULL, bnCtx))
    {
        printf("StealthSecret(): C EC_POINT_mul failed\n");
        rv = 11;
        goto End;
    };
    
    if (!(bnR = BN_bin2bn(&pkSpend[0], pkSpend.size(), BN_new())))
    {
        printf("StealthSecret(): bnR BN_bin2bn failed\n");
        rv = 12;
        goto End;
    };
    
    
    if (!(R = EC_POINT_bn2point(ecgrp, bnR, NULL, bnCtx)))
    {
        printf("StealthSecret(): R EC_POINT_bn2point failed\n");
        rv = 13;
        goto End;
    };
    
    if (!EC_POINT_mul(ecgrp, C, bnc, NULL, NULL, bnCtx))
    {
        printf("StealthSecret(): C EC_POINT_mul failed\n");
        rv = 14;
        goto End;
    };
    
    if (!(Rout = EC_POINT_new(ecgrp)))
    {
        printf("StealthSecret(): Rout EC_POINT_new failed\n");
        rv = 15;
        goto End;
    };
    
    if (!EC_POINT_add(ecgrp, Rout, R, C, bnCtx))
    {
        printf("StealthSecret(): Rout EC_POINT_add failed\n");
        rv = 16;
        goto End;
    };
    
    if (!(bnOutR = EC_POINT_point2bn(ecgrp, Rout, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx)))
    {
        printf("StealthSecret(): Rout EC_POINT_bn2point failed\n");
        rv = 17;
        goto End;
    };
    
    
    pkOut.resize(ec_compressed_size);
    if (BN_num_bytes(bnOutR) != (int) ec_compressed_size
        || BN_bn2bin(bnOutR, &pkOut[0]) != (int) ec_compressed_size)
    {
        printf("StealthSecret(): pkOut incorrect length.\n");
        rv = 18;
        goto End;
    };
    
    End:
    if (bnOutR)     BN_free(bnOutR);
    if (Rout)       EC_POINT_free(Rout);
    if (R)          EC_POINT_free(R);
    if (bnR)        BN_free(bnR);
    if (C)          EC_POINT_free(C);
    if (bnc)        BN_free(bnc);
    if (bnOutQ)     BN_free(bnOutQ);
    if (Q)          EC_POINT_free(Q);
    if (bnQ)        BN_free(bnQ);
    if (bnEphem)    BN_free(bnEphem);
    if (bnCtx)      BN_CTX_free(bnCtx);
    EC_GROUP_free(ecgrp);
    
    return rv;
};
예제 #16
0
int StealthSecretSpend(ec_secret& scanSecret, ec_point& ephemPubkey, ec_secret& spendSecret, ec_secret& secretOut)
{
    /*
    
    c  = H(dP)
    R' = R + cG     [without decrypting wallet]
       = (f + c)G   [after decryption of wallet]
         Remember: mod curve.order, pad with 0x00s where necessary?
    */
    
    int rv = 0;
    std::vector<uint8_t> vchOutP;
    
    BN_CTX* bnCtx           = NULL;
    BIGNUM* bnScanSecret    = NULL;
    BIGNUM* bnP             = NULL;
    EC_POINT* P             = NULL;
    BIGNUM* bnOutP          = NULL;
    BIGNUM* bnc             = NULL;
    BIGNUM* bnOrder         = NULL;
    BIGNUM* bnSpend         = NULL;
    
    EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
    
    if (!ecgrp)
    {
        printf("StealthSecretSpend(): EC_GROUP_new_by_curve_name failed.\n");
        return 1;
    };
    
    if (!(bnCtx = BN_CTX_new()))
    {
        printf("StealthSecretSpend(): BN_CTX_new failed.\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnScanSecret = BN_bin2bn(&scanSecret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): bnScanSecret BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnP = BN_bin2bn(&ephemPubkey[0], ephemPubkey.size(), BN_new())))
    {
        printf("StealthSecretSpend(): bnP BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(P = EC_POINT_bn2point(ecgrp, bnP, NULL, bnCtx)))
    {
        printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };
    
    // -- dP
    if (!EC_POINT_mul(ecgrp, P, NULL, P, bnScanSecret, bnCtx))
    {
        printf("StealthSecretSpend(): dP EC_POINT_mul failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnOutP = EC_POINT_point2bn(ecgrp, P, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx)))
    {
        printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };
    
    
    vchOutP.resize(ec_compressed_size);
    if (BN_num_bytes(bnOutP) != (int) ec_compressed_size
        || BN_bn2bin(bnOutP, &vchOutP[0]) != (int) ec_compressed_size)
    {
        printf("StealthSecretSpend(): bnOutP incorrect length.\n");
        rv = 1;
        goto End;
    };
    
    uint8_t hash1[32];
    SHA256(&vchOutP[0], vchOutP.size(), (uint8_t*)hash1);
    
    
    if (!(bnc = BN_bin2bn(&hash1[0], 32, BN_new())))
    {
        printf("StealthSecretSpend(): BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnOrder = BN_new())
        || !EC_GROUP_get_order(ecgrp, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): EC_GROUP_get_order failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnSpend = BN_bin2bn(&spendSecret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): bnSpend BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };
    
    //if (!BN_add(r, a, b)) return 0;
    //return BN_nnmod(r, r, m, ctx);
    if (!BN_mod_add(bnSpend, bnSpend, bnc, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): bnSpend BN_mod_add failed.\n");
        rv = 1;
        goto End;
    };
    
    if (BN_is_zero(bnSpend)) // possible?
    {
        printf("StealthSecretSpend(): bnSpend is zero.\n");
        rv = 1;
        goto End;
    };
    
    if (BN_num_bytes(bnSpend) != (int) ec_secret_size
        || BN_bn2bin(bnSpend, &secretOut.e[0]) != (int) ec_secret_size)
    {
        printf("StealthSecretSpend(): bnSpend incorrect length.\n");
        rv = 1;
        goto End;
    };
    
    End:
    if (bnSpend)        BN_free(bnSpend);
    if (bnOrder)        BN_free(bnOrder);
    if (bnc)            BN_free(bnc);
    if (bnOutP)         BN_free(bnOutP);
    if (P)              EC_POINT_free(P);
    if (bnP)            BN_free(bnP);
    if (bnScanSecret)   BN_free(bnScanSecret);
    if (bnCtx)          BN_CTX_free(bnCtx);
    EC_GROUP_free(ecgrp);
    
    return rv;
};
예제 #17
0
hash_digest derive_seed(const ec_point& pubkey)
{
    data_chunk data(pubkey.begin(), pubkey.end());
    return bitcoin_hash(data);
}
예제 #18
0
bool ec_tweak_add(ec_point& a, const ec_secret& b)
{
    init.init();
    return secp256k1_ec_pubkey_tweak_add(init.getContext(), a.data(), a.size(), b.data());
}
예제 #19
0
bool ec_add(ec_point& a, const ec_secret& b)
{
    init.init();
    return secp256k1_ec_pubkey_tweak_add(a.data(), a.size(), b.data()) == 1;
}
예제 #20
0
bool ec_multiply(ec_point& a, const ec_secret& b)
{
    init.init();
    return secp256k1_ecdsa_pubkey_tweak_mul(a.data(), a.size(), b.data()) == 1;
}
예제 #21
0
bool verify_public_key(const ec_point& public_key)
{
    init.init();
    return secp256k1_ecdsa_pubkey_verify(public_key.data(), public_key.size())
        == 1;
}