40 #define ENCRYPTED_PAYMENT_ID_TAIL 0x8d 41 #define CHACHA8_KEY_TAIL 0x8c 55 return &
reinterpret_cast<unsigned char &
>(scalar);
58 return &
reinterpret_cast<const unsigned char &
>(scalar);
108 memcpy(data.data(), &view_key,
sizeof(view_key));
109 memcpy(data.data() +
sizeof(view_key), &spend_key,
sizeof(spend_key));
111 crypto::generate_chacha_key(data.data(),
sizeof(data),
key, kdf_rounds);
147 std::vector<crypto::public_key> pkeys; 148 pkeys.reserve(end - begin); 149 cryptonote::subaddress_index index = {account, begin}; 153 CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, (const unsigned char*)keys.m_account_address.m_spend_public_key.data) == 0, 155 ge_p3_to_cached(&cached, &p3); 157 for (uint32_t idx = begin; idx < end; ++idx) 162 pkeys.push_back(keys.m_account_address.m_spend_public_key); 165 crypto::secret_key m = get_subaddress_secret_key(keys.m_view_secret_key, index); 168 ge_scalarmult_base(&p3, (const unsigned char*)m.data); 171 crypto::public_key D; 173 ge_add(&p1p1, &p3, &cached); 174 ge_p1p1_to_p3(&p3, &p1p1); 175 ge_p3_tobytes((unsigned char*)D.data, &p3); 182 cryptonote::account_public_address device_default::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { 184 return keys.m_account_address; 186 crypto::public_key D = get_subaddress_spend_public_key(keys, index); 189 crypto::public_key C = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(D), rct::sk2rct(keys.m_view_secret_key))); 192 cryptonote::account_public_address address; 193 address.m_view_public_key = C; 194 address.m_spend_public_key = D; 198 crypto::secret_key device_default::get_subaddress_secret_key(const crypto::secret_key &a, const cryptonote::subaddress_index &index) { 199 const char prefix[] = "SubAddr
"; 200 char data[sizeof(prefix) + sizeof(crypto::secret_key) + 2 * sizeof(uint32_t)]; 201 memcpy(data, prefix, sizeof(prefix)); 202 memcpy(data + sizeof(prefix), &a, sizeof(crypto::secret_key)); 203 uint32_t idx = SWAP32LE(index.major); 204 memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &idx, sizeof(uint32_t)); 205 idx = SWAP32LE(index.minor); 206 memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(uint32_t), &idx, sizeof(uint32_t)); 207 crypto::secret_key m; 208 crypto::hash_to_scalar(data, sizeof(data), m); 212 // subaddress pub spend is D = B + mG where m is the subaddress secret key, B is the main wallet public spend key 213 // Alternatively write D = bG + mG === (b+m)G 214 // therefore priv spend d = b+m 215 crypto::secret_key device_default::get_subaddress_private_spendkey(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &subaddr_index){ 216 crypto::secret_key subaddr_secret_key = get_subaddress_secret_key(keys.m_view_secret_key, subaddr_index); 217 crypto::secret_key subaddr_private_spendkey; 218 sc_secret_add(subaddr_private_spendkey, subaddr_secret_key, keys.m_spend_secret_key); 219 return subaddr_private_spendkey; 222 // subaddress pub view is C = aD where 'a' is the main wallet private view key 223 // Alternatively write C = a*dG === a*(b+m)G 224 // therefore priv view c = a(b+m) 225 crypto::secret_key device_default::get_subaddress_private_viewkey(const crypto::secret_key &main_wallet_sec_view, crypto::secret_key &subaddress_sec_spend){ 226 crypto::secret_key subaddr_private_viewkey; 227 sc_mul(&subaddr_private_viewkey, &main_wallet_sec_view, &subaddress_sec_spend); 228 return subaddr_private_viewkey; 231 /* ======================================================================= */ 232 /* DERIVATION & KEY */ 233 /* ======================================================================= */ 235 bool device_default::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) { 236 crypto::public_key calculated_pub; 237 bool r = crypto::secret_key_to_public_key(secret_key, calculated_pub); 238 return r && public_key == calculated_pub; 241 bool device_default::scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) { 242 rct::scalarmultKey(aP, P,a); 246 bool device_default::scalarmultBase(rct::key &aG, const rct::key &a) { 247 rct::scalarmultBase(aG,a); 251 bool device_default::sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) { 256 crypto::secret_key device_default::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover) { 257 return crypto::generate_keys(pub, sec, recovery_key, recover); 260 bool device_default::generate_key_derivation(const crypto::public_key &key1, const crypto::secret_key &key2, crypto::key_derivation &derivation) { 261 return crypto::generate_key_derivation(key1, key2, derivation); 264 bool device_default::derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res){ 265 crypto::derivation_to_scalar(derivation,output_index, res); 269 bool device_default::derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &base, crypto::secret_key &derived_key){ 270 crypto::derive_secret_key(derivation, output_index, base, derived_key); 274 bool device_default::derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &base, crypto::public_key &derived_key){ 275 return crypto::derive_public_key(derivation, output_index, base, derived_key); 278 bool device_default::secret_key_to_public_key(const crypto::secret_key &sec, crypto::public_key &pub) { 279 return crypto::secret_key_to_public_key(sec,pub); 282 bool device_default::generate_key_image(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_image &image){ 283 crypto::generate_key_image(pub, sec,image); 287 bool device_default::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations){ 291 /* ======================================================================= */ 293 /* ======================================================================= */ 294 void device_default::generate_tx_proof(const crypto::hash &prefix_hash, 295 const crypto::public_key &R, const crypto::public_key &A, const boost::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r, 296 crypto::signature &sig) { 297 crypto::generate_tx_proof(prefix_hash, R, A, B, D, r, sig); 300 bool device_default::open_tx(crypto::secret_key &tx_key) { 301 cryptonote::keypair txkey = cryptonote::keypair::generate(*this); 306 bool device_default::generate_output_ephemeral_keys(const size_t tx_version, 307 const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, 308 const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, 309 const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, 310 std::vector<crypto::public_key> &additional_tx_public_keys, 311 std::vector<rct::key> &amount_keys, crypto::public_key &out_eph_public_key) { 313 crypto::key_derivation derivation; 315 // make additional tx pubkey if necessary 316 cryptonote::keypair additional_txkey; 317 if (need_additional_txkeys) 319 additional_txkey.sec = additional_tx_keys[output_index]; 320 if (dst_entr.is_subaddress) 321 additional_txkey.pub = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec))); 323 additional_txkey.pub = rct::rct2pk(rct::scalarmultBase(rct::sk2rct(additional_txkey.sec))); 327 if (change_addr && dst_entr.addr == *change_addr) 329 // sending change to yourself; derivation = a*R 330 r = generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation); 331 CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to
generate_key_derivation(
" << txkey_pub << ",
" << sender_account_keys.m_view_secret_key << ")
"); 335 // sending to the recipient; derivation = r*A (or s*C in the subaddress scheme) 336 r = generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation); 337 CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to
generate_key_derivation(
" << dst_entr.addr.m_view_public_key << ",
" << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")
"); 340 if (need_additional_txkeys) 342 additional_tx_public_keys.push_back(additional_txkey.pub); 347 crypto::secret_key scalar1; 348 derivation_to_scalar(derivation, output_index, scalar1); 349 amount_keys.push_back(rct::sk2rct(scalar1)); 351 r = derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key); 352 CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to
derive_public_key(
" << derivation << ",
" << output_index << ",
"<< dst_entr.addr.m_spend_public_key << ")
"); 357 bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { 358 crypto::key_derivation derivation; 360 char data[33]; /* A hash, and an extra byte */ 362 if (!generate_key_derivation(public_key, secret_key, derivation)) 365 memcpy(data, &derivation, 32); 366 data[32] = ENCRYPTED_PAYMENT_ID_TAIL; 367 cn_fast_hash(data, 33, hash); 369 for (size_t b = 0; b < 8; ++b) 370 payment_id.data[b] ^= hash.data[b]; 375 rct::key device_default::genCommitmentMask(const rct::key &amount_key) { 376 return rct::genCommitmentMask(amount_key); 379 bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) { 380 rct::ecdhEncode(unmasked, sharedSec, short_amount); 384 bool device_default::ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) { 385 rct::ecdhDecode(masked, sharedSec, short_amount); 389 bool device_default::mlsag_prepare(const rct::key &H, const rct::key &xx, 390 rct::key &a, rct::key &aG, rct::key &aHP, rct::key &II) { 392 rct::scalarmultKey(aHP, H, a); 393 rct::scalarmultKey(II, H, xx); 396 bool device_default::mlsag_prepare(rct::key &a, rct::key &aG) { 400 bool device_default::mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) { 401 prehash = rct::cn_fast_hash(hashes); 406 bool device_default::mlsag_hash(const rct::keyV &toHash, rct::key &c_old) { 407 c_old = rct::hash_to_scalar(toHash); 411 bool device_default::mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss ) { 412 CHECK_AND_ASSERT_THROW_MES(dsRows<=rows, "dsRows greater than
rows"); 413 CHECK_AND_ASSERT_THROW_MES(xx.size() == rows, "xx size does not match
rows"); 414 CHECK_AND_ASSERT_THROW_MES(alpha.size() == rows, "alpha size does not match
rows"); 415 CHECK_AND_ASSERT_THROW_MES(ss.size() == rows, "ss size does not match
rows"); 416 for (size_t j = 0; j < rows; j++) { 417 sc_mulsub(ss[j].bytes, c.bytes, xx[j].bytes, alpha[j].bytes); 422 bool device_default::close_tx() { 426 bool device_default::hash_to_scalar(boost::shared_ptr<crypto::rs_comm> buf, size_t length, crypto::ec_scalar &res) { 427 crypto::hash_to_scalar(buf.get(), length, res); 431 bool device_default::get_transaction_prefix_hash(const cryptonote::transaction_prefix& tx, crypto::hash& tx_prefix_hash) { 433 std::ostringstream s; 434 binary_archive<true> a(s); 435 ::serialization::serialize(a, const_cast<cryptonote::transaction_prefix&>(tx)); 437 crypto::cn_fast_hash(s.str().data(), s.str().size(), tx_prefix_hash); 442 bool device_default::generate_ring_signature(const crypto::hash &prefix_hash, const crypto::key_image &image, 443 const std::vector<const crypto::public_key *> &pubs, 444 const crypto::secret_key &sec, std::size_t sec_index, 445 crypto::signature *sig){ 446 crypto::generate_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sec, sec_index, sig); 450 bool device_default::generate_input_signature(const crypto::hash &prefix_hash, const uint32_t input_index, const crypto::secret_key sec_view, const crypto::secret_key sec_spend, crypto::signature& signature){ 451 crypto::generate_input_signature(prefix_hash, input_index, sec_view, sec_spend, signature); 455 /* ---------------------------------------------------------- */ 456 static device_default *default_core_device = NULL; 457 void register_all(std::map<std::string, std::unique_ptr<device>> ®istry) { 458 if (!default_core_device) { 459 default_core_device = new device_default(); 460 default_core_device->set_name("default_core_device
"); 463 registry.insert(std::make_pair("default", std::unique_ptr<device>(default_core_device))); #define CHECK_AND_ASSERT_THROW_MES(expr, message)
bool derive_subaddress_public_key(const crypto::public_key &pub, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_pub) override
bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override
virtual bool set_mode(device_mode mode)
void unlock(void) override
const std::string get_name() const override
bool connect(void) override
Archiver & operator &(Archiver &ar, Student &s)
crypto::public_key m_spend_public_key
bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &result)
unsigned __int64 uint64_t
bool try_lock(void) override
bool disconnect() override
crypto::secret_key m_view_secret_key
account_public_address m_account_address
crypto::secret_key get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) override
void * memcpy(void *a, const void *b, size_t c)
crypto::secret_key m_spend_secret_key
bool get_secret_keys(crypto::secret_key &viewkey, crypto::secret_key &spendkey) override
int ge_frombytes_vartime(ge_p3 *, const unsigned char *)
void addKeys(key &AB, const key &A, const key &B)
crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys &keys, const cryptonote::subaddress_index &index) override
bool secret_key_to_public_key(const secret_key &sec, public_key &pub)
bool set_name(const std::string &name) override
std::vector< crypto::public_key > get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) override
bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override
bool generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key, uint64_t kdf_rounds) override
bool get_public_address(cryptonote::account_public_address &pubkey) override
bool set_mode(device_mode mode) override