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);
 }
 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);
 }    
 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;
 }    
 bool crypto_ops::generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation) {
   ge_p3 point;
   ge_p2 point2;
   ge_p1p1 point3;
   assert(sc_check(&key2) == 0);
   if (ge_frombytes_vartime(&point, &key1) != 0) {
     return false;
   }
   ge_scalarmult(&point2, &key2, &point);
   ge_mul8(&point3, &point2);
   ge_p1p1_to_p2(&point2, &point3);
   ge_tobytes(&derivation, &point2);
   return true;
 }