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.
132 lines
5.2 KiB
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;
|
|
//}
|