You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mymonero-core-cpp/src/monero_key_image_utils.cpp

132 lines
5.2 KiB

//
// monero_key_image_utils.cpp
// MyMonero
//
// Created by Paul Shapiro on 1/2/18.
// Copyright (c) 2014-2019, MyMonero.com
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
#include "monero_key_image_utils.hpp"
//
using namespace crypto;
using namespace cryptonote;
//
bool monero_key_image_utils::new__key_image(
const crypto::public_key& account_pub_spend_key,
const crypto::secret_key& account_sec_spend_key,
const crypto::secret_key& account_sec_view_key,
const crypto::public_key& tx_public_key,
uint64_t out_index,
KeyImageRetVals &retVals
) {
retVals = {};
//
bool r = false;
//
// "Subaddresses aren't supported in mymonero/openmonero yet. Roll out the original scheme:
// compute D = a*R
// compute P = Hs(D || i)*G + B
// compute x = Hs(D || i) + b (and check if P==x*G)
// compute I = x*Hp(P)"
crypto::key_derivation derivation;
r = crypto::generate_key_derivation(tx_public_key, account_sec_view_key, derivation);
if (!r) {
retVals.did_error = true;
std::ostringstream ss{};
ss << "failed to generate_key_derivation(" << tx_public_key << ", " << account_sec_view_key << ")";
retVals.err_string = ss.str();
//
return false;
}
cryptonote::keypair in_ephemeral;
r = crypto::derive_public_key(derivation, out_index, account_pub_spend_key, in_ephemeral.pub);
if (!r) {
retVals.did_error = true;
std::ostringstream ss{};
ss << "failed to derive_public_key (" << derivation << ", " << out_index << ", " << account_pub_spend_key << ")";
retVals.err_string = ss.str();
//
return false;
}
crypto::derive_secret_key(derivation, out_index, account_sec_spend_key, in_ephemeral.sec);
crypto::public_key out_pkey_test;
r = crypto::secret_key_to_public_key(in_ephemeral.sec, out_pkey_test);
if (!r) {
retVals.did_error = true;
std::ostringstream ss{};
ss << "failed to secret_key_to_public_key(" << in_ephemeral.sec << ")";
retVals.err_string = ss.str();
//
return false;
}
if (in_ephemeral.pub != out_pkey_test) {
retVals.did_error = true;
retVals.err_string = "derived secret key doesn't match derived public key";
//
return false;
}
crypto::generate_key_image(in_ephemeral.pub, in_ephemeral.sec, retVals.calculated_key_image);
//
return true;
}
//+ (NSString *)new_keyImageFrom_tx_pub_key:(NSString *)tx_pub_key_NSString
//sec_spendKey:(NSString *)sec_spendKey_NSString
//sec_viewKey:(NSString *)sec_viewKey_NSString
//pub_spendKey:(NSString *)pub_spendKey_NSString
//out_index:(uint64_t)out_index
//{
// crypto::secret_key sec_viewKey{};
// crypto::secret_key sec_spendKey{};
// crypto::public_key pub_spendKey{};
// crypto::public_key tx_pub_key{};
// { // Would be nice to find a way to avoid converting these back and forth
// bool r = false;
// r = string_tools::hex_to_pod(std::string(sec_viewKey_NSString.UTF8String), sec_viewKey);
// NSAssert(r, @"Invalid secret view key");
// r = string_tools::hex_to_pod(std::string(sec_spendKey_NSString.UTF8String), sec_spendKey);
// NSAssert(r, @"Invalid secret spend key");
// r = string_tools::hex_to_pod(std::string(pub_spendKey_NSString.UTF8String), pub_spendKey);
// NSAssert(r, @"Invalid public spend key");
// r = string_tools::hex_to_pod(std::string(tx_pub_key_NSString.UTF8String), tx_pub_key);
// NSAssert(r, @"Invalid tx pub key");
// }
// monero_key_image_utils::KeyImageRetVals retVals;
// {
// bool r = monero_key_image_utils::new__key_image(pub_spendKey, sec_spendKey, sec_viewKey, tx_pub_key, out_index, retVals);
// if (!r) {
// return nil; // TODO: return error string? (unwrap optional)
// }
// }
// std::string key_image_hex_string = string_tools::pod_to_hex(retVals.calculated_key_image);
// NSString *key_image_hex_NSString = [NSString stringWithUTF8String:key_image_hex_string.c_str()];
// //
// return key_image_hex_NSString;
//}