text: // Copyright (c) 2012-2013 The Bitcoin Core developers
  // Copyright (c) 2017-2019 The PIVX developers
  // Copyright (c) 2021- The ORO developers
  // Distributed under the MIT/X11 software license, see the accompanying
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  
  #include "key.h"
  
  #include "base58.h"
  #include "script/script.h"
  #include "uint256.h"
  #include "util.h"
  #include "utilstrencodings.h"
  #include "test_oro.h"
  
  #include <string>
  #include <vector>
  
  #include <boost/test/unit_test.hpp>
  
  
  static const std::string strSecret1  = "87vK7Vayi3QLsuiva5yWSuVwSMhMcRM9dBsaD6JXMD1P5vnjRFn";
  static const std::string strSecret2  = "87FGYGFDg5SYfdD4XL593hr7do6f52czPecVsYSAXi8N4RGeS9i";
  static const std::string strSecret1C = "YRYJwfAyJ9c2jhi3T2xQyLijGvM7yLTw4izDaNQLxBzgUYrQiPmJ";
  static const std::string strSecret2C = "YNZyazHkwUbkmUpEYsBGWwHnHQTy2n9rJy1gS5k54YXVx3pE8n6N";
  static const std::string addr1 = "DBFi8XAE1rcdCQfkv9w22n8Y9RxgaJnrDD";
  static const std::string addr2 = "DPvKfv1FVp69yZMDzeuugvfZ9pzYiMv1bs";
  static const std::string addr1C = "DNPrHK9ezAAUVExFDpZ7EE1xWpPskgp1gP";
  static const std::string addr2C = "DNBVSAoc2whPFjZVAZ1pQbXPJk1LRrDC8Q";
  
  
  static const std::string strAddressBad ="Xta1praZQjyELweyMByXyiREw1ZRsjXzVP";
  
  
  #ifdef KEY_TESTS_DUMPINFO
  void dumpKeyInfo(uint256 privkey)
  {
      CKey key;
      key.resize(32);
      memcpy(&secret[0], &privkey, 32);
      std::vector<unsigned char> sec;
      sec.resize(32);
      memcpy(&sec[0], &secret[0], 32);
      printf("  * secret (hex): %s\n", HexStr(sec).c_str());
  
      for (int nCompressed=0; nCompressed<2; nCompressed++)
      {
          printf("    * secret (base58): %s\n", EncodeSecret(secret));
          CKey key;
          key.SetSecret(secret, fCompressed);
          std::vector<unsigned char> vchPubKey = key.GetPubKey();
          printf("    * pubkey (hex): %s\n", HexStr(vchPubKey).c_str());
          printf("    * address (base58): %s\n", EncodeDestination(vchPubKey).c_str());
      }
  }
  #endif
  
  BOOST_FIXTURE_TEST_SUITE(key_tests, TestingSetup)
  
  BOOST_AUTO_TEST_CASE(key_test1)
  {
      CKey key1  = DecodeSecret(strSecret1);
      BOOST_CHECK(key1.IsValid() && !key1.IsCompressed());
      CKey key2  = DecodeSecret(strSecret2);
      BOOST_CHECK(key2.IsValid() && !key2.IsCompressed());
      CKey key1C = DecodeSecret(strSecret1C);
      BOOST_CHECK(key1C.IsValid() && key1C.IsCompressed());
      CKey key2C = DecodeSecret(strSecret2C);
      BOOST_CHECK(key2C.IsValid() && key2C.IsCompressed());
      CKey bad_key = DecodeSecret(strAddressBad);
      BOOST_CHECK(!bad_key.IsValid());
  
      CPubKey pubkey1  = key1. GetPubKey();
      CPubKey pubkey2  = key2. GetPubKey();
      CPubKey pubkey1C = key1C.GetPubKey();
      CPubKey pubkey2C = key2C.GetPubKey();
  
      BOOST_CHECK(key1.VerifyPubKey(pubkey1));
      BOOST_CHECK(!key1.VerifyPubKey(pubkey1C));
      BOOST_CHECK(!key1.VerifyPubKey(pubkey2));
      BOOST_CHECK(!key1.VerifyPubKey(pubkey2C));
  
      BOOST_CHECK(!key1C.VerifyPubKey(pubkey1));
      BOOST_CHECK(key1C.VerifyPubKey(pubkey1C));
      BOOST_CHECK(!key1C.VerifyPubKey(pubkey2));
      BOOST_CHECK(!key1C.VerifyPubKey(pubkey2C));
  
      BOOST_CHECK(!key2.VerifyPubKey(pubkey1));
      BOOST_CHECK(!key2.VerifyPubKey(pubkey1C));
      BOOST_CHECK(key2.VerifyPubKey(pubkey2));
      BOOST_CHECK(!key2.VerifyPubKey(pubkey2C));
  
      BOOST_CHECK(!key2C.VerifyPubKey(pubkey1));
      BOOST_CHECK(!key2C.VerifyPubKey(pubkey1C));
      BOOST_CHECK(!key2C.VerifyPubKey(pubkey2));
      BOOST_CHECK(key2C.VerifyPubKey(pubkey2C));
  
      BOOST_CHECK(DecodeDestination(addr1)  == CTxDestination(pubkey1.GetID()));
      BOOST_CHECK(DecodeDestination(addr2)  == CTxDestination(pubkey2.GetID()));
      BOOST_CHECK(DecodeDestination(addr1C) == CTxDestination(pubkey1C.GetID()));
      BOOST_CHECK(DecodeDestination(addr2C) == CTxDestination(pubkey2C.GetID()));
  
      for (int n=0; n<16; n++)
      {
          std::string strMsg = strprintf("Very secret message %i: 11", n);
          uint256 hashMsg = Hash(strMsg.begin(), strMsg.end());
  
          // normal signatures
  
          std::vector<unsigned char> sign1, sign2, sign1C, sign2C;
  
          BOOST_CHECK(key1.Sign (hashMsg, sign1));
          BOOST_CHECK(key2.Sign (hashMsg, sign2));
          BOOST_CHECK(key1C.Sign(hashMsg, sign1C));
          BOOST_CHECK(key2C.Sign(hashMsg, sign2C));
  
          BOOST_CHECK( pubkey1.Verify(hashMsg, sign1));
          BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2));
          BOOST_CHECK( pubkey1.Verify(hashMsg, sign1C));
          BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2C));
  
          BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1));
          BOOST_CHECK( pubkey2.Verify(hashMsg, sign2));
          BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1C));
          BOOST_CHECK( pubkey2.Verify(hashMsg, sign2C));
  
          BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1));
          BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2));
          BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1C));
          BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2C));
  
          BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1));
          BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2));
          BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1C));
          BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2C));
  
          // compact signatures (with key recovery)
  
          std::vector<unsigned char> csign1, csign2, csign1C, csign2C;
  
          BOOST_CHECK(key1.SignCompact (hashMsg, csign1));
          BOOST_CHECK(key2.SignCompact (hashMsg, csign2));
          BOOST_CHECK(key1C.SignCompact(hashMsg, csign1C));
          BOOST_CHECK(key2C.SignCompact(hashMsg, csign2C));
  
          CPubKey rkey1, rkey2, rkey1C, rkey2C;
  
          BOOST_CHECK(rkey1.RecoverCompact (hashMsg, csign1));
          BOOST_CHECK(rkey2.RecoverCompact (hashMsg, csign2));
          BOOST_CHECK(rkey1C.RecoverCompact(hashMsg, csign1C));
          BOOST_CHECK(rkey2C.RecoverCompact(hashMsg, csign2C));
  
          BOOST_CHECK(rkey1  == pubkey1);
          BOOST_CHECK(rkey2  == pubkey2);
          BOOST_CHECK(rkey1C == pubkey1C);
          BOOST_CHECK(rkey2C == pubkey2C);
      }
  
      // test deterministic signing
  
      std::vector<unsigned char> detsig, detsigc;
      std::string strMsg = "Very deterministic message";
      uint256 hashMsg = Hash(strMsg.begin(), strMsg.end());
      BOOST_CHECK(key1.Sign(hashMsg, detsig));
      BOOST_CHECK(key1C.Sign(hashMsg, detsigc));
      BOOST_CHECK(detsig == detsigc);
      BOOST_CHECK(detsig == ParseHex("30450221009071d4fead181ea197d6a23106c48ee5de25e023b38afaf71c170e3088e5238a02200dcbc7f1aad626a5ee812e08ef047114642538e423a94b4bd6a272731cf500d0"));
      BOOST_CHECK(key2.Sign(hashMsg, detsig));
      BOOST_CHECK(key2C.Sign(hashMsg, detsigc));
      BOOST_CHECK(detsig == detsigc);
      BOOST_CHECK(detsig == ParseHex("304402204f304f1b05599f88bc517819f6d43c69503baea5f253c55ea2d791394f7ce0de02204f23c0d4c1f4d7a89bf130fed755201d22581911a8a44cf594014794231d325a"));
      BOOST_CHECK(key1.SignCompact(hashMsg, detsig));
      BOOST_CHECK(key1C.SignCompact(hashMsg, detsigc));
      BOOST_CHECK(detsig == ParseHex("1b9071d4fead181ea197d6a23106c48ee5de25e023b38afaf71c170e3088e5238a0dcbc7f1aad626a5ee812e08ef047114642538e423a94b4bd6a272731cf500d0"));
      BOOST_CHECK(detsigc == ParseHex("1f9071d4fead181ea197d6a23106c48ee5de25e023b38afaf71c170e3088e5238a0dcbc7f1aad626a5ee812e08ef047114642538e423a94b4bd6a272731cf500d0"));
      BOOST_CHECK(key2.SignCompact(hashMsg, detsig));
      BOOST_CHECK(key2C.SignCompact(hashMsg, detsigc));
      BOOST_CHECK(detsig == ParseHex("1b4f304f1b05599f88bc517819f6d43c69503baea5f253c55ea2d791394f7ce0de4f23c0d4c1f4d7a89bf130fed755201d22581911a8a44cf594014794231d325a"));
      BOOST_CHECK(detsigc == ParseHex("1f4f304f1b05599f88bc517819f6d43c69503baea5f253c55ea2d791394f7ce0de4f23c0d4c1f4d7a89bf130fed755201d22581911a8a44cf594014794231d325a"));
  }
  
  BOOST_AUTO_TEST_SUITE_END()
  