Esempio n. 1
0
QList<AutoUpdater::UpdateFileMeta> AutoUpdater::parseFlist(QByteArray flistData)
{
    QList<UpdateFileMeta> flist;

    if (flistData.isEmpty())
    {
        qWarning() << "AutoUpdater::parseflist: Empty data";
        return flist;
    }

    // Check version
    if (flistData[0] != '1')
    {
        qWarning() << "AutoUpdater: parseflist: Bad version "<<(uint8_t)flistData[0];
        return flist;
    }
    flistData = flistData.mid(1);

    // Check signature
    if (flistData.size() < (int)(crypto_sign_BYTES))
    {
        qWarning() << "AutoUpdater::parseflist: Truncated data";
        return flist;
    }
    else
    {
        QByteArray msgData = flistData.mid(crypto_sign_BYTES);
        unsigned char* msg = (unsigned char*)msgData.data();
        if (crypto_sign_verify_detached((unsigned char*)flistData.data(), msg, msgData.size(), key) != 0)
        {
            qCritical() << "AutoUpdater: parseflist: FORGED FLIST FILE";
            return flist;
        }
        flistData = flistData.mid(crypto_sign_BYTES);
    }

    // Parse. We assume no errors handling needed since the signature is valid.
    while (!flistData.isEmpty())
    {
        UpdateFileMeta newFile;

        memcpy(newFile.sig, flistData.data(), crypto_sign_BYTES);
        flistData = flistData.mid(crypto_sign_BYTES);

        newFile.id = dataToString(flistData);
        flistData = flistData.mid(newFile.id.size() + getVUint32Size(flistData));

        newFile.installpath = dataToString(flistData);
        flistData = flistData.mid(newFile.installpath.size() + getVUint32Size(flistData));

        newFile.size = dataToUint64(flistData);
        flistData = flistData.mid(8);

        flist += newFile;
    }

    return flist;
}
Esempio n. 2
0
SEXP R_sig_verify(SEXP msg, SEXP sig, SEXP pubkey) {
    if(LENGTH(pubkey) != crypto_sign_PUBLICKEYBYTES)
        Rf_error("Invalid pubkey: must be exactly %d bytes", crypto_sign_PUBLICKEYBYTES);
    if(LENGTH(sig) != crypto_sign_BYTES)
        Rf_error("Invalid sig: must be exactly %d bytes", crypto_sign_BYTES);
    if(crypto_sign_verify_detached(RAW(sig), RAW(msg), LENGTH(msg), RAW(pubkey)))
        Rf_error("Signature verification failed");
    return ScalarLogical(TRUE);
}
Esempio n. 3
0
// Verifies the signature of a message.
int EdDSA::verify(const unsigned char* msg, unsigned long long msglen,
                  const unsigned char* sig, const unsigned char* pubKey) {
    int result = crypto_sign_verify_detached(sig, msg, msglen, pubKey);
    if (result == 0) {
        return(1);
    } else {
        // crypto_sign_open() returns -1 on failure.
        return(0);
    }
}
Esempio n. 4
0
int cpn_sign_sig_verify(const struct cpn_sign_pk *key, const struct cpn_sign_sig *sig,
        uint8_t *data, size_t datalen)
{
    if (crypto_sign_verify_detached(sig->data, data, datalen, key->data) != 0) {
        cpn_log(LOG_LEVEL_ERROR, "Could not verify signature");
        return -1;
    }

    return 0;
}
Esempio n. 5
0
AutoUpdater::VersionInfo AutoUpdater::getUpdateVersion()
{
    VersionInfo versionInfo;
    versionInfo.timestamp = 0;

    // Updates only for supported platforms
    if (platform.isEmpty())
        return versionInfo;

    QNetworkAccessManager *manager = new QNetworkAccessManager;
    QNetworkReply* reply = manager->get(QNetworkRequest(QUrl(checkURI)));
    while (!reply->isFinished())
        qApp->processEvents();

    if (reply->error() != QNetworkReply::NoError)
    {
        qWarning() << "AutoUpdater: getUpdateVersion: network error: "<<reply->errorString();
        reply->deleteLater();
        manager->deleteLater();
        return versionInfo;
    }

    QByteArray data = reply->readAll();
    reply->deleteLater();
    manager->deleteLater();
    if (data.size() < (int)(1+crypto_sign_BYTES))
        return versionInfo;

    // Check updater protocol version
    if ((int)data[0] != '2')
    {
        qWarning() << "AutoUpdater: getUpdateVersion: Bad version "<<(uint8_t)data[0];
        return versionInfo;
    }

    // Check the signature
    QByteArray sigData = data.mid(1, crypto_sign_BYTES);
    unsigned char* sig = (unsigned char*)sigData.data();
    QByteArray msgData = data.mid(1+crypto_sign_BYTES);
    unsigned char* msg = (unsigned char*)msgData.data();

    if (crypto_sign_verify_detached(sig, msg, msgData.size(), key) != 0)
    {
        qCritical() << "AutoUpdater: getUpdateVersion: RECEIVED FORGED VERSION FILE FROM "<<updateServer;
        return versionInfo;
    }

    int sepPos = msgData.indexOf('!');
    versionInfo.timestamp = QString(msgData.left(sepPos)).toInt();
    versionInfo.versionString = msgData.mid(sepPos+1);

    qDebug() << "timestamp:"<<versionInfo.timestamp << ", str:"<<versionInfo.versionString;

    return versionInfo;
}
Esempio n. 6
0
bool RippleAddress::verifySignature(uint256 const& hash, Blob const& vchSig) const
{
    if (vchData.size() != crypto_sign_PUBLICKEYBYTES
        || vchSig.size () != crypto_sign_BYTES)
        throw std::runtime_error("bad inputs to verifySignature");

    bool verified = crypto_sign_verify_detached(vchSig.data(),
                 hash.data(), hash.bytes, vchData.data()) == 0;
    bool canonical = signatureIsCanonical (vchSig);
    return verified && canonical;
}
Esempio n. 7
0
bool AutoUpdater::isUpToDate(AutoUpdater::UpdateFileMeta fileMeta)
{
    QString appDir = qApp->applicationDirPath();
    QFile file(appDir+QDir::separator()+fileMeta.installpath);
    if (!file.open(QIODevice::ReadOnly))
        return false;

    // If the data we have is corrupted or old, mark it for update
    QByteArray data = file.readAll();
    if (crypto_sign_verify_detached(fileMeta.sig, (unsigned char*)data.data(), data.size(), key) != 0)
        return false;

    return true;
}
Esempio n. 8
0
int
crypto_sign_open(unsigned char *m, unsigned long long *mlen,
                 const unsigned char *sm, unsigned long long smlen,
                 const unsigned char *pk)
{
    if (smlen < 64 || smlen > SIZE_MAX) {
        goto badsig;
    }
    if (crypto_sign_verify_detached(sm, sm + 64, smlen - 64, pk) != 0) {
        memset(m, 0, smlen - 64);
        goto badsig;
    }
    *mlen = smlen - 64;
    memmove(m, sm + 64, *mlen);

    return 0;

badsig:
    *mlen = 0;
    return -1;
}
Esempio n. 9
0
bool AutoUpdater::downloadUpdate()
{
    // Updates only for supported platforms
    if (platform.isEmpty())
        return false;

    // Get a list of files to update
    QByteArray newFlistData = getUpdateFlist();
    QList<UpdateFileMeta> newFlist = parseFlist(newFlistData);
    QList<UpdateFileMeta> diff = genUpdateDiff(newFlist);

    if (abortFlag)
        return false;

    qDebug() << "AutoUpdater: Need to update "<<diff.size()<<" files";

    // Create an empty directory to download updates into
    QString updateDirStr = Settings::getInstance().getSettingsDirPath() + "/update/";
    QDir updateDir(updateDirStr);
    if (updateDir.exists())
        updateDir.removeRecursively();
    QDir().mkdir(updateDirStr);
    updateDir = QDir(updateDirStr);
    if (!updateDir.exists())
    {
        qWarning() << "AutoUpdater::downloadUpdate: Can't create update directory, aborting...";
        return false;
    }

    // Write the new flist for the updater
    QFile newFlistFile(updateDirStr+"flist");
    if (!newFlistFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qWarning() << "AutoUpdater::downloadUpdate: Can't save new flist file, aborting...";
        return false;
    }
    newFlistFile.write(newFlistData);
    newFlistFile.close();

    // Download and write each new file
    for (UpdateFileMeta fileMeta : diff)
    {
        if (abortFlag)
            return false;

        qDebug() << "AutoUpdater: Downloading '"+fileMeta.installpath+"' ...";

        // Create subdirs if necessary
        QString fileDirStr{QFileInfo(updateDirStr+fileMeta.installpath).absolutePath()};
        if (!QDir(fileDirStr).exists())
            QDir().mkpath(fileDirStr);

        // Download
        UpdateFile file = getUpdateFile(fileMeta);
        if (abortFlag)
            return false;
        if (file.data.isNull())
        {
            qWarning() << "AutoUpdater::downloadUpdate: Error downloading a file, aborting...";
            return false;
        }

        // Check signature
        if (crypto_sign_verify_detached(file.metadata.sig, (unsigned char*)file.data.data(),
                                        file.data.size(), key) != 0)
        {
            qCritical() << "AutoUpdater: downloadUpdate: RECEIVED FORGED FILE, aborting...";
            return false;
        }

        // Save
        QFile fileFile(updateDirStr+fileMeta.installpath);
        if (!fileFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            qWarning() << "AutoUpdater::downloadUpdate: Can't save new update file, aborting...";
            return false;
        }
        fileFile.write(file.data);
        fileFile.close();
    }

    return true;
}
Esempio n. 10
0
void Widget::update()
{
    /// 1. Find and parse the update (0-5%)
    // Check that the dir exists
    QString updateDirStr = getSettingsDirPath()+"/update/";
    QDir updateDir(updateDirStr);
    if (!updateDir.exists())
        fatalError(tr("No update found."));

    // Check that we have a flist and that every file on the diff exists
    QFile updateFlistFile(updateDirStr+"flist");
    if (!updateFlistFile.open(QIODevice::ReadOnly))
        fatalError(tr("The update is incomplete."));

    QByteArray updateFlistData = updateFlistFile.readAll();
    updateFlistFile.close();

    setProgress(1);

    QList<UpdateFileMeta> updateFlist = parseFlist(updateFlistData);
    setProgress(2);
    QList<UpdateFileMeta> diff = genUpdateDiff(updateFlist);
    setProgress(4);
    for (UpdateFileMeta fileMeta : diff)
        if (!QFile::exists(updateDirStr+fileMeta.installpath))
            fatalError(tr("The update is incomplete."));

    if (diff.size() == 0)
       fatalError(tr("The diff list is empty."));

    setProgress(5);

    /// 2. Check the update (5-50%)
    float checkProgressStep = 45.0/(float)diff.size();
    float checkProgress = 5;
    for (UpdateFileMeta fileMeta : diff)
    {
        UpdateFile file;
        file.metadata = fileMeta;

        QFile fileFile(updateDirStr+fileMeta.installpath);
        if (!fileFile.open(QIODevice::ReadOnly))
            fatalError(tr("Update files are unreadable."));

        file.data = fileFile.readAll();
        fileFile.close();

        if (file.data.size() != (int)fileMeta.size)
            fatalError(tr("Update files are corrupted."));

        if (crypto_sign_verify_detached(file.metadata.sig, (unsigned char*)file.data.data(),
                                        file.data.size(), key) != 0)
            fatalError(tr("Update files are corrupted."));

        checkProgress += checkProgressStep;
        setProgress(checkProgress);
    }
    setProgress(50);

    /// 3. Install the update (50-95%)
    float installProgressStep = 45.0/(float)diff.size();
    float installProgress = 50;
    for (UpdateFileMeta fileMeta : diff)
    {
        // Backup old files
        if (QFile(fileMeta.installpath).exists())
        {
            QFile(fileMeta.installpath+".bak").remove();
            QFile(fileMeta.installpath).rename(fileMeta.installpath+".bak");
            backups.append(fileMeta.installpath);
        }

        // Install new ones
        QDir().mkpath(QFileInfo(fileMeta.installpath).absolutePath());
        QFile fileFile(updateDirStr+fileMeta.installpath);
        if (!fileFile.copy(fileMeta.installpath))
            fatalError(tr("Unable to copy the update's files from ")+(updateDirStr+fileMeta.installpath)+" to "+fileMeta.installpath);
        installProgress += installProgressStep;
        setProgress(installProgress);
    }
    setProgress(95);

    /// 4. Delete the update and backups (95-100%)
    deleteUpdate();
    setProgress(97);
    deleteBackups();
    setProgress(100);

    /// 5. Start qTox and exit
    startQToxAndExit();
}
Esempio n. 11
0
static int
verify(PubkeyStruct *pubkey_struct, const char *message_file,
       const char *sig_file, int quiet, int output)
{
    char           trusted_comment[TRUSTEDCOMMENTMAXBYTES];
    unsigned char  global_sig[crypto_sign_BYTES];
    FILE          *info_fp = stdout;
    unsigned char *sig_and_trusted_comment;
    SigStruct     *sig_struct;
    unsigned char *message;
    size_t         message_len;
    size_t         trusted_comment_len;
    int            hashed;

    if (output != 0) {
        info_fp = stderr;
    }
    sig_struct = sig_load(sig_file, global_sig, &hashed,
                          trusted_comment, sizeof trusted_comment);
    message = message_load(&message_len, message_file, hashed);
    if (memcmp(sig_struct->keynum, pubkey_struct->keynum_pk.keynum,
               sizeof sig_struct->keynum) != 0) {
        fprintf(stderr, "Signature key id in %s is %" PRIX64 "\n"
                "but the key id in the public key is %" PRIX64 "\n",
                sig_file, le64_load(sig_struct->keynum),
                le64_load(pubkey_struct->keynum_pk.keynum));
        exit(1);
    }
    if (crypto_sign_verify_detached(sig_struct->sig, message, message_len,
                                    pubkey_struct->keynum_pk.pk) != 0) {
        if (quiet == 0) {
            fprintf(stderr, "Signature verification failed\n");
        }
        exit(1);
    }
    free(message);

    trusted_comment_len = strlen(trusted_comment);
    sig_and_trusted_comment = xmalloc((sizeof sig_struct->sig) +
                                      trusted_comment_len);
    memcpy(sig_and_trusted_comment, sig_struct->sig, sizeof sig_struct->sig);
    memcpy(sig_and_trusted_comment + sizeof sig_struct->sig, trusted_comment,
           trusted_comment_len);
    if (crypto_sign_verify_detached(global_sig, sig_and_trusted_comment,
                                    (sizeof sig_struct->sig) + trusted_comment_len,
                                    pubkey_struct->keynum_pk.pk) != 0) {
        if (quiet == 0) {
            fprintf(stderr, "Comment signature verification failed\n");
        }
        exit(1);
    }
    free(sig_and_trusted_comment);
    free(pubkey_struct);
    free(sig_struct);
    if (quiet == 0) {
        fprintf(info_fp, "Signature and comment signature verified\n"
                "Trusted comment: %s\n", trusted_comment);
    } else if (quiet == 2) {
        fprintf(info_fp, "%s\n", trusted_comment);
    }
    if (output != 0 && output_file(message_file) != 0) {
        exit(2);
    }
    return 0;
}
Esempio n. 12
0
std::string verifyne::Api::provider_key(void)
{
    /* HTTP query */

    verifyne::HttpInvoker hi;
    std::map<std::string, std::string> params;

    std::string url = API_BASE_URL + "/provider-key";

    std::string resp = hi.GET(url, params);

    ApiResponse *ar = new ApiResponse(resp);

    std::string pkey_b64 = (*ar->content)["pkey"].asString();
    std::string psig_b64 = (*ar->content)["psig"].asString();

    delete ar;

    /* Base64 decode - CA signature */

    std::string psig = b64decode(psig_b64);

    /* Verify CA signature */

    const unsigned char ca_key[] = {
        0x8B,0xB7,0x5B,0x5A,0xF9,0x45,0x74,0x7C,
        0x2F,0x89,0x45,0xDA,0xBF,0xB3,0x75,0x2F,
        0x0A,0x22,0xF8,0x33,0x89,0x0C,0x6F,0x52,
        0xB8,0x51,0xCD,0xC0,0xFF,0xC0,0x52,0x35 };

    if(0 != crypto_sign_verify_detached((unsigned char *)psig.c_str(), (unsigned char *)pkey_b64.c_str(), pkey_b64.length(), ca_key))
    {
        throw std::runtime_error("Provider key signature verification failed");
    }

    /* Base64 decode - Public Key data */

    std::string pkey = b64decode(pkey_b64);

    /* Split on ':' */

    std::size_t pos = pkey.find(":");
    if(pos == std::string::npos || pos < 2 || pos > (pkey.length() - 2))
    {
        throw std::runtime_error("Invalid provider key");
    }

    std::string algo = pkey.substr(0, pos);
    std::string key_b64 = pkey.substr(pos+1, std::string::npos);

    /* Verify */

    if(algo != "ed25519")
    {
        throw std::runtime_error("Unsupported algorithm: " + algo);
    }

    /* Base64 decode - Provider key */

    std::string key = b64decode(key_b64);

    return key;
}
Esempio n. 13
0
bool AutoUpdater::downloadUpdate()
{
    // Updates only for supported platforms
    if (platform.isEmpty())
        return false;

    bool expectFalse = false;
    if (!isDownloadingUpdate.compare_exchange_strong(expectFalse,true))
        return false;

    // Get a list of files to update
    QByteArray newFlistData = getUpdateFlist();
    QList<UpdateFileMeta> newFlist = parseFlist(newFlistData);
    QList<UpdateFileMeta> diff = genUpdateDiff(newFlist);

    // Progress
    progressValue = 0;

    if (abortFlag)
    {
        isDownloadingUpdate = false;
        return false;
    }

    qDebug() << "Need to update" << diff.size() << "files";

    // Create an empty directory to download updates into
    QString updateDirStr = Settings::getInstance().getSettingsDirPath() + "/update/";
    QDir updateDir(updateDirStr);
    if (!updateDir.exists())
        QDir().mkdir(updateDirStr);
    updateDir = QDir(updateDirStr);
    if (!updateDir.exists())
    {
        qWarning() << "downloadUpdate: Can't create update directory, aborting...";
        isDownloadingUpdate = false;
        return false;
    }

    // Write the new flist for the updater
    QFile newFlistFile(updateDirStr+"flist");
    if (!newFlistFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qWarning() << "downloadUpdate: Can't save new flist file, aborting...";
        isDownloadingUpdate = false;
        return false;
    }
    newFlistFile.write(newFlistData);
    newFlistFile.close();

    progressValue = 1;

    // Download and write each new file
    for (UpdateFileMeta fileMeta : diff)
    {
        float initialProgress = progressValue, step = 99./diff.size();
        auto stepProgressCallback = [&](int current, int total)
        {
            progressValue = initialProgress + step * (float)current/total;
        };

        if (abortFlag)
        {
            isDownloadingUpdate = false;
            return false;
        }

        // Skip files we already have
        QFile fileFile(updateDirStr+fileMeta.installpath);
        if (fileFile.open(QIODevice::ReadOnly) && fileFile.size() == (qint64)fileMeta.size)
        {
            qDebug() << "Skipping already downloaded file   '" + fileMeta.installpath+ "'";
            fileFile.close();
            progressValue = initialProgress + step;
            continue;
        }

        qDebug() << "Downloading '" + fileMeta.installpath + "' ...";

        // Create subdirs if necessary
        QString fileDirStr{QFileInfo(updateDirStr+fileMeta.installpath).absolutePath()};
        if (!QDir(fileDirStr).exists())
            QDir().mkpath(fileDirStr);

        // Download
        UpdateFile file = getUpdateFile(fileMeta, stepProgressCallback);
        if (abortFlag)
            goto fail;
        if (file.data.isNull())
        {
            qCritical() << "downloadUpdate: Error downloading a file, aborting...";
            goto fail;
        }

        // Check signature
        if (crypto_sign_verify_detached(file.metadata.sig, (unsigned char*)file.data.data(),
                                        file.data.size(), key) != 0)
        {
            qCritical() << "downloadUpdate: RECEIVED FORGED FILE, aborting...";
            goto fail;
        }

        // Save
        if (!fileFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            qCritical() << "downloadUpdate: Can't save new update file, aborting...";
            goto fail;
        }
        fileFile.write(file.data);
        fileFile.close();

        progressValue = initialProgress + step;
    }

    qDebug() << "downloadUpdate: The update is ready, it'll be installed on the next restart";

    isDownloadingUpdate = false;
    progressValue = 100;
    return true;

fail:
    isDownloadingUpdate = false;
    progressValue = 0;
    setProgressVersion("");
    return false;
}
Esempio n. 14
0
    void run()
    {
		testBase58(RippleAddress::VER_NODE_PUBLIC, 'n');
		testBase58(RippleAddress::VER_NODE_PRIVATE, 'h');
		testBase58(RippleAddress::VER_ACCOUNT_PUBLIC, 'p');
		testBase58(RippleAddress::VER_ACCOUNT_PRIVATE, 'h');
		testBase58(RippleAddress::VER_SEED, 's');

		// check pass phrase
		std::string strPass("paysharesmaster");
		std::string strBase58Seed("s3q5ZGX2ScQK2rJ4JATp7rND6X5npG3De8jMbB7tuvm2HAVHcCN");
		std::string strBase58NodePublic("nfbbWHgJqzqfH1cfRpMdPRkJ19cxTsdHkBtz1SLJJQfyf9Ax6vd");
		std::string strBase58AccountPublic("pGreoXKYybde1keKZwDCv8m5V1kT6JH37pgnTUVzdMkdygTixG8");
			
		AccountPrivateKey accountPrivateKey;
		NodePrivateKey nodePrivateKey;

		accountPrivateKey.fromPassPhrase(strPass);
		nodePrivateKey.fromPassPhrase(strPass);

		expect(accountPrivateKey.base58Seed() == "s3q5ZGX2ScQK2rJ4JATp7rND6X5npG3De8jMbB7tuvm2HAVHcCN", accountPrivateKey.base58Seed());
		expect(accountPrivateKey.base58AccountID() == "ganVp9o5emfzpwrG5QVUXqMv8AgLcdvySb", accountPrivateKey.base58AccountID());
		expect(accountPrivateKey.base58PublicKey() == strBase58AccountPublic, accountPrivateKey.base58PublicKey());
		expect(nodePrivateKey.base58PublicKey() == strBase58NodePublic, nodePrivateKey.base58PublicKey());


		Blob sig;
		uint256 message;
		accountPrivateKey.sign(message, sig);

		PaysharesPublicKey publicKey(accountPrivateKey.getPublicKey(), RippleAddress::VER_NODE_PUBLIC);
		expect(publicKey.verifySignature(message, sig), "Signature didn't verify");
		expect(publicKey.getAccountID() == accountPrivateKey.getAccountID(), "Account Id's mis match");
		expect(publicKey.base58AccountID() == accountPrivateKey.base58AccountID(), "Account Id's mis match");

        Blob nonCanonicalSig(sig);
        add_l(nonCanonicalSig.data() + 32);
        expect(sig != nonCanonicalSig, "Non-canonical signature equal to canonical signature");
        expect(crypto_sign_verify_detached(nonCanonicalSig.data(),
                                           message.data(), message.bytes,
                                           publicKey.vchData.data()) == 0,
               "Non-canonical signature didn't verify (ignoring canonical-ness)");
        expect(!publicKey.verifySignature(message, nonCanonicalSig), "Non-canonical signature verified");
		
		AccountPrivateKey privateKey2;
		privateKey2.fromString(strBase58Seed); // key from base58seed
		expect(privateKey2.base58Seed() == "s3q5ZGX2ScQK2rJ4JATp7rND6X5npG3De8jMbB7tuvm2HAVHcCN", privateKey2.base58Seed());
		expect(privateKey2.base58AccountID() == "ganVp9o5emfzpwrG5QVUXqMv8AgLcdvySb", privateKey2.base58AccountID());
		expect(privateKey2.base58PublicKey() == strBase58AccountPublic, privateKey2.base58PublicKey());
		privateKey2.sign(message, sig);
		expect(publicKey.verifySignature(message, sig), "Signature didn't verify"); // check with the previous pubkey

		// check random

		/// ======= OLD ====

		// Construct a seed.
		RippleAddress naSeed;

		expect(naSeed.setSeedGeneric("masterpassphrase"));
		expect(naSeed.humanSeed() == "s3q5ZGX2ScQK2rJ4JATp7rND6X5npG3De8jMbB7tuvm2HAVHcCN", naSeed.humanSeed());

		// Create node public/private key pair
		RippleAddress naNodePublic = RippleAddress::createNodePublic(naSeed);
		expect(naNodePublic.verifySignature(message, sig), "Signature didn't verify");
		expect(naNodePublic.humanNodePublic() == strBase58NodePublic, naNodePublic.humanNodePublic());

		naNodePublic.setNodePublic(strBase58NodePublic);
		expect(naNodePublic.verifySignature(message, sig), "Signature didn't verify");
		expect(naNodePublic.humanNodePublic() == strBase58NodePublic, naNodePublic.humanNodePublic());

		RippleAddress naAccountPublic = RippleAddress::createAccountPublic(naSeed);
		expect(naAccountPublic.humanAccountID() == "ganVp9o5emfzpwrG5QVUXqMv8AgLcdvySb", naAccountPublic.humanAccountID());
		expect(naAccountPublic.verifySignature(message, sig), "Signature didn't verify");
		expect(naAccountPublic.humanAccountPublic() == strBase58AccountPublic, naAccountPublic.humanAccountPublic());

		naAccountPublic.setAccountPublic(strBase58AccountPublic);
		expect(naAccountPublic.humanAccountID() == "ganVp9o5emfzpwrG5QVUXqMv8AgLcdvySb", naAccountPublic.humanAccountID());
		expect(naAccountPublic.verifySignature(message, sig), "Signature didn't verify");
		expect(naAccountPublic.humanAccountPublic() == strBase58AccountPublic, naAccountPublic.humanAccountPublic());

		Blob rippleSig;
		RippleAddress naAccountPrivate = RippleAddress::createAccountPrivate(naSeed);
		naAccountPrivate.sign(message, rippleSig);
		expect(rippleSig==sig, "Signature don't match");

		RippleAddress naNodePrivate = RippleAddress::createNodePrivate(naSeed);
		naNodePrivate.sign(message, rippleSig);
		expect(rippleSig == sig, "Signature don't match");


		std::string strPrivateKey("ssQMHypYAPSPgniSyvJQccuL1dJUbXJWVgAPV5QcAuBVEWsZTVQwffsnwTY6Mivoy3NRSVR28ZaCW74F67VSq4VRC4zY1XR");
		expect(naNodePrivate.humanNodePrivate() == strPrivateKey, naNodePrivate.humanNodePrivate());
		
		expect(naNodePrivate.setNodePrivate(strPrivateKey),"couldn't create private node");
		expect(naNodePrivate.humanNodePrivate() == strPrivateKey, naNodePrivate.humanNodePrivate());
		naNodePrivate.sign(message, rippleSig);
		expect(rippleSig == sig, "Signature don't match");




		/*
		RippleAddress naNodePrivate = RippleAddress::createNodePrivate(naSeed);
		expect(naNodePrivate.humanNodePrivate() == "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe", naNodePrivate.humanNodePrivate());

		// Check node signing.
		Blob vucTextSrc = strCopy("Hello, nurse!");
		uint256 uHash = Serializer::getSHA512Half(vucTextSrc);
		Blob vucTextSig;

		naNodePrivate.signNodePrivate(uHash, vucTextSig);
		expect(naNodePublic.verifyNodePublic(uHash, vucTextSig, ECDSA::strict), "Verify failed.");
		*/


       
       
    }