コード例 #1
0
ファイル: tree-hash.c プロジェクト: ifzz/bitmonero
void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) {
// The blockchain block at height 202612 http://monerochain.info/block/bbd604d2ba11ba27935e006ed39c9bfdd99b76bf4a50654bc1e1e61217962698
// contained 514 transactions, that triggered bad calculation of variable "cnt" in the original version of this function
// as from CryptoNote code.
//
// This bug applies to all CN altcoins.
//
// Mathematical bug here was first published on 14:45:34 (GMT+2) 2014-09-04 by Rafal Freeman <rfree>
// https://github.com/rfree2monero/bitmonero/commit/b417abfb7a297d09f1bbb6de29030f8de9952ac8
// and soon also applied to CryptoNote (15:10 GMT+2), and BoolBerry used not fully correct work around:
// the work around of sizeof(size_t)*8 or <<3 as used before in 2 coins and in BBL later was blocking
// exploitation on normal platforms, how ever we strongly recommend the following fix because it removes
// mistake in mathematical formula.

  assert(count > 0);
  if (count == 1) {
    memcpy(root_hash, hashes, HASH_SIZE);
  } else if (count == 2) {
    cn_fast_hash(hashes, 2 * HASH_SIZE, root_hash);
  } else {
    size_t i, j;

    size_t cnt = tree_hash_cnt( count );
    size_t max_size_t = (size_t) -1; // max allowed value of size_t 
    assert( cnt < max_size_t/2 ); // reasonable size to avoid any overflows. /2 is extra; Anyway should be limited much stronger by logical code 
    // as we have sane limits on transactions counts in blockchain rules

    char (*ints)[HASH_SIZE];
    size_t ints_size = cnt * HASH_SIZE;
    ints = alloca(ints_size); 	memset( ints , 0 , ints_size);  // allocate, and zero out as extra protection for using uninitialized mem

    memcpy(ints, hashes, (2 * cnt - count) * HASH_SIZE);

    for (i = 2 * cnt - count, j = 2 * cnt - count; j < cnt; i += 2, ++j) {
      cn_fast_hash(hashes[i], 64, ints[j]);
    }
    assert(i == count);

    while (cnt > 2) {
      cnt >>= 1;
      for (i = 0, j = 0; j < cnt; i += 2, ++j) {
        cn_fast_hash(ints[i], 64, ints[j]);
      }
    }

    cn_fast_hash(ints[0], 64, root_hash);
  }
}
コード例 #2
0
ファイル: rctOps.cpp プロジェクト: aeonix/aeon
 //cn_fast_hash for a key-vector of arbitrary length
 //this is useful since you take a number of keys
 //put them in the key vector and it concatenates them
 //and then hashes them
 key cn_fast_hash(const keyV &keys) {
     if (keys.empty()) return rct::hash2rct(crypto::cn_fast_hash("", 0));
     key rv;
     cn_fast_hash(rv, &keys[0], keys.size() * sizeof(keys[0]));
     //dp(rv);
     return rv;
 }
コード例 #3
0
bool tx_extra_message::decrypt(size_t index, const Crypto::PublicKey &txkey, const Crypto::SecretKey *recepient_secret_key, std::string &message) const {
  size_t mlen = data.size();
  if (mlen < TX_EXTRA_MESSAGE_CHECKSUM_SIZE) {
    return false;
  }
  const char *buf;
  std::unique_ptr<char[]> ptr;
  if (recepient_secret_key != nullptr) {
    ptr.reset(new char[mlen]);
    assert(ptr);
    message_key_data key_data;
    if (!generate_key_derivation(txkey, *recepient_secret_key, key_data.derivation)) {
      return false;
    }
    key_data.magic1 = 0x80;
    key_data.magic2 = 0;
    Hash h = cn_fast_hash(&key_data, sizeof(message_key_data));
    uint64_t nonce = SWAP64LE(index);
    chacha(10, data.data(), mlen, reinterpret_cast<uint8_t *>(&h), reinterpret_cast<uint8_t *>(&nonce), ptr.get());
    buf = ptr.get();
  } else {
    buf = data.data();
  }
  mlen -= TX_EXTRA_MESSAGE_CHECKSUM_SIZE;
  for (size_t i = 0; i < TX_EXTRA_MESSAGE_CHECKSUM_SIZE; i++) {
    if (buf[mlen + i] != 0) {
      return false;
    }
  }
  message.assign(buf, mlen);
  return true;
}
コード例 #4
0
 static void hash_to_ec(const public_key &key, ge_p3 &res) {
   hash h;
   ge_p2 point;
   ge_p1p1 point2;
   cn_fast_hash(std::addressof(key), sizeof(public_key), h);
   ge_fromfe_frombytes_vartime(&point, reinterpret_cast<const unsigned char *>(&h));
   ge_mul8(&point2, &point);
   ge_p1p1_to_p3(&res, &point2);
 }
コード例 #5
0
bool parseAndValidateTransactionFromBinaryArray(const BinaryArray& tx_blob, Transaction& tx, Hash& tx_hash, Hash& tx_prefix_hash) {
  if (!fromBinaryArray(tx, tx_blob)) {
    return false;
  }

  //TODO: validate tx
  cn_fast_hash(tx_blob.data(), tx_blob.size(), tx_hash);
  getObjectHash(*static_cast<TransactionPrefix*>(&tx), tx_prefix_hash);
  return true;
}
コード例 #6
0
 void hashToPoint(key & pointk, const key & hh) {
     ge_p2 point;
     ge_p1p1 point2;
     ge_p3 res;
     key h = cn_fast_hash(hh); 
     ge_fromfe_frombytes_vartime(&point, h.bytes);
     ge_mul8(&point2, &point);
     ge_p1p1_to_p3(&res, &point2);        
     ge_p3_tobytes(pointk.bytes, &res);
 }    
コード例 #7
0
 //cn_fast_hash for multisig purpose
 //This takes the outputs and commitments
 //and hashes them into a 32 byte sized key
 key cn_fast_hash(ctkeyV PC) {
     key rv = identity();
     std::size_t l = (std::size_t)PC.size();
     size_t i = 0, j = 0;
     vector<char> m(l * 64);
     for (i = 0 ; i < l ; i++) {
         memcpy(&m[i * 64], &PC[i].dest, 32);
         memcpy(&m[i * 64 + 32], &PC[i].mask, 32);
     }
     cn_fast_hash(rv, &m[0], 64*l);
     return rv;
 }
コード例 #8
0
 //cn_fast_hash for a key-vector of arbitrary length
 //this is useful since you take a number of keys
 //put them in the key vector and it concatenates them
 //and then hashes them
 key cn_fast_hash(const keyV &keys) {
     size_t l = keys.size();
     vector<unsigned char> m(l * 32);
     size_t i;
     for (i = 0 ; i < l ; i++) {
         memcpy(&m[i * 32], keys[i].bytes, 32);
     }
     key rv;
     cn_fast_hash(rv, &m[0], 32 * l);
     //dp(rv);
     return rv;
 }
コード例 #9
0
 key hashToPointSimple(const key & hh) {
     key pointk;
     ge_p1p1 point2;
     ge_p2 point;
     ge_p3 res;
     key h = cn_fast_hash(hh); 
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&res, h.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_p3_to_p2(&point, &res);
     ge_mul8(&point2, &point);
     ge_p1p1_to_p3(&res, &point2);
     ge_p3_tobytes(pointk.bytes, &res);
     return pointk;
 }    
コード例 #10
0
bool tx_extra_message::encrypt(size_t index, const std::string &message, const AccountPublicAddress *recipient, const KeyPair &txkey) {
  size_t mlen = message.size();
  std::unique_ptr<char[]> buf(new char[mlen + TX_EXTRA_MESSAGE_CHECKSUM_SIZE]);
  memcpy(buf.get(), message.data(), mlen);
  memset(buf.get() + mlen, 0, TX_EXTRA_MESSAGE_CHECKSUM_SIZE);
  mlen += TX_EXTRA_MESSAGE_CHECKSUM_SIZE;
  if (recipient) {
    message_key_data key_data;
    if (!generate_key_derivation(recipient->spendPublicKey, txkey.secretKey, key_data.derivation)) {
      return false;
    }
    key_data.magic1 = 0x80;
    key_data.magic2 = 0;
    Hash h = cn_fast_hash(&key_data, sizeof(message_key_data));
    uint64_t nonce = SWAP64LE(index);
    chacha(10, buf.get(), mlen, reinterpret_cast<uint8_t *>(&h), reinterpret_cast<uint8_t *>(&nonce), buf.get());
  }
  data.assign(buf.get(), mlen);
  return true;
}
コード例 #11
0
 void hash_to_scalar(key & hash, const key & in) {
     cn_fast_hash(hash, in);
     sc_reduce32(hash.bytes);
 }
コード例 #12
0
 key hash_to_scalar(const keyV &keys) {
     key rv = cn_fast_hash(keys);
     sc_reduce32(rv.bytes);
     return rv;
 }
コード例 #13
0
 key hash_to_scalar(ctkeyV PC) {
     key rv = cn_fast_hash(PC);
     sc_reduce32(rv.bytes);
     return rv;
 }
コード例 #14
0
 static inline void hash_to_scalar(const void *data, size_t length, ec_scalar &res) {
   cn_fast_hash(data, length, reinterpret_cast<hash &>(res));
   sc_reduce32(&res);
 }
コード例 #15
0
 void hash_to_scalar(key &hash, const void * data, const std::size_t l) {
     cn_fast_hash(hash, data, l);
     sc_reduce32(hash.bytes);
 }
コード例 #16
0
ファイル: rctOps.cpp プロジェクト: aeonix/aeon
 key cn_fast_hash(const key64 keys) {
    key rv;
    cn_fast_hash(rv, &keys[0], 64 * sizeof(keys[0]));
    //dp(rv);
    return rv;
 }
コード例 #17
0
ファイル: CryptoNoteTools.cpp プロジェクト: conordb/bytecoin
void getBinaryArrayHash(const BinaryArray& binaryArray, Crypto::Hash& hash) {
  cn_fast_hash(binaryArray.data(), binaryArray.size(), hash);
}
コード例 #18
0
ファイル: rctOps.cpp プロジェクト: aeonix/aeon
 //cn_fast_hash for multisig purpose
 //This takes the outputs and commitments
 //and hashes them into a 32 byte sized key
 key cn_fast_hash(const ctkeyV &PC) {
     if (PC.empty()) return rct::hash2rct(crypto::cn_fast_hash("", 0));
     key rv;
     cn_fast_hash(rv, &PC[0], 64*PC.size());
     return rv;
 }
コード例 #19
0
 key hash_to_scalar(const key & in) {
    key hash = cn_fast_hash(in);
    sc_reduce32(hash.bytes);
    return hash;
 }
コード例 #20
0
void get_blob_hash(const blobdata& blob, crypto::hash& res) {
  cn_fast_hash(blob.data(), blob.size(), res);
}