diff options
53 files changed, 1480 insertions, 1445 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index aac15b5b6..08b47eaf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -800,7 +800,7 @@ endif() include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) if(MINGW) set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi) - set(ICU_LIBRARIES ${Boost_LOCALE_LIBRARY} sicuio sicuin sicuuc sicudt sicutu iconv) + set(ICU_LIBRARIES ${Boost_LOCALE_LIBRARY} icuio icuin icuuc icudt icutu iconv) elseif(APPLE OR OPENBSD OR ANDROID) set(EXTRA_LIBRARIES "") elseif(FREEBSD) @@ -99,9 +99,9 @@ Dates are provided in the format YYYY-MM-DD. | 1220516 | 2017-01-05 | v4 | v0.10.1 | v0.10.2.1 | Allow normal and RingCT transactions | | 1288616 | 2017-04-15 | v5 | v0.10.3.0 | v0.10.3.1 | Adjusted minimum blocksize and fee algorithm | | 1400000 | 2017-09-16 | v6 | v0.11.0.0 | v0.11.0.0 | Allow only RingCT transactions, allow only >= ringsize 5 | -| XXXXXXX | 2018-03-XX | XX | XXXXXXXXX | XXXXXXXXX | XXXXXX +| 1539500 | 2018-03-28 | v7 | XXXXXXXXX | XXXXXXXXX | Cryptonight variant 1, ringsize >= 7, sorted inputs -X's indicate that these details have not been determined as of commit date, 2017-09-20. +X's indicate that these details have not been determined as of commit date. ## Release staging schedule and protocol @@ -373,7 +373,7 @@ To build: `env CC=egcc CXX=eg++ CPP=ecpp DEVELOPER_LOCAL_TOOLS=1 BOOST_ROOT=/pat #### OpenBSD >= 6.2 -You will need to add a few packages to your system. Choose version 4 for db. `pkg_add db cmake miniupnpc zeromq`. +You will need to add a few packages to your system. `pkg_add cmake miniupnpc zeromq libiconv`. The doxygen and graphviz packages are optional and require the xbase set. @@ -396,16 +396,24 @@ ftp -o boost_1_64_0.tar.bz2 https://netcologne.dl.sourceforge.net/project/boost/ echo "7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332 boost_1_64_0.tar.bz2" | sha256 -c tar xfj boost_1_64_0.tar.bz2 -# Fetch a boost patch, required for OpenBSD -ftp -o boost.patch https://raw.githubusercontent.com/openbsd/ports/bee9e6df517077a7269ff0dfd57995f5c6a10379/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp +# Fetch and apply boost patches, required for OpenBSD +ftp -o boost_test_impl_execution_monitor_ipp.patch https://raw.githubusercontent.com/openbsd/ports/bee9e6df517077a7269ff0dfd57995f5c6a10379/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp +ftp -o boost_config_platform_bsd_hpp.patch https://raw.githubusercontent.com/openbsd/ports/90658284fb786f5a60dd9d6e8d14500c167bdaa0/devel/boost/patches/patch-boost_config_platform_bsd_hpp + +# MUST output: (SHA256) boost_config_platform_bsd_hpp.patch: OK +echo "1f5e59d1154f16ee1e0cc169395f30d5e7d22a5bd9f86358f738b0ccaea5e51d boost_config_platform_bsd_hpp.patch" | sha256 -c +# MUST output: (SHA256) boost_test_impl_execution_monitor_ipp.patch: OK +echo "30cec182a1437d40c3e0bd9a866ab5ddc1400a56185b7e671bb3782634ed0206 boost_test_impl_execution_monitor_ipp.patch" | sha256 -c + cd boost_1_64_0 -patch -p0 < ../boost.patch +patch -p0 < ../boost_test_impl_execution_monitor_ipp.patch +patch -p0 < ../boost_config_platform_bsd_hpp.patch # Start building boost echo 'using clang : : c++ : <cxxflags>"-fvisibility=hidden -fPIC" <linkflags>"" <archiver>"ar" <striper>"strip" <ranlib>"ranlib" <rc>"" : ;' > user-config.jam -./bootstrap.sh --without-icu --with-libraries=chrono,filesystem,program_options,system,thread,test,date_time,regex,serialization --with-toolset=clang -./b2 toolset=clang cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" -doas ./b2 -d0 runtime-link=shared threadapi=pthread threading=multi link=static variant=release --layout=tagged --build-type=complete --user-config=user-config.jam -sNO_BZIP2=1 --prefix=/usr/local install +./bootstrap.sh --without-icu --with-libraries=chrono,filesystem,program_options,system,thread,test,date_time,regex,serialization,locale --with-toolset=clang +./b2 toolset=clang cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" -sICONV_PATH=/usr/local +doas ./b2 -d0 runtime-link=shared threadapi=pthread threading=multi link=static variant=release --layout=tagged --build-type=complete --user-config=user-config.jam -sNO_BZIP2=1 -sICONV_PATH=/usr/local --prefix=/usr/local install ``` Build cppzmq @@ -415,22 +423,19 @@ Build the cppzmq bindings. We assume you are compiling with a non-root user and you have `doas` enabled. ``` -# Create a library link so cmake is able to find it -doas ln -s /usr/local/lib/libzmq.so.4.1 /usr/local/lib/libzmq.so - # Create cppzmq building directory mkdir ~/cppzmq cd ~/cppzmq # Fetch cppzmq source -ftp -o cppzmq-4.2.2.tar.gz https://github.com/zeromq/cppzmq/archive/v4.2.2.tar.gz +ftp -o cppzmq-4.2.3.tar.gz https://github.com/zeromq/cppzmq/archive/v4.2.3.tar.gz -# MUST output: (SHA256) cppzmq-4.2.2.tar.gz: OK -echo "3ef50070ac5877c06c6bb25091028465020e181bbfd08f110294ed6bc419737d cppzmq-4.2.2.tar.gz" | sha256 -c -tar xfz cppzmq-4.2.2.tar.gz +# MUST output: (SHA256) cppzmq-4.2.3.tar.gz: OK +echo "3e6b57bf49115f4ae893b1ff7848ead7267013087dc7be1ab27636a97144d373 cppzmq-4.2.3.tar.gz" | sha256 -c +tar xfz cppzmq-4.2.3.tar.gz # Start building cppzmq -cd cppzmq-4.2.2 +cd cppzmq-4.2.3 mkdir build cd build cmake .. @@ -505,21 +510,39 @@ See [README.i18n.md](README.i18n.md). ## Using Tor -While Monero isn't made to integrate with Tor, it can be used wrapped with torsocks, if you add --p2p-bind-ip 127.0.0.1 to the monerod command line. You also want to set DNS requests to go over TCP, so they'll be routed through Tor, by setting DNS_PUBLIC=tcp or use a particular DNS server with DNS_PUBLIC=tcp://a.b.c.d (default is 8.8.4.4, which is Google DNS). You may also disable IGD (UPnP port forwarding negotiation), which is pointless with Tor. To allow local connections from the wallet, you might have to add TORSOCKS_ALLOW_INBOUND=1, some OSes need it and some don't. Example: - -`DNS_PUBLIC=tcp torsocks monerod --p2p-bind-ip 127.0.0.1 --no-igd` - -or: - -`DNS_PUBLIC=tcp TORSOCKS_ALLOW_INBOUND=1 torsocks monerod --p2p-bind-ip 127.0.0.1 --no-igd` - -TAILS ships with a very restrictive set of firewall rules. Therefore, you need to add a rule to allow this connection too, in addition to telling torsocks to allow inbound connections. Full example: - -`sudo iptables -I OUTPUT 2 -p tcp -d 127.0.0.1 -m tcp --dport 18081 -j ACCEPT` - -`DNS_PUBLIC=tcp torsocks ./monerod --p2p-bind-ip 127.0.0.1 --no-igd --rpc-bind-ip 127.0.0.1 --data-dir /home/amnesia/Persistent/your/directory/to/the/blockchain` - -`./monero-wallet-cli` +While Monero isn't made to integrate with Tor, it can be used wrapped with torsocks, by +setting the following configuration parameters and environment variables: + +* `--p2p-bind-ip 127.0.0.1` on the command line or `p2p-bind-ip=127.0.0.1` in + monerod.conf to disable listening for connections on external interfaces. +* `--no-igd` on the command line or `no-igd=1` in monerod.conf to disable IGD + (UPnP port forwarding negotiation), which is pointless with Tor. +* `DNS_PUBLIC=tcp` or `DNS_PUBLIC=tcp://x.x.x.x` where x.x.x.x is the IP of the + desired DNS server, for DNS requests to go over TCP, so that they are routed + through Tor. When IP is not specified, monerod uses the default list of + servers defined in [src/common/dns_utils.cpp](src/common/dns_utils.cpp). +* `TORSOCKS_ALLOW_INBOUND=1` to tell torsocks to allow monerod to bind to interfaces + to accept connections from the wallet. On some Linux systems, torsocks + allows binding to localhost by default, so setting this variable is only + necessary to allow binding to local LAN/VPN interfaces to allow wallets to + connect from remote hosts. On other systems, it may be needed for local wallets + as well. +* Do NOT pass `--detach` when running through torsocks with systemd, (see + [utils/systemd/monerod.service](utils/systemd/monerod.service) for details). + +Example command line to start monerod through Tor: + + DNS_PUBLIC=tcp torsocks monerod --p2p-bind-ip 127.0.0.1 --no-igd + +### Using Tor on Tails + +TAILS ships with a very restrictive set of firewall rules. Therefore, you need +to add a rule to allow this connection too, in addition to telling torsocks to +allow inbound connections. Full example: + + sudo iptables -I OUTPUT 2 -p tcp -d 127.0.0.1 -m tcp --dport 18081 -j ACCEPT + DNS_PUBLIC=tcp torsocks ./monerod --p2p-bind-ip 127.0.0.1 --no-igd --rpc-bind-ip 127.0.0.1 \ + --data-dir /home/amnesia/Persistent/your/directory/to/the/blockchain ## Debugging diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 35c099697..71dcedcab 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -33,7 +33,6 @@ set(crypto_sources crypto-ops-data.c crypto-ops.c crypto.cpp - crypto_device.cpp groestl.c hash-extra-blake.c hash-extra-groestl.c @@ -78,7 +77,6 @@ monero_add_library(cncrypto target_link_libraries(cncrypto PUBLIC epee - device ${Boost_SYSTEM_LIBRARY} PRIVATE ${EXTRA_LIBRARIES}) diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index 22da53bd0..7a120931a 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -69,10 +69,17 @@ namespace crypto { chacha20(data, length, key.data(), reinterpret_cast<const uint8_t*>(&iv), cipher); } - inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, int cn_variant = 0, bool prehashed=false) { + inline void generate_chacha_key(const void *data, size_t size, chacha_key& key) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); tools::scrubbed_arr<char, HASH_SIZE> pwd_hash; - crypto::cn_slow_hash_pre(data, size, pwd_hash.data(), cn_variant, prehashed); + crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/); + memcpy(&key, pwd_hash.data(), sizeof(key)); + } + + inline void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key) { + static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); + tools::scrubbed_arr<char, HASH_SIZE> pwd_hash; + crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/); memcpy(&key, pwd_hash.data(), sizeof(key)); } diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index 0c70b9eeb..494027560 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -436,7 +436,7 @@ namespace crypto { return sc_isnonzero(&c2) == 0; } - void crypto_ops::hash_to_ec(const public_key &key, ge_p3 &res) { + static void hash_to_ec(const public_key &key, ge_p3 &res) { hash h; ge_p2 point; ge_p1p1 point2; diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 75b333473..81ebfb9e2 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -46,10 +46,6 @@ #include "hex.h" #include "span.h" #include "hash.h" -#include "device/device_declare.hpp" -extern "C" { - #include "crypto-ops.h" -} namespace crypto { @@ -117,9 +113,6 @@ namespace crypto { void operator=(const crypto_ops &); ~crypto_ops(); - static void hash_to_ec(const public_key &key, ge_p3 &res) ; - friend void hash_to_ec(const public_key &key, ge_p3 &res) ; - static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false); friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover); static bool check_key(const public_key &); @@ -156,17 +149,6 @@ namespace crypto { const public_key *const *, std::size_t, const signature *); }; - secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover, hw::device &hwdev); - secret_key generate_keys(public_key &pub, secret_key &sec, hw::device &hwdev); - bool secret_key_to_public_key(const secret_key &sec, public_key &pub, hw::device &hwdev); - bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation, hw::device &hwdev); - void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res, hw::device &hwdev) ; - bool derive_public_key(const key_derivation &derivation, size_t output_index, const public_key &base, public_key &derived_key, hw::device &hwdev); - void derive_secret_key(const key_derivation &derivation, size_t output_index, const secret_key &base, secret_key &derived_key, hw::device &hwdev); - bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &derived_key, hw::device &hwdev); - void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image, hw::device &hwdev); - - /* Generate N random bytes */ inline void rand(size_t N, uint8_t *bytes) { @@ -184,9 +166,6 @@ namespace crypto { return res; } - inline void hash_to_ec(const public_key &key, ge_p3 &res) { - crypto_ops::hash_to_ec(key,res); - } /* Generate a new key pair */ inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) { diff --git a/src/crypto/crypto_device.cpp b/src/crypto/crypto_device.cpp deleted file mode 100644 index 5536857c8..000000000 --- a/src/crypto/crypto_device.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// 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 "crypto.h" -#include "device/device.hpp" -#include "device/log.hpp" - -namespace crypto { - - secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover, hw::device &hwdev) { - secret_key rng; - hwdev.generate_keys(pub, sec, recovery_key, recover, rng); - return rng; - } - - secret_key generate_keys(public_key &pub, secret_key &sec, hw::device &hwdev) { - secret_key rng; - hwdev.generate_keys(pub, sec, secret_key(), false, rng); - return rng; - } - - - bool secret_key_to_public_key(const secret_key &sec, public_key &pub, hw::device &hwdev) { - return hwdev.secret_key_to_public_key(sec, pub); - } - - bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation, hw::device &hwdev) { - return hwdev.generate_key_derivation(key1, key2, derivation); - } - - void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res, hw::device &hwdev) { - hwdev.derivation_to_scalar(derivation, output_index, res); - } - - bool derive_public_key(const key_derivation &derivation, size_t output_index, - const public_key &base, public_key &derived_key, hw::device &hwdev) { - return hwdev.derive_public_key(derivation, output_index, base, derived_key); - } - - void derive_secret_key(const key_derivation &derivation, size_t output_index, - const secret_key &base, secret_key &derived_key, hw::device &hwdev) { - hwdev.derive_secret_key(derivation, output_index, base, derived_key); - } - - bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &derived_key, hw::device &hwdev) { - return hwdev.derive_subaddress_public_key(out_key, derivation, output_index, derived_key); - } - - void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image, hw::device &hwdev) { - hwdev.generate_key_image(pub,sec,image); - } -}
\ No newline at end of file diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index 934d464de..d77d55cf3 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -79,8 +79,7 @@ enum { }; void cn_fast_hash(const void *data, size_t length, char *hash); -void cn_slow_hash(const void *data, size_t length, char *hash, int variant); -void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool pre); +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed); void hash_extra_blake(const void *data, size_t length, char *hash); void hash_extra_groestl(const void *data, size_t length, char *hash); diff --git a/src/crypto/hash.h b/src/crypto/hash.h index bf4f4c096..995e2294e 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -72,7 +72,11 @@ namespace crypto { } inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0) { - cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant); + cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/); + } + + inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0) { + cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/); } inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index 8c7dad8e0..d7dcbd274 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -564,11 +564,7 @@ void slow_hash_free_state(void) * @param length the length in bytes of the data * @param hash a pointer to a buffer in which the final 256 bit hash will be stored */ -void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { - cn_slow_hash_pre(data,length,hash,variant,false); -} - -void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool prehashed) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { RDATA_ALIGN16 uint8_t expandedKey[240]; /* These buffers are aligned to use later with SSE functions */ @@ -909,7 +905,7 @@ STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out, const u } } -void cn_slow_hash(const void *data, size_t length, char *hash, int variant) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { RDATA_ALIGN16 uint8_t expandedKey[240]; RDATA_ALIGN16 uint8_t hp_state[MEMORY]; @@ -932,7 +928,11 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) /* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */ - hash_process(&state.hs, data, length); + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + hash_process(&state.hs, data, length); + } memcpy(text, state.init, INIT_SIZE_BYTE); VARIANT1_INIT64(); @@ -1105,7 +1105,7 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b) U64(a)[1] ^= U64(b)[1]; } -void cn_slow_hash(const void *data, size_t length, char *hash, int variant) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; @@ -1131,7 +1131,11 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) long_state = (uint8_t *)malloc(MEMORY); #endif - hash_process(&state.hs, data, length); + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + hash_process(&state.hs, data, length); + } memcpy(text, state.init, INIT_SIZE_BYTE); VARIANT1_INIT64(); @@ -1289,7 +1293,7 @@ union cn_slow_hash_state { }; #pragma pack(pop) -void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { uint8_t long_state[MEMORY]; union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; @@ -1301,7 +1305,11 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { uint8_t aes_key[AES_KEY_SIZE]; oaes_ctx *aes_ctx; - hash_process(&state.hs, data, length); + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + hash_process(&state.hs, data, length); + } memcpy(text, state.init, INIT_SIZE_BYTE); memcpy(aes_key, state.hs.b, AES_KEY_SIZE); aes_ctx = (oaes_ctx *) oaes_alloc(); diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index 375b17389..bab991d19 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -40,7 +40,6 @@ extern "C" } #include "cryptonote_basic_impl.h" #include "cryptonote_format_utils.h" -#include "device/device.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "account" @@ -140,9 +139,7 @@ DISABLE_VS_WARNINGS(4244 4345) hwdev.init(); hwdev.connect(); hwdev.get_public_address(m_keys.m_account_address); - #ifdef DEBUG_HWDEVICE hwdev.get_secret_keys(m_keys.m_view_secret_key, m_keys.m_spend_secret_key); - #endif struct tm timestamp = {0}; timestamp.tm_year = 2014 - 1900; // year 2014 timestamp.tm_mon = 4 - 1; // month april diff --git a/src/cryptonote_basic/account.h b/src/cryptonote_basic/account.h index b5d6ed85d..b5d119c46 100644 --- a/src/cryptonote_basic/account.h +++ b/src/cryptonote_basic/account.h @@ -33,7 +33,6 @@ #include "cryptonote_basic.h" #include "crypto/crypto.h" #include "serialization/keyvalue_serialization.h" -#include "device/device_declare.hpp" namespace cryptonote { diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 4c5f32a09..d4558ef7b 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -49,6 +49,7 @@ #include "misc_language.h" #include "tx_extra.h" #include "ringct/rctTypes.h" +#include "device/device.hpp" namespace cryptonote { @@ -428,16 +429,10 @@ namespace cryptonote crypto::public_key pub; crypto::secret_key sec; - static inline keypair generate() - { - keypair k; - generate_keys(k.pub, k.sec); - return k; - } static inline keypair generate(hw::device &hwdev) { keypair k; - generate_keys(k.pub, k.sec, hwdev); + hwdev.generate_keys(k.pub, k.sec); return k; } }; diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index a10772424..ae7c1c0ae 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -41,8 +41,6 @@ using namespace epee; #include "crypto/crypto.h" #include "crypto/hash.h" #include "ringct/rctSigs.h" -#include "device/device.hpp" -#include "device/log.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "cn" @@ -106,16 +104,6 @@ namespace cryptonote ge_p1p1_to_p3(&A2, &tmp3); ge_p3_tobytes(&AB, &A2); } - - // a copy of rct::scalarmultKey, since we can't link to libringct to avoid circular dependencies - static void secret_key_mult_public_key(crypto::public_key & aP, const crypto::public_key &P, const crypto::secret_key &a) { - ge_p3 A; - ge_p2 R; - //CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); - ge_frombytes_vartime(&A, (const unsigned char*)P.data); - ge_scalarmult(&R, (const unsigned char*)a.data, &A); - ge_tobytes((unsigned char*)aP.data, &R); - } } namespace cryptonote @@ -172,83 +160,17 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index) - { - const char prefix[] = "SubAddr"; - char data[sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(subaddress_index)]; - memcpy(data, prefix, sizeof(prefix)); - memcpy(data + sizeof(prefix), &a, sizeof(crypto::secret_key)); - memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &index, sizeof(subaddress_index)); - crypto::secret_key m; - crypto::hash_to_scalar(data, sizeof(data), m); - return m; - } - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index, hw::device &hwdev) - { - crypto::secret_key m; - hwdev.get_subaddress_secret_key(a, index, m); - return m; - } - - //--------------------------------------------------------------- - std::vector<crypto::public_key> get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) - { - CHECK_AND_ASSERT_THROW_MES(begin <= end, "begin > end"); - - std::vector<crypto::public_key> pkeys; - pkeys.reserve(end - begin); - cryptonote::subaddress_index index = {account, begin}; - - ge_p3 p3; - ge_cached cached; - CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, (const unsigned char*)keys.m_account_address.m_spend_public_key.data) == 0, - "ge_frombytes_vartime failed to convert spend public key"); - ge_p3_to_cached(&cached, &p3); - - for (uint32_t idx = begin; idx < end; ++idx) - { - index.minor = idx; - if (index.is_zero()) - { - pkeys.push_back(keys.m_account_address.m_spend_public_key); - continue; - } - const crypto::secret_key m = cryptonote::get_subaddress_secret_key(keys.m_view_secret_key, index); - - // M = m*G - ge_scalarmult_base(&p3, (const unsigned char*)m.data); - - // D = B + M - crypto::public_key D; - ge_p1p1 p1p1; - ge_add(&p1p1, &p3, &cached); - ge_p1p1_to_p3(&p3, &p1p1); - ge_p3_tobytes((unsigned char*)D.data, &p3); - - pkeys.push_back(D); - } - return pkeys; - } - - std::vector<crypto::public_key> get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, hw::device &hwdev) - { - std::vector<crypto::public_key> pkeys; - hwdev.get_subaddress_spend_public_keys(keys, account, begin, end, pkeys); - return pkeys; - } - - //--------------------------------------------------------------- bool generate_key_image_helper(const account_keys& ack, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev) { crypto::key_derivation recv_derivation = AUTO_VAL_INIT(recv_derivation); - bool r = crypto::generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation, hwdev); + bool r = hwdev.generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation); CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")"); std::vector<crypto::key_derivation> additional_recv_derivations; for (size_t i = 0; i < additional_tx_public_keys.size(); ++i) { crypto::key_derivation additional_recv_derivation = AUTO_VAL_INIT(additional_recv_derivation); - r = crypto::generate_key_derivation(additional_tx_public_keys[i], ack.m_view_secret_key, additional_recv_derivation, hwdev); + r = hwdev.generate_key_derivation(additional_tx_public_keys[i], ack.m_view_secret_key, additional_recv_derivation); CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to generate_key_derivation(" << additional_tx_public_keys[i] << ", " << ack.m_view_secret_key << ")"); additional_recv_derivations.push_back(additional_recv_derivation); } @@ -271,7 +193,7 @@ namespace cryptonote { // derive secret key with subaddress - step 1: original CN derivation crypto::secret_key scalar_step1; - crypto::derive_secret_key(recv_derivation, real_output_index, ack.m_spend_secret_key, scalar_step1, hwdev); // computes Hs(a*R || idx) + b + hwdev.derive_secret_key(recv_derivation, real_output_index, ack.m_spend_secret_key, scalar_step1); // computes Hs(a*R || idx) + b // step 2: add Hs(a || index_major || index_minor) crypto::secret_key subaddr_sk; @@ -282,7 +204,7 @@ namespace cryptonote } else { - hwdev.get_subaddress_secret_key(ack.m_view_secret_key, received_index, subaddr_sk); + subaddr_sk = hwdev.get_subaddress_secret_key(ack.m_view_secret_key, received_index); hwdev.sc_secret_add(scalar_step2, scalar_step1,subaddr_sk); } @@ -291,17 +213,17 @@ namespace cryptonote if (ack.m_multisig_keys.empty()) { // when not in multisig, we know the full spend secret key, so the output pubkey can be obtained by scalarmultBase - CHECK_AND_ASSERT_MES(crypto::secret_key_to_public_key(in_ephemeral.sec, in_ephemeral.pub, hwdev), false, "Failed to derive public key"); + CHECK_AND_ASSERT_MES(hwdev.secret_key_to_public_key(in_ephemeral.sec, in_ephemeral.pub), false, "Failed to derive public key"); } else { // when in multisig, we only know the partial spend secret key. but we do know the full spend public key, so the output pubkey can be obtained by using the standard CN key derivation - CHECK_AND_ASSERT_MES(crypto::derive_public_key(recv_derivation, real_output_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub, hwdev), false, "Failed to derive public key"); + CHECK_AND_ASSERT_MES(hwdev.derive_public_key(recv_derivation, real_output_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub), false, "Failed to derive public key"); // and don't forget to add the contribution from the subaddress part if (!received_index.is_zero()) { crypto::public_key subaddr_pk; - CHECK_AND_ASSERT_MES(crypto::secret_key_to_public_key(subaddr_sk, subaddr_pk, hwdev), false, "Failed to derive public key"); + CHECK_AND_ASSERT_MES(hwdev.secret_key_to_public_key(subaddr_sk, subaddr_pk), false, "Failed to derive public key"); add_public_key(in_ephemeral.pub, in_ephemeral.pub, subaddr_pk); } } @@ -310,7 +232,7 @@ namespace cryptonote false, "key image helper precomp: given output pubkey doesn't match the derived one"); } - crypto::generate_key_image(in_ephemeral.pub, in_ephemeral.sec, ki, hwdev); + hwdev.generate_key_image(in_ephemeral.pub, in_ephemeral.sec, ki); return true; } //--------------------------------------------------------------- @@ -574,41 +496,6 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) - { - crypto::key_derivation derivation; - crypto::hash hash; - char data[33]; /* A hash, and an extra byte */ - - if (!generate_key_derivation(public_key, secret_key, derivation)) - return false; - - memcpy(data, &derivation, 32); - data[32] = ENCRYPTED_PAYMENT_ID_TAIL; - cn_fast_hash(data, 33, hash); - - for (size_t b = 0; b < 8; ++b) - payment_id.data[b] ^= hash.data[b]; - - return true; - } - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) - { - // Encryption and decryption are the same operation (xor with a key) - return encrypt_payment_id(payment_id, public_key, secret_key); - } - - //--------------------------------------------------------------- - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key,hw::device &hwdev) - { - return hwdev.encrypt_payment_id(public_key, secret_key, payment_id); - } - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key, hw::device &hwdev) - { - // Encryption and decryption are the same operation (xor with a key) - return encrypt_payment_id(payment_id, public_key, secret_key, hwdev); - } - //--------------------------------------------------------------- bool get_inputs_money_amount(const transaction& tx, uint64_t& money) { money = 0; @@ -708,10 +595,10 @@ namespace cryptonote bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, const std::vector<crypto::public_key>& additional_tx_pub_keys, size_t output_index) { crypto::key_derivation derivation; - bool r = generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation, acc.get_device()); + bool r = acc.get_device().generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation"); crypto::public_key pk; - r = derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk, acc.get_device()); + r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk); CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key"); if (pk == out_key.key) return true; @@ -719,9 +606,9 @@ namespace cryptonote if (!additional_tx_pub_keys.empty()) { CHECK_AND_ASSERT_MES(output_index < additional_tx_pub_keys.size(), false, "wrong number of additional tx pubkeys"); - r = generate_key_derivation(additional_tx_pub_keys[output_index], acc.m_view_secret_key, derivation, acc.get_device()); + r = acc.get_device().generate_key_derivation(additional_tx_pub_keys[output_index], acc.m_view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation"); - r = derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk, acc.get_device()); + r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk); CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key"); return pk == out_key.key; } @@ -732,7 +619,7 @@ namespace cryptonote { // try the shared tx pubkey crypto::public_key subaddress_spendkey; - derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey,hwdev); + hwdev.derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey); auto found = subaddresses.find(subaddress_spendkey); if (found != subaddresses.end()) return subaddress_receive_info{ found->second, derivation }; @@ -740,7 +627,7 @@ namespace cryptonote if (!additional_derivations.empty()) { CHECK_AND_ASSERT_MES(output_index < additional_derivations.size(), boost::none, "wrong number of additional derivations"); - derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey, hwdev); + hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey); found = subaddresses.find(subaddress_spendkey); if (found != subaddresses.end()) return subaddress_receive_info{ found->second, additional_derivations[output_index] }; @@ -1140,64 +1027,4 @@ namespace cryptonote sc_sub((unsigned char*)key.data, (const unsigned char*)key.data, (const unsigned char*)hash.data); return key; } - - //--------------------------------------------------------------- - #define CHACHA8_KEY_TAIL 0x8c - bool generate_chacha_key_from_secret_keys(const account_keys &keys, crypto::chacha_key &key) - { - const crypto::secret_key &view_key = keys.m_view_secret_key; - const crypto::secret_key &spend_key = keys.m_spend_secret_key; - tools::scrubbed_arr<char, sizeof(view_key) + sizeof(spend_key) + 1> data; - memcpy(data.data(), &view_key, sizeof(view_key)); - memcpy(data.data() + sizeof(view_key), &spend_key, sizeof(spend_key)); - data[sizeof(data) - 1] = CHACHA8_KEY_TAIL; - crypto::generate_chacha_key(data.data(), sizeof(data), key); - return true; - } - - //--------------------------------------------------------------- - crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index) - { - if (index.is_zero()) - return keys.m_account_address.m_spend_public_key; - - // m = Hs(a || index_major || index_minor) - crypto::secret_key m = cryptonote::get_subaddress_secret_key(keys.m_view_secret_key, index); - - // M = m*G - crypto::public_key M; - crypto::secret_key_to_public_key(m, M); - - // D = B + M - crypto::public_key D; - add_public_key(D, keys.m_account_address.m_spend_public_key, M); // could have defined add_public_key() under src/crypto - return D; - } - - //--------------------------------------------------------------- - cryptonote::account_public_address get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index) - { - if (index.is_zero()) - return keys.m_account_address; - - crypto::public_key D = get_subaddress_spend_public_key(keys, index); - - // C = a*D - crypto::public_key C; - secret_key_mult_public_key(C, D, keys.m_view_secret_key); // could have defined secret_key_mult_public_key() under src/crypto - - // result: (C, D) - cryptonote::account_public_address address; - address.m_view_public_key = C; - address.m_spend_public_key = D; - return address; - } - - //--------------------------------------------------------------- - bool verify_keys(const crypto::secret_key& sec, const crypto::public_key& expected_pub) - { - crypto::public_key pub; - bool r = crypto::secret_key_to_public_key(sec, pub); - return r && expected_pub == pub; - } } diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index 7bd34ea87..79466e9c4 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -37,7 +37,6 @@ #include "crypto/crypto.h" #include "crypto/hash.h" #include <unordered_map> -#include "device/device_declare.hpp" namespace epee { @@ -52,10 +51,6 @@ namespace cryptonote bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash); bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx); bool parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx); - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key); - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key, hw::device &hwdev); - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key); - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key, hw::device &hwdev); template<typename T> bool find_tx_extra_field_by_type(const std::vector<tx_extra_field>& tx_extra_fields, T& field, size_t index = 0) @@ -95,10 +90,6 @@ namespace cryptonote bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<size_t>& outs, uint64_t& money_transfered); bool get_tx_fee(const transaction& tx, uint64_t & fee); uint64_t get_tx_fee(const transaction& tx); - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index); - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index, hw::device &hwdev); - std::vector<crypto::public_key> get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end); - std::vector<crypto::public_key> get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, hw::device &hwdev); bool generate_key_image_helper(const account_keys& ack, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev); bool generate_key_image_helper_precomp(const account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const subaddress_index& received_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev); void get_blob_hash(const blobdata& blob, crypto::hash& res); @@ -242,10 +233,4 @@ namespace cryptonote #define CHECKED_GET_SPECIFIC_VARIANT(variant_var, specific_type, variable_name, fail_return_val) \ CHECK_AND_ASSERT_MES(variant_var.type() == typeid(specific_type), fail_return_val, "wrong variant type: " << variant_var.type().name() << ", expected " << typeid(specific_type).name()); \ specific_type& variable_name = boost::get<specific_type>(variant_var); - - cryptonote::account_public_address get_subaddress(const cryptonote::account_keys &keys, const cryptonote::subaddress_index& index); - crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys &keys, const cryptonote::subaddress_index& index); - bool generate_chacha_key_from_secret_keys(const cryptonote::account_keys &keys, crypto::chacha_key &key); - bool verify_keys(const crypto::secret_key& sec, const crypto::public_key& expected_pub); - } diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index c97b75f98..d2d43490e 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -106,6 +106,9 @@ static const struct { // version 6 starts from block 1400000, which is on or around the 16th of September, 2017. Fork time finalised on 2017-08-18. { 6, 1400000, 0, 1503046577 }, + + // version 7 starts from block 1539500, which is on or around the 28th of March, 2018. Fork time finalised on 2018-03-07. + { 7, 1539500, 0, 1520436050 }, }; static const uint64_t mainnet_hard_fork_version_1_till = 1009826; @@ -140,6 +143,14 @@ static const struct { } stagenet_hard_forks[] = { // version 1 from the start of the blockchain { 1, 1, 0, 1341378000 }, + + // versions 2-7 in rapid succession from March 13th, 2018 + { 2, 32000, 0, 1521000000 }, + { 3, 33000, 0, 1521120000 }, + { 4, 34000, 0, 1521240000 }, + { 5, 35000, 0, 1521360000 }, + { 6, 36000, 0, 1521480000 }, + { 7, 37000, 0, 1521600000 }, }; //------------------------------------------------------------------ diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index d0a958e1e..db4ab9e11 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -41,7 +41,6 @@ using namespace epee; #include "crypto/hash.h" #include "ringct/rctSigs.h" #include "multisig/multisig.h" -#include "device/device.hpp" using namespace crypto; @@ -79,7 +78,7 @@ namespace cryptonote tx.vout.clear(); tx.extra.clear(); - keypair txkey = keypair::generate(); + keypair txkey = keypair::generate(hw::get_device("default")); add_tx_pub_key_to_extra(tx, txkey.pub); if(!extra_nonce.empty()) if(!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) @@ -237,7 +236,7 @@ namespace cryptonote return false; } - if (!encrypt_payment_id(payment_id, view_key_pub, tx_key, hwdev)) + if (!hwdev.encrypt_payment_id(payment_id, view_key_pub, tx_key)) { LOG_ERROR("Failed to encrypt payment id"); return false; @@ -343,11 +342,11 @@ namespace cryptonote // if this is a single-destination transfer to a subaddress, we set the tx pubkey to R=s*D if (num_stdaddresses == 0 && num_subaddresses == 1) { - txkey_pub = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(single_dest_subaddress.m_spend_public_key), rct::sk2rct(tx_key), hwdev)); + txkey_pub = rct::rct2pk(hwdev.scalarmultKey(rct::pk2rct(single_dest_subaddress.m_spend_public_key), rct::sk2rct(tx_key))); } else { - txkey_pub = rct::rct2pk(rct::scalarmultBase(rct::sk2rct(tx_key), hwdev)); + txkey_pub = rct::rct2pk(hwdev.scalarmultBase(rct::sk2rct(tx_key))); } remove_field_from_tx_extra(tx.extra, typeid(tx_extra_pub_key)); add_tx_pub_key_to_extra(tx, txkey_pub); @@ -376,22 +375,22 @@ namespace cryptonote { additional_txkey.sec = additional_tx_keys[output_index]; if (dst_entr.is_subaddress) - additional_txkey.pub = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec),hwdev)); + additional_txkey.pub = rct::rct2pk(hwdev.scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec))); else - additional_txkey.pub = rct::rct2pk(rct::scalarmultBase(rct::sk2rct(additional_txkey.sec), hwdev)); + additional_txkey.pub = rct::rct2pk(hwdev.scalarmultBase(rct::sk2rct(additional_txkey.sec))); } bool r; if (change_addr && dst_entr.addr == *change_addr) { // sending change to yourself; derivation = a*R - r = crypto::generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation, hwdev); + r = hwdev.generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")"); } else { // sending to the recipient; derivation = r*A (or s*C in the subaddress scheme) - r = crypto::generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation, hwdev); + r = hwdev.generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation); 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) << ")"); } @@ -403,13 +402,13 @@ namespace cryptonote if (tx.version > 1) { crypto::secret_key scalar1; - crypto::derivation_to_scalar(derivation, output_index, scalar1, hwdev); + hwdev.derivation_to_scalar(derivation, output_index, scalar1); amount_keys.push_back(rct::sk2rct(scalar1)); } - r = crypto::derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key, hwdev); + r = hwdev.derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key); CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")"); - hwdev.add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, output_index, amount_keys.back(), out_eph_public_key); + hwdev.add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, output_index, amount_keys.back(), out_eph_public_key); tx_out out; out.amount = dst_entr.amount; diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 7eccc1cc2..cc2d20a54 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -37,7 +37,6 @@ if(PCSC_FOUND) endif() set(device_headers - device_declare.hpp device.hpp device_default.hpp log.hpp @@ -68,7 +67,7 @@ target_link_libraries(device PUBLIC ${PCSC_LIBRARIES} cncrypto - ringct + ringct_basic ${OPENSSL_CRYPTO_LIBRARIES} PRIVATE ${Blocks} diff --git a/src/device/device.cpp b/src/device/device.cpp index 068529388..983f59b60 100644 --- a/src/device/device.cpp +++ b/src/device/device.cpp @@ -67,4 +67,4 @@ namespace hw { return *device->second; } -}
\ No newline at end of file +} diff --git a/src/device/device.hpp b/src/device/device.hpp index bdea7b8f6..b47460472 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -28,11 +28,25 @@ // +/* Note about debug: + * To debug Device you can def the following : + * #define DEBUG_HWDEVICE + * Activate debug mechanism: + * - Add more trace + * - All computation done by device are checked by default device. + * Required IODUMMYCRYPT_HWDEVICE or IONOCRYPT_HWDEVICE for fully working + * #define IODUMMYCRYPT_HWDEVICE 1 + * - It assumes sensitive data encryption is is off on device side. a XOR with 0x55. This allow Ledger Class to make check on clear value + * #define IONOCRYPT_HWDEVICE 1 + * - It assumes sensitive data encryption is off on device side. + */ + + #pragma once -#include "cryptonote_basic/cryptonote_basic.h" -#include "cryptonote_basic/account.h" -#include "cryptonote_basic/subaddress_index.h" +#include "crypto/crypto.h" +#include "crypto/chacha.h" +#include "ringct/rctTypes.h" #ifndef USE_DEVICE_LEDGER #define USE_DEVICE_LEDGER 1 @@ -47,6 +61,14 @@ #define WITH_DEVICE_LEDGER #endif +// forward declaration needed because this header is included by headers in libcryptonote_basic which depends on libdevice +namespace cryptonote +{ + struct account_public_address; + struct account_keys; + struct subaddress_index; +} + namespace hw { namespace { //device funcion not supported @@ -95,10 +117,10 @@ namespace hw { /* SUB ADDRESS */ /* ======================================================================= */ virtual 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) = 0; - virtual bool get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index, crypto::public_key &D) = 0; - virtual bool get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, std::vector<crypto::public_key> &pkeys) = 0; - virtual bool get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index, cryptonote::account_public_address &address) = 0; - virtual bool get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index, crypto::secret_key &sub_sec) = 0; + virtual crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index) = 0; + virtual std::vector<crypto::public_key> get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) = 0; + virtual cryptonote::account_public_address get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) = 0; + virtual crypto::secret_key get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) = 0; /* ======================================================================= */ /* DERIVATION & KEY */ @@ -107,7 +129,7 @@ namespace hw { virtual bool scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) = 0; virtual bool scalarmultBase(rct::key &aG, const rct::key &a) = 0; virtual bool sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) = 0; - virtual bool generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover, crypto::secret_key &rng) = 0; + virtual crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) = 0; virtual bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) = 0; virtual bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) = 0; virtual bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) = 0; @@ -115,6 +137,21 @@ namespace hw { virtual bool secret_key_to_public_key(const crypto::secret_key &sec, crypto::public_key &pub) = 0; virtual bool generate_key_image(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_image &image) = 0; + // alternative prototypes available in libringct + rct::key scalarmultKey(const rct::key &P, const rct::key &a) + { + rct::key aP; + scalarmultKey(aP, P, a); + return aP; + } + + rct::key scalarmultBase(const rct::key &a) + { + rct::key aG; + scalarmultBase(aG, a); + return aG; + } + /* ======================================================================= */ /* TRANSACTION */ /* ======================================================================= */ @@ -123,13 +160,18 @@ namespace hw { virtual bool set_signature_mode(unsigned int sig_mode) = 0; - virtual bool encrypt_payment_id(const crypto::public_key &public_key, const crypto::secret_key &secret_key, crypto::hash8 &payment_id ) = 0; + virtual bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) = 0; + bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) + { + // Encryption and decryption are the same operation (xor with a key) + return encrypt_payment_id(payment_id, public_key, secret_key); + } virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) = 0; virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) = 0; - virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0; + virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, + const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0; virtual bool 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) = 0; diff --git a/src/device/device_declare.hpp b/src/device/device_declare.hpp deleted file mode 100644 index 799052ad2..000000000 --- a/src/device/device_declare.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// 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. -// - -#pragma once - - -//#define DEBUG_HWDEVICE -//#define IODUMMYCRYPT 1 -//#define IONOCRYPT 1 - -namespace hw { - class device; - - device& get_device(std::string device_descriptor); -} - diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index c3ba42000..d63dafe9e 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -31,10 +31,13 @@ #include "device_default.hpp" - -#include "cryptonote_basic/cryptonote_format_utils.h" +#include "cryptonote_basic/account.h" +#include "cryptonote_basic/subaddress_index.h" #include "ringct/rctOps.h" +#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d +#define CHACHA8_KEY_TAIL 0x8c + namespace hw { namespace core { @@ -83,7 +86,14 @@ namespace hw { /* ======================================================================= */ bool device_default::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key) { - return cryptonote::generate_chacha_key_from_secret_keys(keys, key); + const crypto::secret_key &view_key = keys.m_view_secret_key; + const crypto::secret_key &spend_key = keys.m_spend_secret_key; + tools::scrubbed_arr<char, sizeof(view_key) + sizeof(spend_key) + 1> data; + memcpy(data.data(), &view_key, sizeof(view_key)); + memcpy(data.data() + sizeof(view_key), &spend_key, sizeof(spend_key)); + data[sizeof(data) - 1] = CHACHA8_KEY_TAIL; + crypto::generate_chacha_key(data.data(), sizeof(data), key); + return true; } bool device_default::get_public_address(cryptonote::account_public_address &pubkey) { dfns(); @@ -99,24 +109,85 @@ namespace hw { return crypto::derive_subaddress_public_key(out_key, derivation, output_index,derived_key); } - bool device_default::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index, crypto::public_key &D) { - D = cryptonote::get_subaddress_spend_public_key(keys,index); - return true; + crypto::public_key device_default::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { + if (index.is_zero()) + return keys.m_account_address.m_spend_public_key; + + // m = Hs(a || index_major || index_minor) + crypto::secret_key m = get_subaddress_secret_key(keys.m_view_secret_key, index); + + // M = m*G + crypto::public_key M; + crypto::secret_key_to_public_key(m, M); + + // D = B + M + crypto::public_key D = rct::rct2pk(rct::addKeys(rct::pk2rct(keys.m_account_address.m_spend_public_key), rct::pk2rct(M))); + return D; } - bool device_default::get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, std::vector<crypto::public_key> &pkeys) { - pkeys = cryptonote::get_subaddress_spend_public_keys(keys, account, begin, end); - return true; + std::vector<crypto::public_key> device_default::get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) { + CHECK_AND_ASSERT_THROW_MES(begin <= end, "begin > end"); + + std::vector<crypto::public_key> pkeys; + pkeys.reserve(end - begin); + cryptonote::subaddress_index index = {account, begin}; + + ge_p3 p3; + ge_cached cached; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, (const unsigned char*)keys.m_account_address.m_spend_public_key.data) == 0, + "ge_frombytes_vartime failed to convert spend public key"); + ge_p3_to_cached(&cached, &p3); + + for (uint32_t idx = begin; idx < end; ++idx) + { + index.minor = idx; + if (index.is_zero()) + { + pkeys.push_back(keys.m_account_address.m_spend_public_key); + continue; + } + crypto::secret_key m = get_subaddress_secret_key(keys.m_view_secret_key, index); + + // M = m*G + ge_scalarmult_base(&p3, (const unsigned char*)m.data); + + // D = B + M + crypto::public_key D; + ge_p1p1 p1p1; + ge_add(&p1p1, &p3, &cached); + ge_p1p1_to_p3(&p3, &p1p1); + ge_p3_tobytes((unsigned char*)D.data, &p3); + + pkeys.push_back(D); + } + return pkeys; } - bool device_default::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index, cryptonote::account_public_address &address) { - address = cryptonote::get_subaddress(keys,index); - return true; + cryptonote::account_public_address device_default::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { + if (index.is_zero()) + return keys.m_account_address; + + crypto::public_key D = get_subaddress_spend_public_key(keys, index); + + // C = a*D + crypto::public_key C = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(D), rct::sk2rct(keys.m_view_secret_key))); + + // result: (C, D) + cryptonote::account_public_address address; + address.m_view_public_key = C; + address.m_spend_public_key = D; + return address; } - bool device_default::get_subaddress_secret_key(const crypto::secret_key &a, const cryptonote::subaddress_index &index, crypto::secret_key &m) { - m = cryptonote::get_subaddress_secret_key(a,index); - return true; + crypto::secret_key device_default::get_subaddress_secret_key(const crypto::secret_key &a, const cryptonote::subaddress_index &index) { + const char prefix[] = "SubAddr"; + char data[sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(cryptonote::subaddress_index)]; + memcpy(data, prefix, sizeof(prefix)); + memcpy(data + sizeof(prefix), &a, sizeof(crypto::secret_key)); + memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &index, sizeof(cryptonote::subaddress_index)); + crypto::secret_key m; + crypto::hash_to_scalar(data, sizeof(data), m); + return m; } /* ======================================================================= */ @@ -124,7 +195,9 @@ namespace hw { /* ======================================================================= */ bool device_default::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) { - return cryptonote::verify_keys(secret_key, public_key); + crypto::public_key calculated_pub; + bool r = crypto::secret_key_to_public_key(secret_key, calculated_pub); + return r && public_key == calculated_pub; } bool device_default::scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) { @@ -142,9 +215,8 @@ namespace hw { return true; } - bool device_default::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover, crypto::secret_key &rng) { - rng = crypto::generate_keys(pub, sec, recovery_key, recover); - return true; + crypto::secret_key device_default::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover) { + return crypto::generate_keys(pub, sec, recovery_key, recover); } bool device_default::generate_key_derivation(const crypto::public_key &key1, const crypto::secret_key &key2, crypto::key_derivation &derivation) { @@ -179,13 +251,13 @@ namespace hw { /* ======================================================================= */ bool device_default::open_tx(crypto::secret_key &tx_key) { - cryptonote::keypair txkey = cryptonote::keypair::generate(); + cryptonote::keypair txkey = cryptonote::keypair::generate(*this); tx_key = txkey.sec; return true; } - bool device_default::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, + bool device_default::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, const rct::key &amount_key, const crypto::public_key &out_eph_public_key) { return true; } @@ -194,8 +266,22 @@ namespace hw { return true; } - bool device_default::encrypt_payment_id(const crypto::public_key &public_key, const crypto::secret_key &secret_key, crypto::hash8 &payment_id ) { - return cryptonote::encrypt_payment_id(payment_id, public_key, secret_key); + bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { + crypto::key_derivation derivation; + crypto::hash hash; + char data[33]; /* A hash, and an extra byte */ + + if (!generate_key_derivation(public_key, secret_key, derivation)) + return false; + + memcpy(data, &derivation, 32); + data[32] = ENCRYPTED_PAYMENT_ID_TAIL; + cn_fast_hash(data, 33, hash); + + for (size_t b = 0; b < 8; ++b) + payment_id.data[b] ^= hash.data[b]; + + return true; } bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) { diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index f5b158a3b..02faeba0c 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -70,10 +70,10 @@ namespace hw { /* SUB ADDRESS */ /* ======================================================================= */ 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 get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index, crypto::public_key &D) override; - bool get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, std::vector<crypto::public_key> &pkeys) override; - bool get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index, cryptonote::account_public_address &address) override; - bool get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index, crypto::secret_key &sub_sec) override; + crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index) 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; + cryptonote::account_public_address get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) override; + crypto::secret_key get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) override; /* ======================================================================= */ /* DERIVATION & KEY */ @@ -82,7 +82,7 @@ namespace hw { bool scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) override; bool scalarmultBase(rct::key &aG, const rct::key &a) override; bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override; - bool generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover, crypto::secret_key &rng) override; + crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override; bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override; bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override; bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override; @@ -100,13 +100,13 @@ namespace hw { //bool get_additional_key(const bool subaddr, cryptonote::keypair &additional_txkey) override; bool set_signature_mode(unsigned int sig_mode) override; - bool encrypt_payment_id(const crypto::public_key &public_key, const crypto::secret_key &secret_key, crypto::hash8 &payment_id ) override; + bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override; - bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; + bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, + const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; bool 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) override; diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 571d42724..b3c0035a1 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -30,6 +30,8 @@ #include "device_ledger.hpp" #include "log.hpp" #include "ringct/rctOps.h" +#include "cryptonote_basic/account.h" +#include "cryptonote_basic/subaddress_index.h" @@ -55,30 +57,29 @@ namespace hw { #define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ; #ifdef DEBUG_HWDEVICE - #define DEVICE_CONTROLE :controle_device(hw::get_device("default")) crypto::secret_key viewkey; crypto::secret_key spendkey; - #else - #define DEVICE_CONTROLE #endif /* ===================================================================== */ /* === Keymap ==== */ /* ===================================================================== */ - ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, size_t real_output_index, const rct::key& P, const rct::key& AK) { + ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, const size_t real_output_index, const rct::key& P, const rct::key& AK) { Aout = A; Bout = B; + is_subaddress = is_subaddr; index = real_output_index; Pout = P; AKout = AK; } ABPkeys::ABPkeys(const ABPkeys& keys) { - Aout = keys.Aout; - Bout = keys.Bout; + Aout = keys.Aout; + Bout = keys.Bout; + is_subaddress = keys.is_subaddress; index = keys.index; - Pout = keys.Pout; + Pout = keys.Pout; AKout = keys.AKout; } @@ -109,6 +110,7 @@ namespace hw { log_message(" keymap", std::to_string(i)); log_hexbuffer(" Aout", (char*)ABP[i].Aout.bytes, 32); log_hexbuffer(" Bout", (char*)ABP[i].Bout.bytes, 32); + log_message (" is_sub", std::to_string(ABP[i].is_subaddress)); log_message (" index", std::to_string(ABP[i].index)); log_hexbuffer(" Pout", (char*)ABP[i].Pout.bytes, 32); } @@ -189,7 +191,7 @@ namespace hw { } /* -------------------------------------------------------------- */ - device_ledger::device_ledger() DEVICE_CONTROLE { + device_ledger::device_ledger() { this->id = device_id++; this->hCard = 0; this->hContext = 0; @@ -300,6 +302,9 @@ namespace hw { } bool device_ledger::init(void) { + #ifdef DEBUG_HWDEVICE + this->controle_device = &hw::get_device("default"); + #endif LONG rv; this->release(); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM,0,0, &this->hContext); @@ -411,12 +416,6 @@ namespace hw { /* WALLET & ADDRESS */ /* ======================================================================= */ - bool device_ledger::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) { - memset(viewkey.data, 0x00, 32); - memset(spendkey.data, 0xFF, 32); - return true; - } - /* Application API */ bool device_ledger::get_public_address(cryptonote::account_public_address &pubkey){ @@ -449,8 +448,11 @@ namespace hw { return true; } - #ifdef DEBUG_HWDEVICE bool device_ledger::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) { + memset(viewkey.data, 0x00, 32); + memset(spendkey.data, 0xFF, 32); + + #ifdef DEBUG_HWDEVICE lock_device(); try { //spcialkey, normal conf handled in decrypt @@ -479,9 +481,9 @@ namespace hw { unlock_device(); throw; } + #endif return true; } - #endif bool device_ledger::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key) { lock_device(); @@ -489,9 +491,9 @@ namespace hw { int offset; #ifdef DEBUG_HWDEVICE - const cryptonote::account_keys keys_x = decrypt(keys); crypto::chacha_key key_x; - this->controle_device.generate_chacha_key(keys_x, key_x); + cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); + this->controle_device->generate_chacha_key(keys_x, key_x); #endif reset_buffer(); @@ -511,10 +513,10 @@ namespace hw { char prekey[200]; memmove(prekey, &this->buffer_recv[0], 200); - crypto::generate_chacha_key(&prekey[0], sizeof(prekey), key, 0, true); + crypto::generate_chacha_key_prehashed(&prekey[0], sizeof(prekey), key); #ifdef DEBUG_HWDEVICE - hw::ledger::check32("generate_chacha_key", "key", (char*)key_x.data(), (char*)key.data()); + hw::ledger::check32("generate_chacha_key_prehashed", "key", (char*)key_x.data(), (char*)key.data()); #endif unlock_device(); @@ -541,7 +543,11 @@ namespace hw { const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); const std::size_t output_index_x = output_index; crypto::public_key derived_pub_x; - this->controle_device.derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32); + hw::ledger::log_message ("derive_subaddress_public_key: [[IN]] index ", std::to_string((int)output_index_x)); + this->controle_device->derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32); #endif reset_buffer(); @@ -589,7 +595,8 @@ namespace hw { return true; } - bool device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index, crypto::public_key &D) { + crypto::public_key device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { + crypto::public_key D; lock_device(); try { int offset =0; @@ -599,7 +606,11 @@ namespace hw { const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::subaddress_index index_x = index; crypto::public_key D_x; - this->controle_device.get_subaddress_spend_public_key(keys_x, index_x, D_x); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32); + hw::ledger::log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); + this->controle_device->get_subaddress_spend_public_key(keys_x, index_x, D_x); + hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32); #endif if (index.is_zero()) { @@ -638,21 +649,23 @@ namespace hw { unlock_device(); throw; } - return true; + return D; } - bool device_ledger::get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, std::vector<crypto::public_key> &pkeys) { + std::vector<crypto::public_key> device_ledger::get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) { + std::vector<crypto::public_key> pkeys; cryptonote::subaddress_index index = {account, begin}; crypto::public_key D; for (uint32_t idx = begin; idx < end; ++idx) { index.minor = idx; - this->get_subaddress_spend_public_key(keys, index, D); + D = this->get_subaddress_spend_public_key(keys, index); pkeys.push_back(D); } - return true; + return pkeys; } - bool device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index, cryptonote::account_public_address &address) { + cryptonote::account_public_address device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { + cryptonote::account_public_address address; lock_device(); try { int offset =0; @@ -662,7 +675,14 @@ namespace hw { const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::subaddress_index index_x = index; cryptonote::account_public_address address_x; - this->controle_device.get_subaddress(keys_x, index_x, address_x); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32); + hw::ledger::log_message ("get_subaddress: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); + this->controle_device->get_subaddress(keys_x, index_x, address_x); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32); + hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32); #endif if (index.is_zero()) { @@ -702,10 +722,11 @@ namespace hw { unlock_device(); throw; } - return true; + return address; } - bool device_ledger::get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index, crypto::secret_key &sub_sec) { + crypto::secret_key device_ledger::get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) { + crypto::secret_key sub_sec; lock_device(); try { int offset =0; @@ -715,7 +736,10 @@ namespace hw { const crypto::secret_key sec_x = hw::ledger::decrypt(sec); const cryptonote::subaddress_index index_x = index; crypto::secret_key sub_sec_x; - this->controle_device.get_subaddress_secret_key(sec_x, index_x, sub_sec_x); + hw::ledger::log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor)); + hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32); + this->controle_device->get_subaddress_secret_key(sec_x, index_x, sub_sec_x); + hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32); #endif reset_buffer(); @@ -753,7 +777,7 @@ namespace hw { unlock_device(); throw; } - return true; + return sub_sec; } /* ======================================================================= */ @@ -808,10 +832,13 @@ namespace hw { unsigned char options = 0; #ifdef DEBUG_HWDEVICE - const rct::key pub_x = pub; - const rct::key sec_x = hw::ledger::decrypt(sec); - rct::key mulkey_x; - this->controle_device.scalarmultKey(pub_x, sec_x, mulkey_x); + const rct::key P_x = P; + const rct::key a_x = hw::ledger::decrypt(a); + rct::key aP_x; + hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] P ", (char*)P_x.bytes, 32); + hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32); + this->controle_device->scalarmultKey(aP_x, P_x, a_x); + hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aP", (char*)aP_x.bytes, 32); #endif reset_buffer(); @@ -843,7 +870,7 @@ namespace hw { memmove(aP.bytes, &this->buffer_recv[0], 32); #ifdef DEBUG_HWDEVICE - hw::ledger::check32("scalarmultKey", "mulkey", (char*)mulkey_x.bytes, (char*)mulkey.bytes); + hw::ledger::check32("scalarmultKey", "mulkey", (char*)aP_x.bytes, (char*)aP.bytes); #endif unlock_device(); @@ -861,9 +888,11 @@ namespace hw { unsigned char options = 0; #ifdef DEBUG_HWDEVICE - const rct::key sec_x = hw::ledger::decrypt(sec); - rct::key mulkey_x; - this->controle_device.scalarmultBase(sec_x, mulkey_x); + const rct::key a_x = hw::ledger::decrypt(a); + rct::key aG_x; + hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32); + this->controle_device->scalarmultBase(aG_x, a_x); + hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aG", (char*)aG_x.bytes, 32); #endif reset_buffer(); @@ -891,7 +920,7 @@ namespace hw { memmove(aG.bytes, &this->buffer_recv[0], 32); #ifdef DEBUG_HWDEVICE - hw::ledger::check32("scalarmultBase", "mulkey", (char*)mulkey_x.bytes, (char*)mulkey.bytes); + hw::ledger::check32("scalarmultBase", "mulkey", (char*)aG_x.bytes, (char*)aG.bytes); #endif unlock_device(); @@ -913,7 +942,7 @@ namespace hw { const crypto::secret_key a_x = hw::ledger::decrypt(a); const crypto::secret_key b_x = hw::ledger::decrypt(b); crypto::secret_key r_x; - this->controle_device.sc_secret_add(r_x, a_x, b_x); + this->controle_device->sc_secret_add(r_x, a_x, b_x); #endif reset_buffer(); @@ -956,7 +985,7 @@ namespace hw { return true; } - bool device_ledger::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover, crypto::secret_key &rng) { + crypto::secret_key device_ledger::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover) { if (recover) { throw std::runtime_error("device generate key does not support recover"); } @@ -1007,7 +1036,7 @@ namespace hw { unlock_device(); throw; } - return true; + return sec; } @@ -1021,10 +1050,10 @@ namespace hw { const crypto::public_key pub_x = pub; const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::key_derivation derivation_x; - this->controle_device.generate_key_derivation(pub_x, sec_x, derivation_x); - hw::ledger::log_hexbuffer("generate_key_derivation: sec_x.data", sec_x.data, 32); - hw::ledger::log_hexbuffer("generate_key_derivation: pub_x.data", pub_x.data, 32); - hw::ledger::log_hexbuffer("generate_key_derivation: derivation_x.data", derivation_x.data, 32); + hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32); + hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32); + this->controle_device->generate_key_derivation(pub_x, sec_x, derivation_x); + hw::ledger::log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32); #endif reset_buffer(); @@ -1075,7 +1104,10 @@ namespace hw { const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); const size_t output_index_x = output_index; crypto::ec_scalar res_x; - this->controle_device.derivation_to_scalar(derivation_x, output_index_x, res_x); + hw::ledger::log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32); + hw::ledger::log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index_x)); + this->controle_device->derivation_to_scalar(derivation_x, output_index_x, res_x); + hw::ledger::log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data, 32); #endif reset_buffer(); @@ -1132,7 +1164,11 @@ namespace hw { const std::size_t output_index_x = output_index; const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::secret_key derived_sec_x; - this->controle_device.derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x); + hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data, 32); + hw::ledger::log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index_x)); + hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data, 32); + this->controle_device->derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x); + hw::ledger::log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32); #endif reset_buffer(); @@ -1192,7 +1228,11 @@ namespace hw { const std::size_t output_index_x = output_index; const crypto::public_key pub_x = pub; crypto::public_key derived_pub_x; - this->controle_device.derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x); + hw::ledger::log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data, 32); + hw::ledger::log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index_x)); + hw::ledger::log_hexbuffer("derive_public_key: [[IN]] pub ", pub_x.data, 32); + this->controle_device->derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x); + hw::ledger::log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32); #endif reset_buffer(); @@ -1249,7 +1289,12 @@ namespace hw { #ifdef DEBUG_HWDEVICE const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::public_key pub_x; - this->controle_device.secret_key_to_public_key(sec_x, pub_x); + hw::ledger::log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32); + bool rc = this->controle_device->secret_key_to_public_key(sec_x, pub_x); + hw::ledger::log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32); + if (!rc){ + hw::ledger::log_message("secret_key_to_public_key", "secret_key rejected"); + } #endif reset_buffer(); @@ -1298,7 +1343,10 @@ namespace hw { const crypto::public_key pub_x = pub; const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::key_image image_x; - this->controle_device.generate_key_image(pub_x, sec_x, image_x); + hw::ledger::log_hexbuffer("generate_key_image: [[IN]] pub ", pub_x.data, 32); + hw::ledger::log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data, 32); + this->controle_device->generate_key_image(pub_x, sec_x, image_x); + hw::ledger::log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data, 32); #endif reset_buffer(); @@ -1415,7 +1463,7 @@ namespace hw { return true; } - bool device_ledger::encrypt_payment_id(const crypto::public_key &public_key, const crypto::secret_key &secret_key, crypto::hash8 &payment_id) { + bool device_ledger::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { lock_device(); try { int offset =0; @@ -1425,7 +1473,7 @@ namespace hw { const crypto::public_key public_key_x = public_key; const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key); crypto::hash8 payment_id_x = payment_id; - this->controle_device.encrypt_payment_id(public_key_x, secret_key_x, payment_id_x); + this->controle_device->encrypt_payment_id(public_key_x, secret_key_x, payment_id_x); #endif reset_buffer(); @@ -1466,11 +1514,11 @@ namespace hw { return true; } - bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) { + bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, + const rct::key &amount_key, const crypto::public_key &out_eph_public_key) { lock_device(); try { - key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), real_output_index, rct::pk2rct(out_eph_public_key), amount_key)); + key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, real_output_index, rct::pk2rct(out_eph_public_key), amount_key)); unlock_device(); }catch (...) { unlock_device(); @@ -1488,7 +1536,7 @@ namespace hw { #ifdef DEBUG_HWDEVICE const rct::key AKout_x = hw::ledger::decrypt(AKout); rct::ecdhTuple unmasked_x = unmasked; - this->controle_device.ecdhEncode(AKout_x, unmasked_x); + this->controle_device->ecdhEncode(unmasked_x, AKout_x); #endif reset_buffer(); @@ -1543,7 +1591,7 @@ namespace hw { #ifdef DEBUG_HWDEVICE const rct::key AKout_x = hw::ledger::decrypt(AKout); rct::ecdhTuple masked_x = masked; - this->controle_device.ecdhDecode(AKout_x, masked_x); + this->controle_device->ecdhDecode(masked_x, AKout_x); #endif reset_buffer(); @@ -1604,7 +1652,7 @@ namespace hw { const rct::keyV hashes_x = hashes; const rct::ctkeyV outPk_x = outPk; rct::key prehash_x; - this->controle_device.mlsag_prehash(blob_x, inputs_size_x, outputs_size_x, hashes_x, outPk_x, prehash_x); + this->controle_device->mlsag_prehash(blob_x, inputs_size_x, outputs_size_x, hashes_x, outPk_x, prehash_x); if (inputs_size) { log_message("mlsag_prehash", (std::string("inputs_size not null: ") + std::to_string(inputs_size)).c_str()); } @@ -1629,6 +1677,7 @@ namespace hw { offset += 1; //type + uint8_t type = data[0]; this->buffer_send[offset] = data[0]; offset += 1; @@ -1648,25 +1697,27 @@ namespace hw { this->exchange(); //pseudoOuts - for ( i = 0; i < inputs_size; i++) { - reset_buffer(); - this->buffer_send[0] = 0x00; - this->buffer_send[1] = INS_VALIDATE; - this->buffer_send[2] = 0x01; - this->buffer_send[3] = i+2; - this->buffer_send[4] = 0x00; - offset = 5; - //options - this->buffer_send[offset] = (i==inputs_size-1)? 0x00:0x80; - offset += 1; - //pseudoOut - memmove(this->buffer_send+offset, data+data_offset,32); - offset += 32; - data_offset += 32; - - this->buffer_send[4] = offset-5; - this->length_send = offset; - this->exchange(); + if ((type == rct::RCTTypeSimple) || (type == rct::RCTTypeSimpleBulletproof)) { + for ( i = 0; i < inputs_size; i++) { + reset_buffer(); + this->buffer_send[0] = 0x00; + this->buffer_send[1] = INS_VALIDATE; + this->buffer_send[2] = 0x01; + this->buffer_send[3] = i+2; + this->buffer_send[4] = 0x00; + offset = 5; + //options + this->buffer_send[offset] = (i==inputs_size-1)? 0x00:0x80; + offset += 1; + //pseudoOut + memmove(this->buffer_send+offset, data+data_offset,32); + offset += 32; + data_offset += 32; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + } } // ====== Aout, Bout, AKout, C, v, k ====== @@ -1693,6 +1744,9 @@ namespace hw { this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ; offset += 1; if (found) { + //is_subaddress + this->buffer_send[offset] = outKeys.is_subaddress; + offset++; //Aout memmove(this->buffer_send+offset, outKeys.Aout.bytes, 32); offset+=32; @@ -1703,8 +1757,8 @@ namespace hw { memmove(this->buffer_send+offset, outKeys.AKout.bytes, 32); offset+=32; } else { - // dummy: Aout Bout AKout - offset += 32*3; + // dummy: is_subaddress Aout Bout AKout + offset += 1+32*3; } //C memmove(this->buffer_send+offset, data+C_offset,32); @@ -1905,7 +1959,7 @@ namespace hw { #ifdef DEBUG_HWDEVICE const rct::keyV long_message_x = long_message; rct::key c_x; - this->controle_device.mlsag_hash(long_message_x, c_x); + this->controle_device->mlsag_hash(long_message_x, c_x); #endif cnt = long_message.size(); @@ -1964,7 +2018,7 @@ namespace hw { const int rows_x = rows; const int dsRows_x = dsRows; rct::keyV ss_x(ss.size()); - this->controle_device.mlsag_sign(c_x, xx_x, alpha_x, rows_x, dsRows_x, ss_x); + this->controle_device->mlsag_sign(c_x, xx_x, alpha_x, rows_x, dsRows_x, ss_x); #endif for (size_t j = 0; j < dsRows; j++) { diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index ab8e0c553..e06c5f72c 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -56,12 +56,13 @@ namespace hw { public: rct::key Aout; rct::key Bout; + bool is_subaddress; size_t index; rct::key Pout; rct::key AKout; - ABPkeys(const rct::key& A, const rct::key& B, size_t index, const rct::key& P,const rct::key& AK); + ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, size_t index, const rct::key& P,const rct::key& AK); ABPkeys(const ABPkeys& keys) ; - ABPkeys() {index=0;} + ABPkeys() {index=0;is_subaddress=false;} }; class Keymap { @@ -103,8 +104,8 @@ namespace hw { unsigned int exchange(unsigned int ok=0x9000, unsigned int mask=0xFFFF); void reset_buffer(void); - #ifdef DEBUGLEDGER - Device &controle_device; + #ifdef DEBUG_HWDEVICE + device *controle_device; #endif public: @@ -141,10 +142,10 @@ namespace hw { /* SUB ADDRESS */ /* ======================================================================= */ 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 get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index, crypto::public_key &D) override; - bool get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, std::vector<crypto::public_key> &pkeys) override; - bool get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index, cryptonote::account_public_address &address) override; - bool get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index, crypto::secret_key &sub_sec) override; + crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index) 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; + cryptonote::account_public_address get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) override; + crypto::secret_key get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) override; /* ======================================================================= */ /* DERIVATION & KEY */ @@ -153,7 +154,7 @@ namespace hw { bool scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) override; bool scalarmultBase(rct::key &aG, const rct::key &a) override; bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override; - bool generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover, crypto::secret_key &rng) override; + crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override; bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override; bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override; bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override; @@ -169,13 +170,13 @@ namespace hw { bool set_signature_mode(unsigned int sig_mode) override; - bool encrypt_payment_id(const crypto::public_key &public_key, const crypto::secret_key &secret_key, crypto::hash8 &payment_id ) override; + bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override; - bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; + bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, + const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; bool 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) override; @@ -190,7 +191,7 @@ namespace hw { - #ifdef DEBUGLEDGER + #ifdef DEBUG_HWDEVICE extern crypto::secret_key viewkey; extern crypto::secret_key spendkey; #endif diff --git a/src/device/log.cpp b/src/device/log.cpp index 103b2b3ba..a2ad0f4f4 100644 --- a/src/device/log.cpp +++ b/src/device/log.cpp @@ -55,14 +55,14 @@ namespace hw { MDEBUG(msg << ": " << info); } - #ifdef DEBUGLEDGER + #ifdef DEBUG_HWDEVICE extern crypto::secret_key viewkey; extern crypto::secret_key spendkey; void decrypt(char* buf, size_t len) { - #ifdef IODUMMYCRYPT - int i; + #ifdef IODUMMYCRYPT_HWDEVICE + size_t i; if (len == 32) { //view key? for (i = 0; i<32; i++) { @@ -144,7 +144,7 @@ namespace hw { log_hexbuffer(" device", dd, len); } else { - buffer_to_str(logstr, dd, len); + buffer_to_str(logstr, 128, dd, len); log_message("ASSERT EQ OK", msg + ": "+ info + ": "+ std::string(logstr) ); } } diff --git a/src/gen_multisig/gen_multisig.cpp b/src/gen_multisig/gen_multisig.cpp index 9bcf4495c..e165b8053 100644 --- a/src/gen_multisig/gen_multisig.cpp +++ b/src/gen_multisig/gen_multisig.cpp @@ -73,11 +73,12 @@ namespace const command_line::arg_descriptor<uint32_t> arg_threshold = {"threshold", genms::tr("How many signers are required to sign a valid transaction"), 0}; const command_line::arg_descriptor<bool, false> arg_testnet = {"testnet", genms::tr("Create testnet multisig wallets"), false}; const command_line::arg_descriptor<bool, false> arg_stagenet = {"stagenet", genms::tr("Create stagenet multisig wallets"), false}; + const command_line::arg_descriptor<bool, false> arg_create_address_file = {"create-address-file", genms::tr("Create an address file for new wallets"), false}; const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""}; } -static bool generate_multisig(uint32_t threshold, uint32_t total, const std::string &basename, network_type nettype) +static bool generate_multisig(uint32_t threshold, uint32_t total, const std::string &basename, network_type nettype, bool create_address_file) { tools::msg_writer() << (boost::format(genms::tr("Generating %u %u/%u multisig wallets")) % total % threshold % total).str(); @@ -92,7 +93,7 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str std::string name = basename + "-" + std::to_string(n + 1); wallets[n].reset(new tools::wallet2(nettype)); wallets[n]->init(""); - wallets[n]->generate(name, pwd_container->password(), rct::rct2sk(rct::skGen()), false, false); + wallets[n]->generate(name, pwd_container->password(), rct::rct2sk(rct::skGen()), false, false, create_address_file); } // gather the keys @@ -171,6 +172,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_participants); command_line::add_arg(desc_params, arg_testnet); command_line::add_arg(desc_params, arg_stagenet); + command_line::add_arg(desc_params, arg_create_address_file); const auto vm = wallet_args::main( argc, argv, @@ -241,7 +243,8 @@ int main(int argc, char* argv[]) tools::fail_msg_writer() << genms::tr("Error: unsupported scheme: only N/N and N-1/N are supported"); return 1; } - if (!generate_multisig(threshold, total, basename, testnet ? TESTNET : stagenet ? STAGENET : MAINNET)) + bool create_address_file = command_line::get_arg(*vm, arg_create_address_file); + if (!generate_multisig(threshold, total, basename, testnet ? TESTNET : stagenet ? STAGENET : MAINNET, create_address_file)) return 1; return 0; diff --git a/src/multisig/multisig.cpp b/src/multisig/multisig.cpp index 91042d58a..d85c47772 100644 --- a/src/multisig/multisig.cpp +++ b/src/multisig/multisig.cpp @@ -33,7 +33,6 @@ #include "cryptonote_basic/account.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "multisig.h" -#include "device/device_default.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "multisig" diff --git a/src/ringct/CMakeLists.txt b/src/ringct/CMakeLists.txt index 2d3ea5cf4..c8dcdca26 100644 --- a/src/ringct/CMakeLists.txt +++ b/src/ringct/CMakeLists.txt @@ -26,21 +26,39 @@ # 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. -set(ringct_sources +set(ringct_basic_sources rctOps.cpp - rctOps_device.cpp - rctSigs.cpp rctTypes.cpp rctCryptoOps.c bulletproofs.cc) +set(ringct_basic_private_headers + rctOps.h + rctTypes.h + bulletproofs.h) + +monero_private_headers(ringct_basic + ${crypto_private_headers}) +monero_add_library(ringct_basic + ${ringct_basic_sources} + ${ringct_basic_private_headers}) +target_link_libraries(ringct_basic + PUBLIC + common + cncrypto + PRIVATE + ${OPENSSL_LIBRARIES} + ${EXTRA_LIBRARIES}) + +set(ringct_sources + rctSigs.cpp +) + set(ringct_headers) set(ringct_private_headers - rctOps.h rctSigs.h - rctTypes.h - bulletproofs.h) +) monero_private_headers(ringct ${crypto_private_headers}) diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index c9f2e7a43..3f8f6955c 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -112,14 +112,10 @@ namespace rct { //does a * G where a is a scalar and G is the curve basepoint void scalarmultBase(key & aG, const key &a); - void scalarmultBase(key & aG, const key &a, hw::device &hwdev); key scalarmultBase(const key & a); - key scalarmultBase(const key & a, hw::device &hwdev); //does a * P where a is a scalar and P is an arbitrary point void scalarmultKey(key &aP, const key &P, const key &a); - void scalarmultKey(key &aP, const key &P, const key &a, hw::device &hwdev); key scalarmultKey(const key &P, const key &a); - key scalarmultKey(const key &P, const key &a, hw::device &hwdev); //Computes aH where H= toPoint(cn_fast_hash(G)), G the basepoint key scalarmultH(const key & a); @@ -178,8 +174,6 @@ namespace rct { //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec); - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, hw::device &hwdev); void ecdhDecode(ecdhTuple & masked, const key & sharedSec); - void ecdhDecode(ecdhTuple & masked, const key & sharedSec, hw::device &hwdev); } #endif /* RCTOPS_H */ diff --git a/src/ringct/rctOps_device.cpp b/src/ringct/rctOps_device.cpp deleted file mode 100644 index fbfe8e9cf..000000000 --- a/src/ringct/rctOps_device.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// 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 "misc_log_ex.h" -#include "rctOps.h" -#include "device/device.hpp" -using namespace crypto; -using namespace std; - - -namespace rct -{ - void scalarmultKey(key & aP, const key &P, const key &a, hw::device &hwdev) { - hwdev.scalarmultKey(aP, P, a); - } - - key scalarmultKey(const key & P, const key & a, hw::device &hwdev) { - key aP; - hwdev.scalarmultKey(aP, P, a); - return aP; - } - - void scalarmultBase(key &aG, const key &a, hw::device &hwdev) { - hwdev.scalarmultBase(aG, a); - } - - key scalarmultBase(const key & a, hw::device &hwdev) { - key aG; - hwdev.scalarmultBase(aG, a); - return aG; - } - - void ecdhDecode(ecdhTuple & masked, const key & sharedSec, hw::device &hwdev) { - hwdev.ecdhDecode(masked, sharedSec); - } - - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, hw::device &hwdev) { - hwdev.ecdhEncode(unmasked, sharedSec); - } -}
\ No newline at end of file diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index ae0ee21c8..4ecf62cec 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -35,9 +35,6 @@ #include "rctSigs.h" #include "bulletproofs.h" #include "cryptonote_basic/cryptonote_format_utils.h" -#include "cryptonote_basic/cryptonote_basic.h" -#include "cryptonote_basic/subaddress_index.h" -#include "device/device.hpp" using namespace crypto; using namespace std; @@ -118,19 +115,32 @@ namespace rct { } //see above. - bool verifyBorromean(const boroSig &bb, const key64 P1, const key64 P2) { + bool verifyBorromean(const boroSig &bb, const ge_p3 P1[64], const ge_p3 P2[64]) { key64 Lv1; key chash, LL; int ii = 0; + ge_p2 p2; for (ii = 0 ; ii < 64 ; ii++) { - addKeys2(LL, bb.s0[ii], bb.ee, P1[ii]); + // equivalent of: addKeys2(LL, bb.s0[ii], bb.ee, P1[ii]); + ge_double_scalarmult_base_vartime(&p2, bb.ee.bytes, &P1[ii], bb.s0[ii].bytes); + ge_tobytes(LL.bytes, &p2); chash = hash_to_scalar(LL); - addKeys2(Lv1[ii], bb.s1[ii], chash, P2[ii]); + // equivalent of: addKeys2(Lv1[ii], bb.s1[ii], chash, P2[ii]); + ge_double_scalarmult_base_vartime(&p2, chash.bytes, &P2[ii], bb.s1[ii].bytes); + ge_tobytes(Lv1[ii].bytes, &p2); } key eeComputed = hash_to_scalar(Lv1); //hash function fine return equalKeys(eeComputed, bb.ee); } - + bool verifyBorromean(const boroSig &bb, const key64 P1, const key64 P2) { + ge_p3 P1_p3[64], P2_p3[64]; + for (size_t i = 0 ; i < 64 ; ++i) { + CHECK_AND_ASSERT_MES(ge_frombytes_vartime(&P1_p3[i], P1[i].bytes) == 0, false, "point conv failed"); + CHECK_AND_ASSERT_MES(ge_frombytes_vartime(&P2_p3[i], P2[i].bytes) == 0, false, "point conv failed"); + } + return verifyBorromean(bb, P1_p3, P2_p3); + } + //Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures) //This is a just slghtly more efficient version than the ones described below //(will be explained in more detail in Ring Multisig paper @@ -336,16 +346,30 @@ namespace rct { try { PERF_TIMER(verRange); - key64 CiH; + ge_p3 CiH[64], asCi[64]; int i = 0; - key Ctmp = identity(); + ge_p3 Ctmp_p3 = ge_p3_identity; for (i = 0; i < 64; i++) { - subKeys(CiH[i], as.Ci[i], H2[i]); - addKeys(Ctmp, Ctmp, as.Ci[i]); + // faster equivalent of: + // subKeys(CiH[i], as.Ci[i], H2[i]); + // addKeys(Ctmp, Ctmp, as.Ci[i]); + ge_cached cached; + ge_p3 p3; + ge_p1p1 p1; + CHECK_AND_ASSERT_MES(ge_frombytes_vartime(&p3, H2[i].bytes) == 0, false, "point conv failed"); + ge_p3_to_cached(&cached, &p3); + CHECK_AND_ASSERT_MES(ge_frombytes_vartime(&asCi[i], as.Ci[i].bytes) == 0, false, "point conv failed"); + ge_sub(&p1, &asCi[i], &cached); + ge_p3_to_cached(&cached, &asCi[i]); + ge_p1p1_to_p3(&CiH[i], &p1); + ge_add(&p1, &Ctmp_p3, &cached); + ge_p1p1_to_p3(&Ctmp_p3, &p1); } + key Ctmp; + ge_p3_tobytes(Ctmp.bytes, &Ctmp_p3); if (!equalKeys(C, Ctmp)) return false; - if (!verifyBorromean(as.asig, as.Ci, CiH)) + if (!verifyBorromean(as.asig, asCi, CiH)) return false; return true; } @@ -669,7 +693,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(amounts[i]); - ecdhEncode(rv.ecdhInfo[i], amount_keys[i], hwdev); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); } //set txn fee @@ -750,7 +774,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(outamounts[i]); - ecdhEncode(rv.ecdhInfo[i], amount_keys[i],hwdev); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); } //set txn fee @@ -1007,7 +1031,7 @@ namespace rct { //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - ecdhDecode(ecdh_info, sk, hwdev); + hwdev.ecdhDecode(ecdh_info, sk); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; @@ -1035,7 +1059,7 @@ namespace rct { //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - ecdhDecode(ecdh_info, sk, hwdev); + hwdev.ecdhDecode(ecdh_info, sk); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index 7485938ee..b8aab0f11 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -50,8 +50,6 @@ extern "C" { #include "rctTypes.h" #include "rctOps.h" -#include "cryptonote_basic/cryptonote_basic.h" -#include "device/device_declare.hpp" //Define this flag when debugging to get additional info on the console #ifdef DBG @@ -60,6 +58,9 @@ extern "C" { #define DP(x) #endif +namespace hw { + class device; +} namespace rct { diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 6491955c6..3668df7b9 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -62,7 +62,6 @@ #include "ringct/rctSigs.h" #include "multisig/multisig.h" #include "wallet/wallet_args.h" -#include "device/device.hpp" #include <stdexcept> #ifdef WIN32 @@ -134,6 +133,7 @@ namespace const command_line::arg_descriptor<bool> arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false}; const command_line::arg_descriptor<uint64_t> arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0}; const command_line::arg_descriptor<bool> arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the monero network"), false}; + const command_line::arg_descriptor<bool> arg_create_address_file = {"create-address-file", sw::tr("Create an address file for new wallets"), false}; const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""}; @@ -2848,10 +2848,12 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, m_wallet->set_seed_language(mnemonic_language); + bool create_address_file = command_line::get_arg(vm, arg_create_address_file); + crypto::secret_key recovery_val; try { - recovery_val = m_wallet->generate(m_wallet_file, std::move(rc.second).password(), recovery_key, recover, two_random); + recovery_val = m_wallet->generate(m_wallet_file, std::move(rc.second).password(), recovery_key, recover, two_random, create_address_file); message_writer(console_color_white, true) << tr("Generated new wallet: ") << m_wallet->get_account().get_public_address_str(m_wallet->nettype()); std::cout << tr("View key: ") << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL; @@ -2900,15 +2902,17 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, if (m_restore_height) m_wallet->set_refresh_from_block_height(m_restore_height); + bool create_address_file = command_line::get_arg(vm, arg_create_address_file); + try { if (spendkey) { - m_wallet->generate(m_wallet_file, std::move(rc.second).password(), address, *spendkey, viewkey); + m_wallet->generate(m_wallet_file, std::move(rc.second).password(), address, *spendkey, viewkey, create_address_file); } else { - m_wallet->generate(m_wallet_file, std::move(rc.second).password(), address, viewkey); + m_wallet->generate(m_wallet_file, std::move(rc.second).password(), address, viewkey, create_address_file); } message_writer(console_color_white, true) << tr("Generated new wallet: ") << m_wallet->get_account().get_public_address_str(m_wallet->nettype()); @@ -2971,9 +2975,11 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, m_wallet->set_seed_language(mnemonic_language); + bool create_address_file = command_line::get_arg(vm, arg_create_address_file); + try { - m_wallet->generate(m_wallet_file, std::move(rc.second).password(), multisig_keys); + m_wallet->generate(m_wallet_file, std::move(rc.second).password(), multisig_keys, create_address_file); bool ready; uint32_t threshold, total; if (!m_wallet->multisig(&ready, &threshold, &total) || !ready) @@ -3143,7 +3149,17 @@ bool simple_wallet::save_watch_only(const std::vector<std::string> &args/* = std return true; } - m_wallet->write_watch_only_wallet(m_wallet_file, pwd_container->password()); + try + { + std::string new_keys_filename; + m_wallet->write_watch_only_wallet(m_wallet_file, pwd_container->password(), new_keys_filename); + success_msg_writer() << tr("Watch only wallet saved as: ") << new_keys_filename; + } + catch (const std::exception &e) + { + fail_msg_writer() << tr("Failed to save watch only wallet: ") << e.what(); + return true; + } return true; } @@ -6978,6 +6994,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version); command_line::add_arg(desc_params, arg_restore_height); command_line::add_arg(desc_params, arg_do_not_relay); + command_line::add_arg(desc_params, arg_create_address_file); po::positional_options_description positional_options; positional_options.add(arg_command.name, -1); diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index c6d0bd9da..d82e1dace 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -111,7 +111,9 @@ if (BUILD_GUI_DEPS) mnemonics common cncrypto + device ringct + ringct_basic checkpoints version) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index ff0d2fdbd..fb9e8b28b 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -306,8 +306,20 @@ void Wallet::init(const char *argv0, const char *default_log_base_name) { mlog_configure(mlog_get_default_log_path(default_log_base_name), true); } -void Wallet::debug(const std::string &str) { - MDEBUG(str); +void Wallet::debug(const std::string &category, const std::string &str) { + MCDEBUG(category.empty() ? MONERO_DEFAULT_LOG_CATEGORY : category.c_str(), str); +} + +void Wallet::info(const std::string &category, const std::string &str) { + MCINFO(category.empty() ? MONERO_DEFAULT_LOG_CATEGORY : category.c_str(), str); +} + +void Wallet::warning(const std::string &category, const std::string &str) { + MCWARNING(category.empty() ? MONERO_DEFAULT_LOG_CATEGORY : category.c_str(), str); +} + +void Wallet::error(const std::string &category, const std::string &str) { + MCERROR(category.empty() ? MONERO_DEFAULT_LOG_CATEGORY : category.c_str(), str); } ///////////////////////// WalletImpl implementation //////////////////////// diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 36b3b9c9b..87c1cccfa 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -556,7 +556,10 @@ struct Wallet static uint64_t maximumAllowedAmount(); // Easylogger wrapper static void init(const char *argv0, const char *default_log_base_name); - static void debug(const std::string &str); + static void debug(const std::string &category, const std::string &str); + static void info(const std::string &category, const std::string &str); + static void warning(const std::string &category, const std::string &str); + static void error(const std::string &category, const std::string &str); /** * @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds) @@ -774,7 +777,7 @@ struct WalletManager * \param nettype Network type * \return Wallet instance (Wallet::status() needs to be called to check if created successfully) */ - virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, NetworkType nettype = MAINNET) = 0; + virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, NetworkType nettype) = 0; Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, bool testnet = false) // deprecated { return createWallet(path, password, language, testnet ? TESTNET : MAINNET); @@ -787,7 +790,7 @@ struct WalletManager * \param nettype Network type * \return Wallet instance (Wallet::status() needs to be called to check if opened successfully) */ - virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype = MAINNET) = 0; + virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype) = 0; Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) // deprecated { return openWallet(path, password, testnet ? TESTNET : MAINNET); @@ -819,7 +822,7 @@ struct WalletManager * \param restoreHeight restore from start height * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) */ - virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype = MAINNET, uint64_t restoreHeight = 0) = 0; + virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight = 0) = 0; Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, bool testnet = false, uint64_t restoreHeight = 0) // deprecated { return recoveryWallet(path, mnemonic, testnet ? TESTNET : MAINNET, restoreHeight); diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index b03332f40..80f5780b5 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -37,7 +37,6 @@ #include "common/updates.h" #include "version.h" #include "net/http_client.h" -#include "device/device.hpp" #include <boost/filesystem.hpp> #include <boost/regex.hpp> diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d845dd896..1702eb129 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -66,7 +66,6 @@ using namespace epee; #include "memwipe.h" #include "common/base58.h" #include "ringct/rctSigs.h" -#include "device/device.hpp" extern "C" { @@ -318,10 +317,13 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, address, std::string, String, false, std::string()); + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, create_address_file, int, Int, false, false); + bool create_address_file = field_create_address_file; + // compatibility checks if (!field_seed_found && !field_viewkey_found && !field_spendkey_found) { - THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified")); + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("At least one of either an Electrum-style word list, private view key, or private spend key must be specified")); } if (field_seed_found && (field_viewkey_found || field_spendkey_found)) { @@ -372,11 +374,11 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, { if (!field_seed.empty()) { - wallet->generate(field_filename, field_password, recovery_key, recover, false); + wallet->generate(field_filename, field_password, recovery_key, recover, false, create_address_file); } else if (field_viewkey.empty() && !field_spendkey.empty()) { - wallet->generate(field_filename, field_password, spendkey, recover, false); + wallet->generate(field_filename, field_password, spendkey, recover, false, create_address_file); } else { @@ -402,14 +404,14 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, { THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Address must be specified in order to create watch-only wallet")); } - wallet->generate(field_filename, field_password, address, viewkey); + wallet->generate(field_filename, field_password, address, viewkey, create_address_file); } else { if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) { THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } - wallet->generate(field_filename, field_password, address, spendkey, viewkey); + wallet->generate(field_filename, field_password, address, spendkey, viewkey, create_address_file); } } } @@ -558,7 +560,7 @@ crypto::hash8 get_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::de MWARNING("Encrypted payment id found, but no destinations public key, cannot decrypt"); return crypto::null_hash8; } - decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key, hwdev); + hwdev.decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key); } } return payment_id8; @@ -582,6 +584,14 @@ tools::wallet2::tx_construction_data get_construction_data_with_decrypted_short_ return construction_data; } +uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra) +{ + static constexpr uint32_t uint32_max = std::numeric_limits<uint32_t>::max(); + if (idx > uint32_max - extra) + return uint32_max; + return idx + extra; +} + //----------------------------------------------------------------- } //namespace @@ -829,18 +839,14 @@ void wallet2::set_seed_language(const std::string &language) //---------------------------------------------------------------------------------------------------- cryptonote::account_public_address wallet2::get_subaddress(const cryptonote::subaddress_index& index) const { - cryptonote::account_public_address address; hw::device &hwdev = m_account.get_device(); - hwdev.get_subaddress(m_account.get_keys(), index,address); - return address; + return hwdev.get_subaddress(m_account.get_keys(), index); } //---------------------------------------------------------------------------------------------------- crypto::public_key wallet2::get_subaddress_spend_public_key(const cryptonote::subaddress_index& index) const { - crypto::public_key D ; hw::device &hwdev = m_account.get_device(); - hwdev.get_subaddress_spend_public_key(m_account.get_keys(), index, D); - return D; + return hwdev.get_subaddress_spend_public_key(m_account.get_keys(), index); } //---------------------------------------------------------------------------------------------------- std::string wallet2::get_subaddress_as_str(const cryptonote::subaddress_index& index) const @@ -876,10 +882,11 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index) { // add new accounts cryptonote::subaddress_index index2; - for (index2.major = m_subaddress_labels.size(); index2.major < index.major + m_subaddress_lookahead_major; ++index2.major) + const uint32_t major_end = get_subaddress_clamped_sum(index.major, m_subaddress_lookahead_major); + for (index2.major = m_subaddress_labels.size(); index2.major < major_end; ++index2.major) { - const uint32_t end = (index2.major == index.major ? index.minor : 0) + m_subaddress_lookahead_minor; - const std::vector<crypto::public_key> pkeys = cryptonote::get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, 0, end, hwdev); + const uint32_t end = get_subaddress_clamped_sum((index2.major == index.major ? index.minor : 0), m_subaddress_lookahead_minor); + const std::vector<crypto::public_key> pkeys = hwdev.get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, 0, end); for (index2.minor = 0; index2.minor < end; ++index2.minor) { const crypto::public_key &D = pkeys[index2.minor]; @@ -892,10 +899,10 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index) else if (m_subaddress_labels[index.major].size() <= index.minor) { // add new subaddresses - const uint32_t end = index.minor + m_subaddress_lookahead_minor; + const uint32_t end = get_subaddress_clamped_sum(index.minor, m_subaddress_lookahead_minor); const uint32_t begin = m_subaddress_labels[index.major].size(); cryptonote::subaddress_index index2 = {index.major, begin}; - const std::vector<crypto::public_key> pkeys = cryptonote::get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, index2.minor, end, hwdev); + const std::vector<crypto::public_key> pkeys = hwdev.get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, index2.minor, end); for (; index2.minor < end; ++index2.minor) { const crypto::public_key &D = pkeys[index2.minor - begin]; @@ -924,6 +931,8 @@ void wallet2::set_subaddress_label(const cryptonote::subaddress_index& index, co //---------------------------------------------------------------------------------------------------- void wallet2::set_subaddress_lookahead(size_t major, size_t minor) { + THROW_WALLET_EXCEPTION_IF(major > 0xffffffff, error::wallet_internal_error, "Subaddress major lookahead is too large"); + THROW_WALLET_EXCEPTION_IF(minor > 0xffffffff, error::wallet_internal_error, "Subaddress minor lookahead is too large"); m_subaddress_lookahead_major = major; m_subaddress_lookahead_minor = minor; } @@ -975,7 +984,7 @@ void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivatio static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &derivation, unsigned int i, rct::key & mask, hw::device &hwdev) { crypto::secret_key scalar1; - crypto::derivation_to_scalar(derivation, i, scalar1, hwdev); + hwdev.derivation_to_scalar(derivation, i, scalar1); try { switch (rv.type) @@ -1068,7 +1077,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote const cryptonote::account_keys& keys = m_account.get_keys(); hw::device &hwdev = m_account.get_device(); crypto::key_derivation derivation; - if (!generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation, hwdev)) + if (!hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation)) { MWARNING("Failed to generate key derivation from tx pubkey, skipping"); static_assert(sizeof(derivation) == sizeof(rct::key), "Mismatched sizes of key_derivation and rct::key"); @@ -1081,7 +1090,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i) { additional_derivations.push_back({}); - if (!generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back(),hwdev)) + if (!hwdev.generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back())) { MWARNING("Failed to generate key derivation from tx pubkey, skipping"); additional_derivations.pop_back(); @@ -1373,7 +1382,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote LOG_PRINT_L2("Found encrypted payment ID: " << payment_id8); if (tx_pub_key != null_pkey) { - if (!decrypt_payment_id(payment_id8, tx_pub_key, m_account.get_keys().m_view_secret_key, m_account.get_device())) + if (!m_account.get_device().decrypt_payment_id(payment_id8, tx_pub_key, m_account.get_keys().m_view_secret_key)) { LOG_PRINT_L0("Failed to decrypt payment ID: " << payment_id8); } @@ -2740,7 +2749,7 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip * \param multisig_data The multisig restore info and keys */ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, - const std::string& multisig_data) + const std::string& multisig_data, bool create_address_file) { clear(); prepare_file_names(wallet_); @@ -2812,8 +2821,11 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); - if(!r) MERROR("String with address text not saved"); + if (m_nettype != MAINNET || create_address_file) + { + r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); + if(!r) MERROR("String with address text not saved"); + } } cryptonote::block b; @@ -2835,7 +2847,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& * \return The secret key of the generated wallet */ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, - const crypto::secret_key& recovery_param, bool recover, bool two_random) + const crypto::secret_key& recovery_param, bool recover, bool two_random, bool create_address_file) { clear(); prepare_file_names(wallet_); @@ -2866,8 +2878,11 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); - if(!r) MERROR("String with address text not saved"); + if (m_nettype != MAINNET || create_address_file) + { + r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); + if(!r) MERROR("String with address text not saved"); + } } cryptonote::block b; @@ -2931,7 +2946,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip */ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, - const crypto::secret_key& viewkey) + const crypto::secret_key& viewkey, bool create_address_file) { clear(); prepare_file_names(wallet_); @@ -2956,8 +2971,11 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& bool r = store_keys(m_keys_file, password, true); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); - if(!r) MERROR("String with address text not saved"); + if (m_nettype != MAINNET || create_address_file) + { + r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); + if(!r) MERROR("String with address text not saved"); + } } cryptonote::block b; @@ -2978,7 +2996,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& */ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, - const crypto::secret_key& spendkey, const crypto::secret_key& viewkey) + const crypto::secret_key& spendkey, const crypto::secret_key& viewkey, bool create_address_file) { clear(); prepare_file_names(wallet_); @@ -3003,8 +3021,11 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); - if(!r) MERROR("String with address text not saved"); + if (m_nettype != MAINNET || create_address_file) + { + r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); + if(!r) MERROR("String with address text not saved"); + } } cryptonote::block b; @@ -3136,8 +3157,11 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password, bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); - if(!r) MERROR("String with address text not saved"); + if (boost::filesystem::exists(m_wallet_file + ".address.txt")) + { + r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); + if(!r) MERROR("String with address text not saved"); + } } cryptonote::block b; @@ -3236,8 +3260,11 @@ bool wallet2::finalize_multisig(const epee::wipeable_string &password, std::unor bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); - if(!r) MERROR("String with address text not saved"); + if (boost::filesystem::exists(m_wallet_file + ".address.txt")) + { + r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype)); + if(!r) MERROR("String with address text not saved"); + } } m_subaddresses.clear(); @@ -3415,15 +3442,15 @@ void wallet2::rewrite(const std::string& wallet_name, const epee::wipeable_strin * \param wallet_name Base name of wallet file * \param password Password for wallet file */ -void wallet2::write_watch_only_wallet(const std::string& wallet_name, const epee::wipeable_string& password) +void wallet2::write_watch_only_wallet(const std::string& wallet_name, const epee::wipeable_string& password, std::string &new_keys_filename) { prepare_file_names(wallet_name); boost::system::error_code ignored_ec; - std::string filename = m_keys_file + "-watchonly"; - bool watch_only_keys_file_exists = boost::filesystem::exists(filename, ignored_ec); - THROW_WALLET_EXCEPTION_IF(watch_only_keys_file_exists, error::file_save_error, filename); - bool r = store_keys(filename, password, true); - THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, filename); + new_keys_filename = m_wallet_file + "-watchonly.keys"; + bool watch_only_keys_file_exists = boost::filesystem::exists(new_keys_filename, ignored_ec); + THROW_WALLET_EXCEPTION_IF(watch_only_keys_file_exists, error::file_save_error, new_keys_filename); + bool r = store_keys(new_keys_filename, password, true); + THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, new_keys_filename); } //---------------------------------------------------------------------------------------------------- void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists) @@ -3760,10 +3787,13 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas prepare_file_names(path); bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - // save address to the new file - const std::string address_file = m_wallet_file + ".address.txt"; - r = file_io_utils::save_string_to_file(address_file, m_account.get_public_address_str(m_nettype)); - THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file); + if (boost::filesystem::exists(old_address_file)) + { + // save address to the new file + const std::string address_file = m_wallet_file + ".address.txt"; + r = file_io_utils::save_string_to_file(address_file, m_account.get_public_address_str(m_nettype)); + THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file); + } // remove old wallet file r = boost::filesystem::remove(old_file); if (!r) { @@ -4316,7 +4346,7 @@ crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const MWARNING("Encrypted payment id found, but no destinations public key, cannot decrypt"); return crypto::null_hash; } - if (decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key, m_account.get_device())) + if (m_account.get_device().decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key)) { memcpy(payment_id.data, payment_id8.data, 8); } @@ -6677,6 +6707,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp cryptonote::transaction tx; pending_tx ptx; size_t bytes; + std::vector<std::vector<tools::wallet2::get_outs_entry>> outs; void add(const account_public_address &addr, bool is_subaddress, uint64_t amount, unsigned int original_output_index, bool merge_destinations) { if (merge_destinations) @@ -7066,40 +7097,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp LOG_PRINT_L2("Made a final " << get_size_string(txBlob) << " tx, with " << print_money(test_ptx.fee) << " fee and " << print_money(test_ptx.change_dts.amount) << " change"); - if ((!dsts.empty()) || - (dsts.empty() && !(adding_fee || !preferred_inputs.empty() || should_pick_a_second_output(use_rct, txes.back().selected_transfers.size(), *unused_transfers_indices, *unused_dust_indices)) ) - ) { - hwdev.set_signature_mode(hw::device::SIGNATURE_REAL); - if (use_rct) { - transfer_selected_rct(tx.dsts, /* NOMOD std::vector<cryptonote::tx_destination_entry> dsts,*/ - tx.selected_transfers, /* const std::list<size_t> selected_transfers */ - fake_outs_count, /* CONST size_t fake_outputs_count, */ - outs, /* MOD std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, */ - unlock_time, /* CONST uint64_t unlock_time, */ - needed_fee, /* CONST uint64_t fee, */ - extra, /* const std::vector<uint8_t>& extra, */ - test_tx, /* OUT cryptonote::transaction& tx, */ - test_ptx, /* OUT cryptonote::transaction& tx, */ - bulletproof); - } else { - transfer_selected(tx.dsts, - tx.selected_transfers, - fake_outs_count, - outs, - unlock_time, - needed_fee, - extra, - detail::digit_split_strategy, - tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), - test_tx, - test_ptx); - } - hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE); - } - tx.tx = test_tx; tx.ptx = test_ptx; tx.bytes = txBlob.size(); + tx.outs = outs; accumulated_fee += test_ptx.fee; accumulated_change += test_ptx.change_dts.amount; adding_fee = false; @@ -7139,6 +7140,42 @@ skip_tx: LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) << " total fee, " << print_money(accumulated_change) << " total change"); + hwdev.set_signature_mode(hw::device::SIGNATURE_REAL); + for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) + { + TX &tx = *i; + cryptonote::transaction test_tx; + pending_tx test_ptx; + if (use_rct) { + transfer_selected_rct(tx.dsts, /* NOMOD std::vector<cryptonote::tx_destination_entry> dsts,*/ + tx.selected_transfers, /* const std::list<size_t> selected_transfers */ + fake_outs_count, /* CONST size_t fake_outputs_count, */ + tx.outs, /* MOD std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, */ + unlock_time, /* CONST uint64_t unlock_time, */ + needed_fee, /* CONST uint64_t fee, */ + extra, /* const std::vector<uint8_t>& extra, */ + test_tx, /* OUT cryptonote::transaction& tx, */ + test_ptx, /* OUT cryptonote::transaction& tx, */ + bulletproof); + } else { + transfer_selected(tx.dsts, + tx.selected_transfers, + fake_outs_count, + tx.outs, + unlock_time, + needed_fee, + extra, + detail::digit_split_strategy, + tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), + test_tx, + test_ptx); + } + auto txBlob = t_serializable_object_to_blob(test_ptx.tx); + tx.tx = test_tx; + tx.ptx = test_ptx; + tx.bytes = txBlob.size(); + } + std::vector<wallet2::pending_tx> ptx_vector; for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) { @@ -7241,6 +7278,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton cryptonote::transaction tx; pending_tx ptx; size_t bytes; + std::vector<std::vector<get_outs_entry>> outs; }; std::vector<TX> txes; uint64_t needed_fee, available_for_fee = 0; @@ -7332,24 +7370,13 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton " fee and " << print_money(test_ptx.change_dts.amount) << " change"); } while (needed_fee > test_ptx.fee); - if (!unused_transfers_indices.empty() || !unused_dust_indices.empty()) { - hwdev.set_signature_mode(hw::device::SIGNATURE_REAL); - if (use_rct) { - transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, - test_tx, test_ptx, bulletproof); - } else { - transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, - detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx); - } - hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE); - } - LOG_PRINT_L2("Made a final " << get_size_string(txBlob) << " tx, with " << print_money(test_ptx.fee) << " fee and " << print_money(test_ptx.change_dts.amount) << " change"); tx.tx = test_tx; tx.ptx = test_ptx; tx.bytes = txBlob.size(); + tx.outs = outs; accumulated_fee += test_ptx.fee; accumulated_change += test_ptx.change_dts.amount; if (!unused_transfers_indices.empty() || !unused_dust_indices.empty()) @@ -7362,6 +7389,25 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) << " total fee, " << print_money(accumulated_change) << " total change"); + + hwdev.set_signature_mode(hw::device::SIGNATURE_REAL); + for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) + { + TX &tx = *i; + cryptonote::transaction test_tx; + pending_tx test_ptx; + if (use_rct) { + transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, needed_fee, extra, + test_tx, test_ptx, bulletproof); + } else { + transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, needed_fee, extra, + detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx); + } + auto txBlob = t_serializable_object_to_blob(test_ptx.tx); + tx.tx = test_tx; + tx.ptx = test_ptx; + tx.bytes = txBlob.size(); + } std::vector<wallet2::pending_tx> ptx_vector; for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) @@ -7808,13 +7854,13 @@ bool wallet2::check_spend_proof(const crypto::hash &txid, const std::string &mes void wallet2::check_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) { crypto::key_derivation derivation; - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(address.m_view_public_key, tx_key, derivation, m_account.get_device()), error::wallet_internal_error, + THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(address.m_view_public_key, tx_key, derivation), error::wallet_internal_error, "Failed to generate key derivation from supplied parameters"); std::vector<crypto::key_derivation> additional_derivations; additional_derivations.resize(additional_tx_keys.size()); for (size_t i = 0; i < additional_tx_keys.size(); ++i) - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(address.m_view_public_key, additional_tx_keys[i], additional_derivations[i], m_account.get_device()), error::wallet_internal_error, + THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(address.m_view_public_key, additional_tx_keys[i], additional_derivations[i]), error::wallet_internal_error, "Failed to generate key derivation from supplied parameters"); check_tx_key_helper(txid, derivation, additional_derivations, address, received, in_pool, confirmations); @@ -7856,13 +7902,13 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de continue; crypto::public_key derived_out_key; - bool r = derive_public_key(derivation, n, address.m_spend_public_key, derived_out_key, hwdev); + bool r = hwdev.derive_public_key(derivation, n, address.m_spend_public_key, derived_out_key); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key"); bool found = out_key->key == derived_out_key; crypto::key_derivation found_derivation = derivation; if (!found && !additional_derivations.empty()) { - r = derive_public_key(additional_derivations[n], n, address.m_spend_public_key, derived_out_key,hwdev); + r = hwdev.derive_public_key(additional_derivations[n], n, address.m_spend_public_key, derived_out_key); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key"); found = out_key->key == derived_out_key; found_derivation = additional_derivations[n]; @@ -7878,9 +7924,9 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de else { crypto::secret_key scalar1; - crypto::derivation_to_scalar(found_derivation, n, scalar1, hwdev); + hwdev.derivation_to_scalar(found_derivation, n, scalar1); rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n]; - rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), hwdev); + hwdev.ecdhDecode(ecdh_info, rct::sk2rct(scalar1)); const rct::key C = tx.rct_signatures.outPk[n].mask; rct::key Ctmp; rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H); @@ -8250,7 +8296,7 @@ std::string wallet2::get_reserve_proof(const boost::optional<std::pair<uint32_t, crypto::secret_key subaddr_spend_skey = m_account.get_keys().m_spend_secret_key; if (!index.is_zero()) { - crypto::secret_key m = cryptonote::get_subaddress_secret_key(m_account.get_keys().m_view_secret_key, index); + crypto::secret_key m = m_account.get_device().get_subaddress_secret_key(m_account.get_keys().m_view_secret_key, index); crypto::secret_key tmp = subaddr_spend_skey; sc_add((unsigned char*)&subaddr_spend_skey, (unsigned char*)&m, (unsigned char*)&tmp); } @@ -8615,14 +8661,14 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i) { additional_derivations.push_back({}); - bool r = generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back(), hwdev); + bool r = hwdev.generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back()); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation"); } while (find_tx_extra_field_by_type(tx_extra_fields, pub_key_field, pk_index++)) { const crypto::public_key tx_pub_key = pub_key_field.pub_key; crypto::key_derivation derivation; - bool r = generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation, hwdev); + bool r = hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation"); for (size_t i = 0; i < td.m_tx.vout.size(); ++i) @@ -8911,14 +8957,14 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag const cryptonote::account_keys& keys = m_account.get_keys(); const crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(spent_tx); crypto::key_derivation derivation; - bool r = generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation, hwdev); + bool r = hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation"); const std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(spent_tx); std::vector<crypto::key_derivation> additional_derivations; for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i) { additional_derivations.push_back({}); - r = generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back(), hwdev); + r = hwdev.generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back()); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation"); } size_t output_index = 0; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 57a61cb9d..9accc65ca 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -449,44 +449,48 @@ namespace tools /*! * \brief Generates a wallet or restores one. - * \param wallet_ Name of wallet file - * \param password Password of wallet file - * \param multisig_data The multisig restore info and keys + * \param wallet_ Name of wallet file + * \param password Password of wallet file + * \param multisig_data The multisig restore info and keys + * \param create_address_file Whether to create an address file */ void generate(const std::string& wallet_, const epee::wipeable_string& password, - const std::string& multisig_data); + const std::string& multisig_data, bool create_address_file = false); /*! * \brief Generates a wallet or restores one. - * \param wallet_ Name of wallet file - * \param password Password of wallet file - * \param recovery_param If it is a restore, the recovery key - * \param recover Whether it is a restore - * \param two_random Whether it is a non-deterministic wallet - * \return The secret key of the generated wallet + * \param wallet_ Name of wallet file + * \param password Password of wallet file + * \param recovery_param If it is a restore, the recovery key + * \param recover Whether it is a restore + * \param two_random Whether it is a non-deterministic wallet + * \param create_address_file Whether to create an address file + * \return The secret key of the generated wallet */ crypto::secret_key generate(const std::string& wallet, const epee::wipeable_string& password, const crypto::secret_key& recovery_param = crypto::secret_key(), bool recover = false, - bool two_random = false); + bool two_random = false, bool create_address_file = false); /*! * \brief Creates a wallet from a public address and a spend/view secret key pair. - * \param wallet_ Name of wallet file - * \param password Password of wallet file - * \param viewkey view secret key - * \param spendkey spend secret key + * \param wallet_ Name of wallet file + * \param password Password of wallet file + * \param viewkey view secret key + * \param spendkey spend secret key + * \param create_address_file Whether to create an address file */ void generate(const std::string& wallet, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, - const crypto::secret_key& spendkey, const crypto::secret_key& viewkey); + const crypto::secret_key& spendkey, const crypto::secret_key& viewkey, bool create_address_file = false); /*! * \brief Creates a watch only wallet from a public address and a view secret key. - * \param wallet_ Name of wallet file - * \param password Password of wallet file - * \param viewkey view secret key + * \param wallet_ Name of wallet file + * \param password Password of wallet file + * \param viewkey view secret key + * \param create_address_file Whether to create an address file */ void generate(const std::string& wallet, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, - const crypto::secret_key& viewkey = crypto::secret_key()); + const crypto::secret_key& viewkey = crypto::secret_key(), bool create_address_file = false); /*! * \brief Restore a wallet hold by an HW. * \param wallet_ Name of wallet file @@ -548,7 +552,7 @@ namespace tools * \param password Password for wallet file */ void rewrite(const std::string& wallet_name, const epee::wipeable_string& password); - void write_watch_only_wallet(const std::string& wallet_name, const epee::wipeable_string& password); + void write_watch_only_wallet(const std::string& wallet_name, const epee::wipeable_string& password, std::string &new_keys_filename); void load(const std::string& wallet, const epee::wipeable_string& password); void store(); /*! diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 370fea858..a0f43c9b9 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -398,7 +398,7 @@ namespace wallet_rpc KV_SERIALIZE(account_index) KV_SERIALIZE(subaddr_indices) KV_SERIALIZE(priority) - KV_SERIALIZE(mixin) + KV_SERIALIZE_OPT(mixin, (uint64_t)0) KV_SERIALIZE_OPT(ring_size, (uint64_t)0) KV_SERIALIZE(unlock_time) KV_SERIALIZE(payment_id) @@ -455,7 +455,7 @@ namespace wallet_rpc KV_SERIALIZE(account_index) KV_SERIALIZE(subaddr_indices) KV_SERIALIZE(priority) - KV_SERIALIZE(mixin) + KV_SERIALIZE_OPT(mixin, (uint64_t)0) KV_SERIALIZE_OPT(ring_size, (uint64_t)0) KV_SERIALIZE(unlock_time) KV_SERIALIZE(payment_id) @@ -568,7 +568,7 @@ namespace wallet_rpc KV_SERIALIZE(account_index) KV_SERIALIZE(subaddr_indices) KV_SERIALIZE(priority) - KV_SERIALIZE(mixin) + KV_SERIALIZE_OPT(mixin, (uint64_t)0) KV_SERIALIZE_OPT(ring_size, (uint64_t)0) KV_SERIALIZE(unlock_time) KV_SERIALIZE(payment_id) @@ -630,7 +630,7 @@ namespace wallet_rpc BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(address) KV_SERIALIZE(priority) - KV_SERIALIZE(mixin) + KV_SERIALIZE_OPT(mixin, (uint64_t)0) KV_SERIALIZE_OPT(ring_size, (uint64_t)0) KV_SERIALIZE(unlock_time) KV_SERIALIZE(payment_id) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 5e1525e3e..41256a4f1 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -521,7 +521,7 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins keypair* p_txkey/* = 0*/) { keypair txkey; - txkey = keypair::generate(); + txkey = keypair::generate(hw::get_device("default")); add_tx_pub_key_to_extra(tx, txkey.pub); if (0 != p_txkey) diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index d6d5236aa..f0a385ee5 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -49,7 +49,7 @@ namespace m_tx.version = version; m_tx.unlock_time = unlock_time; - m_tx_key = keypair::generate(); + m_tx_key = keypair::generate(hw::get_device("default")); add_tx_pub_key_to_extra(m_tx, m_tx_key.pub); } @@ -518,7 +518,7 @@ bool gen_tx_key_image_not_derive_from_tx_key::generate(std::vector<test_event_en builder.step2_fill_inputs(miner_account.get_keys(), sources); txin_to_key& in_to_key = boost::get<txin_to_key>(builder.m_tx.vin.front()); - keypair kp = keypair::generate(); + keypair kp = keypair::generate(hw::get_device("default")); key_image another_ki; crypto::generate_key_image(kp.pub, kp.sec, another_ki); in_to_key.k_image = another_ki; diff --git a/tests/crypto/CMakeLists.txt b/tests/crypto/CMakeLists.txt index c89049d50..df96c57cc 100644 --- a/tests/crypto/CMakeLists.txt +++ b/tests/crypto/CMakeLists.txt @@ -42,10 +42,7 @@ add_executable(cncrypto-tests ${crypto_headers}) target_link_libraries(cncrypto-tests PRIVATE - wallet - cryptonote_core common - device ${Boost_SYSTEM_LIBRARY} ${EXTRA_LIBRARIES}) set_property(TARGET cncrypto-tests diff --git a/tests/crypto/crypto.cpp b/tests/crypto/crypto.cpp index 90212bd0b..6a1dd1b29 100644 --- a/tests/crypto/crypto.cpp +++ b/tests/crypto/crypto.cpp @@ -33,7 +33,7 @@ #include "crypto-tests.h" bool check_scalar(const crypto::ec_scalar &scalar) { - return sc_check(crypto::operator &(scalar)) == 0; + return crypto::sc_check(crypto::operator &(scalar)) == 0; } void random_scalar(crypto::ec_scalar &res) { @@ -45,13 +45,13 @@ void hash_to_scalar(const void *data, std::size_t length, crypto::ec_scalar &res } void hash_to_point(const crypto::hash &h, crypto::ec_point &res) { - ge_p2 point; - ge_fromfe_frombytes_vartime(&point, reinterpret_cast<const unsigned char *>(&h)); - ge_tobytes(crypto::operator &(res), &point); + crypto::ge_p2 point; + crypto::ge_fromfe_frombytes_vartime(&point, reinterpret_cast<const unsigned char *>(&h)); + crypto::ge_tobytes(crypto::operator &(res), &point); } void hash_to_ec(const crypto::public_key &key, crypto::ec_point &res) { - ge_p3 tmp; + crypto::ge_p3 tmp; crypto::hash_to_ec(key, tmp); - ge_p3_tobytes(crypto::operator &(res), &tmp); + crypto::ge_p3_tobytes(crypto::operator &(res), &tmp); } diff --git a/tests/fuzz/cold-outputs.cpp b/tests/fuzz/cold-outputs.cpp index 9aa9460d5..59b59810c 100644 --- a/tests/fuzz/cold-outputs.cpp +++ b/tests/fuzz/cold-outputs.cpp @@ -54,6 +54,7 @@ int ColdOutputsFuzzer::init() try { wallet.init(""); + wallet.set_subaddress_lookahead(1, 1); wallet.generate("", "", spendkey, true, false); } catch (const std::exception &e) diff --git a/tests/fuzz/cold-transaction.cpp b/tests/fuzz/cold-transaction.cpp index d81092c82..da33dc318 100644 --- a/tests/fuzz/cold-transaction.cpp +++ b/tests/fuzz/cold-transaction.cpp @@ -55,6 +55,7 @@ int ColdTransactionFuzzer::init() try { wallet.init(""); + wallet.set_subaddress_lookahead(1, 1); wallet.generate("", "", spendkey, true, false); } catch (const std::exception &e) diff --git a/tests/fuzz/signature.cpp b/tests/fuzz/signature.cpp index 2b8ffe465..7f22757b2 100644 --- a/tests/fuzz/signature.cpp +++ b/tests/fuzz/signature.cpp @@ -55,6 +55,7 @@ int SignatureFuzzer::init() try { wallet.init(""); + wallet.set_subaddress_lookahead(1, 1); wallet.generate("", "", spendkey, true, false); cryptonote::address_parse_info info; diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp index 5a16284df..c7e1fe712 100644 --- a/tests/hash/main.cpp +++ b/tests/hash/main.cpp @@ -52,10 +52,10 @@ extern "C" { tree_hash((const char (*)[32]) data, length >> 5, hash); } static void cn_slow_hash_0(const void *data, size_t length, char *hash) { - return cn_slow_hash(data, length, hash, 0); + return cn_slow_hash(data, length, hash, 0/*variant*/, 0/*prehashed*/); } static void cn_slow_hash_1(const void *data, size_t length, char *hash) { - return cn_slow_hash(data, length, hash, 1); + return cn_slow_hash(data, length, hash, 1/*variant*/, 0/*prehashed*/); } } POP_WARNINGS diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index 1e63a12f3..fe31541df 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -130,7 +130,7 @@ struct Utils static std::string get_wallet_address(const std::string &filename, const std::string &password) { Monero::WalletManager *wmgr = Monero::WalletManagerFactory::getWalletManager(); - Monero::Wallet * w = wmgr->openWallet(filename, password, true); + Monero::Wallet * w = wmgr->openWallet(filename, password, Monero::NetworkType::TESTNET); std::string result = w->mainAddress(); wmgr->closeWallet(w); return result; @@ -208,7 +208,7 @@ struct WalletTest2 : public testing::Test TEST_F(WalletManagerTest, WalletManagerCreatesWallet) { - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(!wallet->seed().empty()); std::vector<std::string> words; @@ -225,10 +225,10 @@ TEST_F(WalletManagerTest, WalletManagerCreatesWallet) TEST_F(WalletManagerTest, WalletManagerOpensWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS); + Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); std::cout << "** seed: " << wallet2->seed() << std::endl; @@ -261,7 +261,7 @@ void open_wallet_helper(Monero::WalletManager *wmgr, Monero::Wallet **wallet, co if (mutex) mutex->lock(); LOG_PRINT_L3("opening wallet in thread: " << boost::this_thread::get_id()); - *wallet = wmgr->openWallet(WALLET_NAME, pass, true); + *wallet = wmgr->openWallet(WALLET_NAME, pass, Monero::NetworkType::TESTNET); LOG_PRINT_L3("wallet address: " << (*wallet)->mainAddress()); LOG_PRINT_L3("wallet status: " << (*wallet)->status()); LOG_PRINT_L3("closing wallet in thread: " << boost::this_thread::get_id()); @@ -277,7 +277,7 @@ void open_wallet_helper(Monero::WalletManager *wmgr, Monero::Wallet **wallet, co // // create password protected wallet // std::string wallet_pass = "password"; // std::string wrong_wallet_pass = "1111"; -// Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, true); +// Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Monero::NetworkType::TESTNET); // std::string seed1 = wallet1->seed(); // ASSERT_TRUE(wmgr->closeWallet(wallet1)); @@ -303,7 +303,7 @@ TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopen) // create password protected wallet std::string wallet_pass = "password"; std::string wrong_wallet_pass = "1111"; - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, true); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Monero::NetworkType::TESTNET); std::string seed1 = wallet1->seed(); ASSERT_TRUE(wmgr->closeWallet(wallet1)); @@ -326,11 +326,11 @@ TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopen) TEST_F(WalletManagerTest, WalletManagerStoresWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); wallet1->store(""); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS); + Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); } @@ -339,12 +339,12 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet) TEST_F(WalletManagerTest, WalletManagerMovesWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string WALLET_NAME_MOVED = std::string("/tmp/") + WALLET_NAME + ".moved"; std::string seed1 = wallet1->seed(); ASSERT_TRUE(wallet1->store(WALLET_NAME_MOVED)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_MOVED, WALLET_PASS); + Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_MOVED, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet2->filename() == WALLET_NAME_MOVED); ASSERT_TRUE(wallet2->keysFilename() == WALLET_NAME_MOVED + ".keys"); ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); @@ -354,15 +354,15 @@ TEST_F(WalletManagerTest, WalletManagerMovesWallet) TEST_F(WalletManagerTest, WalletManagerChangesPassword) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); ASSERT_TRUE(wallet1->setPassword(WALLET_PASS2)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS2); + Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS2, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); ASSERT_TRUE(wmgr->closeWallet(wallet2)); - Monero::Wallet * wallet3 = wmgr->openWallet(WALLET_NAME, WALLET_PASS); + Monero::Wallet * wallet3 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_FALSE(wallet3->status() == Monero::Wallet::Status_Ok); } @@ -370,13 +370,13 @@ TEST_F(WalletManagerTest, WalletManagerChangesPassword) TEST_F(WalletManagerTest, WalletManagerRecoversWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_FALSE(address1.empty()); ASSERT_TRUE(wmgr->closeWallet(wallet1)); Utils::deleteWallet(WALLET_NAME); - Monero::Wallet * wallet2 = wmgr->recoveryWallet(WALLET_NAME, seed1); + Monero::Wallet * wallet2 = wmgr->recoveryWallet(WALLET_NAME, seed1, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); ASSERT_TRUE(wallet2->mainAddress() == address1); @@ -386,14 +386,14 @@ TEST_F(WalletManagerTest, WalletManagerRecoversWallet) TEST_F(WalletManagerTest, WalletManagerStoresWallet1) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_TRUE(wallet1->store("")); ASSERT_TRUE(wallet1->store(WALLET_NAME_COPY)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_COPY, WALLET_PASS); + Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_COPY, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); ASSERT_TRUE(wallet2->mainAddress() == address1); @@ -403,14 +403,14 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet1) TEST_F(WalletManagerTest, WalletManagerStoresWallet2) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_TRUE(wallet1->store(WALLET_NAME_WITH_DIR)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR, WALLET_PASS); + wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet1->seed() == seed1); ASSERT_TRUE(wallet1->mainAddress() == address1); @@ -420,20 +420,20 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet2) TEST_F(WalletManagerTest, WalletManagerStoresWallet3) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_FALSE(wallet1->store(WALLET_NAME_WITH_DIR_NON_WRITABLE)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR_NON_WRITABLE, WALLET_PASS); + wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR_NON_WRITABLE, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_FALSE(wallet1->status() == Monero::Wallet::Status_Ok); // "close" always returns true; ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS); + wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet1->seed() == seed1); ASSERT_TRUE(wallet1->mainAddress() == address1); @@ -444,7 +444,7 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet3) TEST_F(WalletManagerTest, WalletManagerStoresWallet4) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); + Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); @@ -456,7 +456,7 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet4) ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS); + wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet1->seed() == seed1); ASSERT_TRUE(wallet1->mainAddress() == address1); @@ -488,7 +488,7 @@ TEST_F(WalletTest1, WalletGeneratesIntegratedAddress) { std::string payment_id = Monero::Wallet::genPaymentId(); - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); std::string integrated_address = wallet1->integratedAddress(payment_id); ASSERT_TRUE(integrated_address.length() == 106); } @@ -496,14 +496,14 @@ TEST_F(WalletTest1, WalletGeneratesIntegratedAddress) TEST_F(WalletTest1, WalletShowsBalance) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); ASSERT_TRUE(wallet1->balance(0) > 0); ASSERT_TRUE(wallet1->unlockedBalance(0) > 0); uint64_t balance1 = wallet1->balance(0); uint64_t unlockedBalance1 = wallet1->unlockedBalance(0); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet2 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); ASSERT_TRUE(balance1 == wallet2->balance(0)); std::cout << "wallet balance: " << wallet2->balance(0) << std::endl; @@ -514,7 +514,7 @@ TEST_F(WalletTest1, WalletShowsBalance) TEST_F(WalletTest1, WalletReturnsCurrentBlockHeight) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); ASSERT_TRUE(wallet1->blockChainHeight() > 0); wmgr->closeWallet(wallet1); } @@ -522,14 +522,14 @@ TEST_F(WalletTest1, WalletReturnsCurrentBlockHeight) TEST_F(WalletTest1, WalletReturnsDaemonBlockHeight) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // wallet not connected to daemon ASSERT_TRUE(wallet1->daemonBlockChainHeight() == 0); ASSERT_TRUE(wallet1->status() != Monero::Wallet::Status_Ok); ASSERT_FALSE(wallet1->errorString().empty()); wmgr->closeWallet(wallet1); - wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // wallet connected to daemon wallet1->init(TESTNET_DAEMON_ADDRESS, 0); ASSERT_TRUE(wallet1->daemonBlockChainHeight() > 0); @@ -542,7 +542,7 @@ TEST_F(WalletTest1, WalletRefresh) { std::cout << "Opening wallet: " << CURRENT_SRC_WALLET << std::endl; - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running std::cout << "connecting to daemon: " << TESTNET_DAEMON_ADDRESS << std::endl; ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); @@ -566,7 +566,7 @@ TEST_F(WalletTest1, WalletConvertsToString) TEST_F(WalletTest1, WalletTransaction) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet1->refresh()); @@ -608,7 +608,7 @@ TEST_F(WalletTest1, WalletTransactionWithMixin) std::string payment_id = ""; - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running @@ -642,7 +642,7 @@ TEST_F(WalletTest1, WalletTransactionWithPriority) std::string payment_id = ""; - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); @@ -682,7 +682,7 @@ TEST_F(WalletTest1, WalletTransactionWithPriority) TEST_F(WalletTest1, WalletHistory) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet1->refresh()); @@ -700,7 +700,7 @@ TEST_F(WalletTest1, WalletHistory) TEST_F(WalletTest1, WalletTransactionAndHistory) { return; - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); @@ -739,7 +739,7 @@ TEST_F(WalletTest1, WalletTransactionAndHistory) TEST_F(WalletTest1, WalletTransactionWithPaymentId) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); @@ -881,7 +881,7 @@ struct MyWalletListener : public Monero::WalletListener TEST_F(WalletTest2, WalletCallBackRefreshedSync) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src); ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src_listener->refresh_triggered); @@ -898,7 +898,7 @@ TEST_F(WalletTest2, WalletCallBackRefreshedSync) TEST_F(WalletTest2, WalletCallBackRefreshedAsync) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src); boost::chrono::seconds wait_for = boost::chrono::seconds(20); @@ -920,14 +920,14 @@ TEST_F(WalletTest2, WalletCallBackRefreshedAsync) TEST_F(WalletTest2, WalletCallbackSent) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src); uint64_t balance = wallet_src->balance(0); std::cout << "** Balance: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl; - Monero::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); uint64_t amount = AMOUNT_1XMR * 5; std::cout << "** Sending " << Monero::Wallet::displayAmount(amount) << " to " << wallet_dst->mainAddress(); @@ -959,13 +959,13 @@ TEST_F(WalletTest2, WalletCallbackSent) TEST_F(WalletTest2, WalletCallbackReceived) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); std::cout << "** Balance src1: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl; - Monero::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); ASSERT_TRUE(wallet_dst->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_dst->refresh()); uint64_t balance = wallet_dst->balance(0); @@ -1006,7 +1006,7 @@ TEST_F(WalletTest2, WalletCallbackReceived) TEST_F(WalletTest2, WalletCallbackNewBlock) { - Monero::Wallet * wallet_src = wmgr->openWallet(TESTNET_WALLET5_NAME, TESTNET_WALLET_PASS, true); + Monero::Wallet * wallet_src = wmgr->openWallet(TESTNET_WALLET5_NAME, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); @@ -1033,7 +1033,7 @@ TEST_F(WalletTest2, WalletCallbackNewBlock) TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetSync) { - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet)); wallet->init(MAINNET_DAEMON_ADDRESS, 0); std::cerr << "TEST: waiting on refresh lock...\n"; @@ -1052,7 +1052,7 @@ TEST_F(WalletManagerMainnetTest, CreateAndRefreshWalletMainNetAsync) // supposing 120 seconds should be enough for fast refresh int SECONDS_TO_REFRESH = 120; - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet)); boost::chrono::seconds wait_for = boost::chrono::seconds(SECONDS_TO_REFRESH); @@ -1075,9 +1075,9 @@ TEST_F(WalletManagerMainnetTest, OpenAndRefreshWalletMainNetAsync) // supposing 120 seconds should be enough for fast refresh int SECONDS_TO_REFRESH = 120; - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); wmgr->closeWallet(wallet); - wallet = wmgr->openWallet(WALLET_NAME_MAINNET, ""); + wallet = wmgr->openWallet(WALLET_NAME_MAINNET, "", Monero::NetworkType::MAINNET); std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet)); @@ -1102,7 +1102,7 @@ TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync) // supposing 120 seconds should be enough for fast refresh int SECONDS_TO_REFRESH = 120; - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); std::string seed = wallet->seed(); std::string address = wallet->mainAddress(); wmgr->closeWallet(wallet); @@ -1111,7 +1111,7 @@ TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync) Utils::deleteWallet(WALLET_NAME_MAINNET); // ..and recovering wallet from seed - wallet = wmgr->recoveryWallet(WALLET_NAME_MAINNET, seed); + wallet = wmgr->recoveryWallet(WALLET_NAME_MAINNET, seed, Monero::NetworkType::MAINNET); ASSERT_TRUE(wallet->status() == Monero::Wallet::Status_Ok); ASSERT_TRUE(wallet->mainAddress() == address); std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet)); diff --git a/tests/performance_tests/generate_keypair.h b/tests/performance_tests/generate_keypair.h index f97f4c213..91c830166 100644 --- a/tests/performance_tests/generate_keypair.h +++ b/tests/performance_tests/generate_keypair.h @@ -45,7 +45,7 @@ public: bool test() { - cryptonote::keypair::generate(); + cryptonote::keypair::generate(hw::get_device("default")); return true; } }; diff --git a/translations/monero_sv.ts b/translations/monero_sv.ts index 6b461c102..e99076960 100644 --- a/translations/monero_sv.ts +++ b/translations/monero_sv.ts @@ -21,7 +21,7 @@ <message> <location filename="../src/wallet/api/address_book.cpp" line="77"/> <source>Integrated address and long payment ID can't be used at the same time</source> - <translation type="unfinished"></translation> + <translation>Integrerad adress och långt betalnings-ID kan inte användas samtidigt</translation> </message> </context> <context> @@ -93,7 +93,7 @@ <message> <location filename="../src/wallet/api/unsigned_transaction.cpp" line="184"/> <source>Change goes to more than one address</source> - <translation>Växel går till mer än en adress</translation> + <translation>Växel går till fler än en adress</translation> </message> <message> <location filename="../src/wallet/api/unsigned_transaction.cpp" line="197"/> @@ -118,7 +118,7 @@ <message> <location filename="../src/wallet/api/unsigned_transaction.cpp" line="214"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu. %s</source> - <translation type="unfinished"></translation> + <translation>Läste in %lu transaktioner, för %s, avgift %s, %s, %s, med minsta ringstorlek %lu. %s</translation> </message> </context> <context> @@ -126,7 +126,7 @@ <message> <location filename="../src/wallet/api/wallet.cpp" line="1111"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> - <translation>betalnings-ID har ogiltigt format. En 16- eller 64-teckens hex-sträng förväntades: </translation> + <translation>betalnings-ID har ogiltigt format. En hexadecimal sträng med 16 eller 64 tecken förväntades: </translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1121"/> @@ -155,18 +155,18 @@ <location filename="../src/wallet/api/wallet.cpp" line="1197"/> <location filename="../src/wallet/api/wallet.cpp" line="1301"/> <source>not enough outputs for specified ring size</source> - <translation type="unfinished"></translation> + <translation>inte tillräckligt med utgångar för angiven ringstorlek</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1199"/> <location filename="../src/wallet/api/wallet.cpp" line="1303"/> <source>found outputs to use</source> - <translation type="unfinished"></translation> + <translation>hittade utgångar att använda</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1201"/> <source>Please sweep unmixable outputs.</source> - <translation type="unfinished"></translation> + <translation>Svep upp omixbara utgångar.</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1267"/> @@ -192,12 +192,12 @@ <message> <location filename="../src/wallet/api/wallet.cpp" line="496"/> <source>No view key supplied, cancelled</source> - <translation>Ingen visningsnyckel angiven, avbruten</translation> + <translation>Ingen granskningsnyckel angiven, avbruten</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="503"/> <source>failed to parse secret view key</source> - <translation>det gick inte att parsa hemlig visningsnyckel</translation> + <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="513"/> @@ -212,12 +212,12 @@ <message> <location filename="../src/wallet/api/wallet.cpp" line="524"/> <source>failed to verify secret view key</source> - <translation>det gick inte att verifiera hemlig visningsnyckel</translation> + <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="529"/> <source>view key does not match address</source> - <translation>visningsnyckel matchar inte adress</translation> + <translation>granskningsnyckel matchar inte adress</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="548"/> @@ -227,7 +227,7 @@ <message> <location filename="../src/wallet/api/wallet.cpp" line="773"/> <source>Failed to send import wallet request</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att skicka begäran om att importera plånbok</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="919"/> @@ -252,22 +252,22 @@ <message> <location filename="../src/wallet/api/wallet.cpp" line="986"/> <source>Key images can only be imported with a trusted daemon</source> - <translation type="unfinished"></translation> + <translation>Nyckelavbildningar kan bara importeras med en betrodd daemon</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="999"/> <source>Failed to import key images: </source> - <translation>det gick inte att importera nyckelavbildningar: </translation> + <translation>Det gick inte att importera nyckelavbildningar: </translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1032"/> <source>Failed to get subaddress label: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att hämta etikett för underadress: </translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1046"/> <source>Failed to set subaddress label: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att ange etikett för underadress: </translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1163"/> @@ -278,7 +278,7 @@ <location filename="../src/wallet/api/wallet.cpp" line="1179"/> <location filename="../src/wallet/api/wallet.cpp" line="1283"/> <source>not enough money to transfer, overall balance only %s, sent amount %s</source> - <translation type="unfinished"></translation> + <translation>inte tillräckligt med pengar för överföring, totalt saldo är bara %s, skickat belopp %s</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1188"/> @@ -348,18 +348,18 @@ <location filename="../src/wallet/api/wallet.cpp" line="1556"/> <location filename="../src/wallet/api/wallet.cpp" line="1579"/> <source>Failed to parse txid</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att parsa txid</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1430"/> <source>no tx keys found for this txid</source> - <translation type="unfinished">inga tx-nycklar kunde hittas för detta txid</translation> + <translation>inga tx-nycklar kunde hittas för detta txid</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1450"/> <location filename="../src/wallet/api/wallet.cpp" line="1460"/> <source>Failed to parse tx key</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att parsa txnyckel</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1470"/> @@ -367,12 +367,12 @@ <location filename="../src/wallet/api/wallet.cpp" line="1533"/> <location filename="../src/wallet/api/wallet.cpp" line="1621"/> <source>Failed to parse address</source> - <translation type="unfinished">Det gick inte att parsa adressen</translation> + <translation>Det gick inte att parsa adressen</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1627"/> <source>Address must not be a subaddress</source> - <translation type="unfinished"></translation> + <translation>Adressen får inte vara en underadress</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1849"/> @@ -413,7 +413,7 @@ <message> <location filename="../src/common/command_line.cpp" line="71"/> <source>no</source> - <translation type="unfinished"></translation> + <translation>nej</translation> </message> </context> <context> @@ -421,7 +421,7 @@ <message> <location filename="../src/rpc/rpc_args.cpp" line="40"/> <source>Specify IP to bind RPC server</source> - <translation type="unfinished"></translation> + <translation>Ange IP-adress för att binda till RPC-server</translation> </message> <message> <location filename="../src/rpc/rpc_args.cpp" line="41"/> @@ -431,12 +431,12 @@ <message> <location filename="../src/rpc/rpc_args.cpp" line="42"/> <source>Confirm rpc-bind-ip value is NOT a loopback (local) IP</source> - <translation>Bekräftelsevärde för rpc-bind-ip är INTE ett lokalt (loopback) IP</translation> + <translation>Bekräftelsevärde för rpc-bind-ip är INTE en lokal IP-adress (loopback)</translation> </message> <message> <location filename="../src/rpc/rpc_args.cpp" line="43"/> <source>Specify a comma separated list of origins to allow cross origin resource sharing</source> - <translation type="unfinished"></translation> + <translation>Ange en kommaseparerad lista av ursprung för att tillåta resursdelning för korsande ursprung (Cross-origin resource sharing)</translation> </message> <message> <location filename="../src/rpc/rpc_args.cpp" line="70"/> @@ -457,12 +457,12 @@ <location filename="../src/rpc/rpc_args.cpp" line="95"/> <location filename="../src/rpc/rpc_args.cpp" line="105"/> <source> cannot be empty</source> - <translation> kan inte vara tomt</translation> + <translation> får inte vara tomt</translation> </message> <message> <location filename="../src/rpc/rpc_args.cpp" line="105"/> <source> requires RFC server password --</source> - <translation type="unfinished"></translation> + <translation> kräver lösenord till RPC-server --</translation> </message> </context> <context> @@ -485,7 +485,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1905"/> <source>set seed: needs an argument. available options: language</source> - <translation>set seed: behöver ett argument. tillgängliga alternativ: språk</translation> + <translation>set seed: kräver ett argument. tillgängliga alternativ: språk</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1933"/> @@ -500,7 +500,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1987"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> - <translation>Försöker skapa eller återställa plånbok, men angivna filer existerar. Avslutar för att inte riskera att skriva över någonting.</translation> + <translation>Försöker skapa eller återställa plånbok, men angivna filer finns redan. Avslutar för att inte riskera att skriva över någonting.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="662"/> @@ -541,7 +541,7 @@ <location filename="../src/simplewallet/simplewallet.cpp" line="2041"/> <source>NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. </source> - <translation>OBSERVERA: följande 25 ord kan användas för att återfå tillgång till din plånbok. Skriv ner och spara dem på ett säkert ställe. Spara dem inte i din e-post eller på något lagringsutrymme som du inte har direkt kontroll över. + <translation>OBS: följande 25 ord kan användas för att återställa åtkomst till din plånbok. Skriv ner och spara dem på ett säkert ställe. Spara dem inte i din e-post eller på något lagringsutrymme som du inte har direkt kontroll över. </translation> </message> <message> @@ -572,7 +572,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2662"/> <source>List of available languages for your wallet's seed:</source> - <translation>Lista över tillgängliga språk för din plånboks frö:</translation> + <translation>Lista över tillgängliga språk för din plånboks startvärde:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2671"/> @@ -583,7 +583,7 @@ <location filename="../src/simplewallet/simplewallet.cpp" line="2737"/> <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. </source> - <translation>Du hade använt en inaktuell version av plånboken. Använd det nya frö som vi tillhandahåller. + <translation>Du hade använt en inaktuell version av plånboken. Använd det nya startvärde som tillhandahålls. </translation> </message> <message> @@ -632,7 +632,7 @@ <location filename="../src/simplewallet/simplewallet.cpp" line="2941"/> <source>Use the "help" command to see the list of available commands. </source> - <translation>Använd kommandot "help" för att se en lista över tillgängliga kommandon. + <translation>Använd kommandot "help" för att visa en lista över tillgängliga kommandon. </translation> </message> <message> @@ -663,7 +663,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> <source>Blockchain saved</source> - <translation>Blockkedjan sparad</translation> + <translation>Blockkedjan sparades</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3165"/> @@ -680,7 +680,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> <source>spent </source> - <translation>spenderad </translation> + <translation>spenderat </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3198"/> @@ -701,19 +701,19 @@ <location filename="../src/simplewallet/simplewallet.cpp" line="3758"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> - <translation>betalnings-ID har ogiltigt format. En 16- eller 64-teckens hex-sträng förväntades: </translation> + <translation>betalnings-ID har ogiltigt format. En hexadecimal sträng med 16 eller 64 tecken förväntades: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3773"/> <source>bad locked_blocks parameter:</source> - <translation>dålig parameter för locked_blocks:</translation> + <translation>felaktig parameter för locked_blocks:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3801"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4248"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4462"/> <source>a single transaction cannot use more than one payment id: </source> - <translation>en enstaka transaktion kan inte använda mer än ett betalnings-ID: </translation> + <translation>en enda transaktion kan inte använda fler än ett betalnings-ID: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3810"/> @@ -733,44 +733,47 @@ <location filename="../src/simplewallet/simplewallet.cpp" line="4484"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4527"/> <source>transaction cancelled.</source> - <translation>transaktion avbröts.</translation> + <translation>transaktion avbruten.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> <source>Is this okay anyway? (Y/Yes/N/No): </source> - <translation type="unfinished"></translation> + <translation>Är detta okej ändå? (J/Ja/N/Nej): </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3900"/> <source>There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): </source> - <translation type="unfinished"></translation> + <translation>Det finns för närvarande en %u blocks eftersläpning på den avgiftsnivån. Är detta okej? (J/Ja/N/Nej): </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> <source>Failed to check for backlog: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att kontrollera eftersläpning: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3946"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4302"/> <source> Transaction </source> - <translation type="unfinished"></translation> + <translation> +Transaktion </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3951"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4307"/> <source>Spending from address index %d </source> - <translation type="unfinished"></translation> + <translation>Spendera från adressindex %d +</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3953"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4309"/> <source>WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy. </source> - <translation type="unfinished"></translation> + <translation>VARNING: Utgångar från flera adresser används tillsammans, vilket möjligen kan kompromettera din sekretess. +</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3955"/> @@ -780,7 +783,7 @@ Transaction </source> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3958"/> <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> - <translation>Transaktionen behöver delas upp i %llu transaktioner. Detta kommer att göra att en transaktionsavgift läggs till varje transaktion, med ett totalt belopp på %s</translation> + <translation>Transaktionen behöver delas upp i %llu transaktioner. Detta gör att en transaktionsavgift läggs till varje transaktion, med ett totalbelopp på %s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3964"/> @@ -800,14 +803,14 @@ Transaction </source> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> <source>A total of %s from dust change will be sent to dust address</source> - <translation>Ett total belopp på %s från växeldamm kommer att skickas till damm-adressen</translation> + <translation>Ett totalt belopp på %s från växeldamm skickas till damm-adressen</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3973"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation>. -Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (förutsatt en blocktid på 2 minuter)</translation> +Denna transaktion låses upp vid block %llu, om ungefär %s dagar (förutsatt en blocktid på 2 minuter)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3999"/> @@ -844,9 +847,54 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <translation>Ingen adress har angivits</translation> </message> <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4424"/> + <source>failed to parse Payment ID</source> + <translation>det gick inte att parsa betalnings-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4440"/> + <source>usage: sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> + <translation>användning: sweep_single [<prioritet>] [<ringstorlek>] <nyckelavbildning> <adress> [<betalnings_id>]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4447"/> + <source>failed to parse key image</source> + <translation>det gick inte att parsa nyckelavbildning</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4499"/> + <source>No outputs found</source> + <translation>Inga utgångar kunde hittas</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4504"/> + <source>Multiple transactions are created, which is not supposed to happen</source> + <translation>Flera transaktioner skapas, vilket inte ska kunna inträffa</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> + <source>The transaction uses multiple or no inputs, which is not supposed to happen</source> + <translation>Transaktionen använder flera eller inga ingångar, vilket inte ska kunna inträffa</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4586"/> + <source>missing threshold amount</source> + <translation>tröskelbelopp saknas</translation> + </message> + <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> <source>invalid amount threshold</source> - <translation>ogiltig beloppströskel</translation> + <translation>ogiltigt tröskelbelopp</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4601"/> + <source>donations are not enabled on the testnet</source> + <translation>donationer är inte aktiverade på testnet</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> + <source>usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> + <translation>användning: donate [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <belopp> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4702"/> @@ -864,11 +912,31 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <translation>skickar %s till %s</translation> </message> <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4748"/> + <source> dummy output(s)</source> + <translation> dummy-utgångar</translation> + </message> + <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4751"/> <source>with no destinations</source> <translation>utan några mål</translation> </message> <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4763"/> + <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): </source> + <translation>Läste in %lu transaktioner, för %s, avgift %s, %s, %s, med minsta ringstorlek %lu, %s. %sÄr detta okej? (J/Ja/N/Nej): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> + <source>This is a multisig wallet, it can only sign with sign_multisig</source> + <translation>Detta är en multisig-plånbok, som endast kan signera med sign_multisig</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4797"/> + <source>usage: sign_transfer [export]</source> + <translation>användning: sign_transfer [export]</translation> + </message> + <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4809"/> <source>Failed to sign transaction</source> <translation>Det gick inte att signera transaktionen</translation> @@ -876,7 +944,12 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4815"/> <source>Failed to sign transaction: </source> - <translation>Det gick inte att signera transaktion: </translation> + <translation>Det gick inte att signera transaktionen: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4836"/> + <source>Transaction raw hex data exported to </source> + <translation>Hexadecimala rådata för transaktionen exporterades till </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4852"/> @@ -904,7 +977,7 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <message> <location filename="../src/simplewallet/simplewallet.cpp" line="650"/> <source>Error with wallet rewrite: </source> - <translation>Fel vid återskrivning av plånbok: </translation> + <translation>Ett fel uppstod vid återskrivning av plånbok: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> @@ -912,6 +985,12 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <translation>prioritet måste vara 0, 1, 2, 3 eller 4 </translation> </message> <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1301"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1316"/> + <source>priority must be 0, 1, 2, 3, or 4</source> + <translation>prioritet måste vara 0, 1, 2, 3 eller 4</translation> + </message> + <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1404"/> <source>invalid unit</source> <translation>ogiltig enhet</translation> @@ -941,7 +1020,7 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <location filename="../src/simplewallet/simplewallet.cpp" line="2509"/> <location filename="../src/simplewallet/simplewallet.cpp" line="2536"/> <source>bad m_restore_height parameter: </source> - <translation>dålig parameter för m_restore_height: </translation> + <translation>felaktig parameter för m_restore_height: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2514"/> @@ -1002,7 +1081,7 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> <source>refresh failed: </source> - <translation>det gick inte att att uppdatera: </translation> + <translation>det gick inte att uppdatera: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> @@ -1024,177 +1103,177 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <message> <location filename="../src/simplewallet/simplewallet.cpp" line="219"/> <source>false</source> - <translation type="unfinished"></translation> + <translation>falskt</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="493"/> <source>Unknown command: </source> - <translation type="unfinished"></translation> + <translation>Okänt kommando: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="500"/> <source>Command usage: </source> - <translation type="unfinished"></translation> + <translation>Användning av kommando: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> <source>Command description: </source> - <translation type="unfinished"></translation> + <translation>Beskrivning av kommando: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="551"/> <source>wallet is multisig but not yet finalized</source> - <translation type="unfinished"></translation> + <translation>plånboken är multisig men är ännu inte slutförd</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="567"/> <source>Enter optional seed encryption passphrase, empty to see raw seed</source> - <translation type="unfinished"></translation> + <translation>Ange valfri lösenfras för kryptering av startvärdet, lämna tomt för att se rådata för startvärdet</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="584"/> <source>Failed to retrieve seed</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att hämta startvärde</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="603"/> <source>wallet is multisig and has no seed</source> - <translation type="unfinished"></translation> + <translation>plånboken är multisig och har inget startvärde</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="674"/> <source>Cannot connect to daemon</source> - <translation type="unfinished"></translation> + <translation>Det går inte att ansluta till daemonen</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="679"/> <source>Current fee is %s monero per kB</source> - <translation type="unfinished"></translation> + <translation>Aktuell avgift är %s monero per kB</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> <source>Error: failed to estimate backlog array size: </source> - <translation type="unfinished"></translation> + <translation>Fel: det gick inte att uppskatta eftersläpningsmatrisens storlek: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> <source>Error: bad estimated backlog array size</source> - <translation type="unfinished"></translation> + <translation>Fel: felaktigt uppskattat värde för eftersläpningsmatrisens storlek</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> <source> (current)</source> - <translation type="unfinished"></translation> + <translation> (aktuellt)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> <source>%u block (%u minutes) backlog at priority %u%s</source> - <translation type="unfinished"></translation> + <translation>%u blocks (%u minuters) eftersläpning vid prioritet %u%s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> <source>%u to %u block (%u to %u minutes) backlog at priority %u</source> - <translation type="unfinished"></translation> + <translation>%u till %u blocks (%u till %u minuters) eftersläpning vid prioritet %u</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> <source>No backlog at priority </source> - <translation type="unfinished"></translation> + <translation>Ingen eftersläpning vid prioritet </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> <location filename="../src/simplewallet/simplewallet.cpp" line="762"/> <source>This wallet is already multisig</source> - <translation type="unfinished"></translation> + <translation>Denna plånbok är redan multisig</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> <location filename="../src/simplewallet/simplewallet.cpp" line="767"/> <source>wallet is watch-only and cannot be made multisig</source> - <translation type="unfinished"></translation> + <translation>plånboken är enbart för granskning och kan inte göras om till multisig</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> <location filename="../src/simplewallet/simplewallet.cpp" line="773"/> <source>This wallet has been used before, please use a new wallet to create a multisig wallet</source> - <translation type="unfinished"></translation> + <translation>Denna plånbok har använts tidigare. Använd en ny plånbok för att skapa en multisig-plånbok</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="747"/> <source>Your password is incorrect.</source> - <translation type="unfinished"></translation> + <translation>Ditt lösenord är fel.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="753"/> <source>Send this multisig info to all other participants, then use make_multisig <threshold> <info1> [<info2>...] with others' multisig info</source> - <translation type="unfinished"></translation> + <translation>Skicka denna multisig-info till alla andra deltagare och använd sedan make_multisig <tröskelvärde> <info1> [<info2>…] med de andras multisig-info</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="754"/> <source>This includes the PRIVATE view key, so needs to be disclosed only to that multisig wallet's participants </source> - <translation type="unfinished"></translation> + <translation>Detta innefattar den PRIVATA granskningsnyckeln, så den behöver endast lämnas ut till den multisig-plånbokens deltagare </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="786"/> <source>usage: make_multisig <threshold> <multisiginfo1> [<multisiginfo2>...]</source> - <translation type="unfinished"></translation> + <translation>användning: make_multisig <tröskelvärde> <multisiginfo1> [<multisiginfo2>…]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="794"/> <source>Invalid threshold</source> - <translation type="unfinished"></translation> + <translation>Ogiltigt tröskelvärde</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> <source>Another step is needed</source> - <translation type="unfinished"></translation> + <translation>Ytterligare ett steg krävs</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> <source>Send this multisig info to all other participants, then use finalize_multisig <info1> [<info2>...] with others' multisig info</source> - <translation type="unfinished"></translation> + <translation>Skicka denna multisig-info till alla andra deltagare, använd sedan finalize_multisig <info1> [<info2>…] med de andras multisig-info</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="815"/> <source>Error creating multisig: </source> - <translation type="unfinished"></translation> + <translation>Ett fel uppstod när multisig skapades: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="822"/> <source>Error creating multisig: new wallet is not multisig</source> - <translation type="unfinished"></translation> + <translation>Ett fel uppstod när multisig skapades: den nya plånboken är inte multisig</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="825"/> <source> multisig address: </source> - <translation type="unfinished"></translation> + <translation> multisig-adress: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="836"/> <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> <source>This wallet is not multisig</source> - <translation type="unfinished"></translation> + <translation>Denna plånbok är inte multisig</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="841"/> <source>This wallet is already finalized</source> - <translation type="unfinished"></translation> + <translation>Denna plånbok är redan slutförd</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> <source>usage: finalize_multisig <multisiginfo1> [<multisiginfo2>...]</source> - <translation type="unfinished"></translation> + <translation>användning: finalize_multisig <multisiginfo1> [<multisiginfo2>…]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="862"/> <source>Failed to finalize multisig</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att slutföra multisig</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> <source>Failed to finalize multisig: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att slutföra multisig: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="885"/> @@ -1203,1031 +1282,1073 @@ Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (fà <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> <location filename="../src/simplewallet/simplewallet.cpp" line="1136"/> <source>This multisig wallet is not yet finalized</source> - <translation type="unfinished"></translation> + <translation>Denna multisig-plånbok är inte slutförd ännu</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="890"/> <source>usage: export_multisig_info <filename></source> - <translation type="unfinished"></translation> + <translation>användning: export_multisig_info <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="913"/> <source>Error exporting multisig info: </source> - <translation type="unfinished"></translation> + <translation>Ett fel uppstod när multisig-info exporterades: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="917"/> <source>Multisig info exported to </source> - <translation type="unfinished"></translation> + <translation>Multisig-info exporterades till </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> <source>usage: import_multisig_info <filename1> [<filename2>...] - one for each other participant</source> - <translation type="unfinished"></translation> + <translation>användning: import_multisig_info <filename1> [<filename2>…] - en för varje annan deltagare</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="965"/> <source>Multisig info imported</source> - <translation type="unfinished"></translation> + <translation>Multisig-info importerades</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="969"/> <source>Failed to import multisig info: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att importera multisig-info: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="980"/> <source>Failed to update spent status after importing multisig info: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att uppdatera spenderstatus efter import av multisig-info: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="985"/> <source>Untrusted daemon, spent status may be incorrect. Use a trusted daemon and run "rescan_spent"</source> - <translation type="unfinished"></translation> + <translation>Ej betrodd daemon. Spenderstatus kan vara felaktig. Använd en betrodd daemon och kör "rescan_spent"</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1001"/> <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> <location filename="../src/simplewallet/simplewallet.cpp" line="1131"/> <source>This is not a multisig wallet</source> - <translation type="unfinished"></translation> + <translation>Detta är inte en multisig-plånbok</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> <source>usage: sign_multisig <filename></source> - <translation type="unfinished"></translation> + <translation>användning: sign_multisig <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1024"/> <source>Failed to sign multisig transaction</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att signera multisig-transaktion</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1030"/> <source>Multisig error: </source> - <translation type="unfinished"></translation> + <translation>Multisig-fel: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1035"/> <source>Failed to sign multisig transaction: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att signera multisig-transaktion: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1058"/> <source>It may be relayed to the network with submit_multisig</source> - <translation type="unfinished"></translation> + <translation>Den kan skickas vidare till nätverket med submit_multisig</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> <source>usage: submit_multisig <filename></source> - <translation type="unfinished"></translation> + <translation>användning: submit_multisig <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1094"/> <location filename="../src/simplewallet/simplewallet.cpp" line="1155"/> <source>Failed to load multisig transaction from file</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att läsa in multisig-transaktion från fil</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> <location filename="../src/simplewallet/simplewallet.cpp" line="1160"/> <source>Multisig transaction signed by only %u signers, needs %u more signatures</source> - <translation type="unfinished"></translation> + <translation>Multisig-transaktion har signerats av bara %u signerare. Den behöver %u ytterligare signaturer</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1108"/> <location filename="../src/simplewallet/simplewallet.cpp" line="6750"/> <source>Transaction successfully submitted, transaction </source> - <translation type="unfinished"></translation> + <translation>Transaktionen skickades, transaktion </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1109"/> <location filename="../src/simplewallet/simplewallet.cpp" line="6751"/> <source>You can check its status by using the `show_transfers` command.</source> - <translation type="unfinished"></translation> + <translation>Du kan kontrollera dess status genom att använda kommandot 'show_transfers'.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> <source>usage: export_raw_multisig <filename></source> - <translation type="unfinished"></translation> + <translation>användning: export_raw_multisig <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> <source>Failed to export multisig transaction to file </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att exportera multisig-transaktion till fil </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1180"/> <source>Saved exported multisig transaction file(s): </source> - <translation type="unfinished"></translation> + <translation>Sparade filer med exporterade multisig-transaktioner: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1252"/> <location filename="../src/simplewallet/simplewallet.cpp" line="1258"/> <location filename="../src/simplewallet/simplewallet.cpp" line="1272"/> <source>ring size must be an integer >= </source> - <translation type="unfinished"></translation> + <translation>ringstorlek måste vara ett heltal >= </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1277"/> <source>could not change default ring size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1301"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1316"/> - <source>priority must be 0, 1, 2, 3, or 4</source> - <translation type="unfinished">prioritet måste vara 0, 1, 2, 3 eller 4 {0, 1, 2, 3,?} {4?}</translation> + <translation>det gick inte att ändra standardinställning för ringstorlek</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> <source>Invalid height</source> - <translation type="unfinished"></translation> + <translation>Ogiltig höjd</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1564"/> <source>start_mining [<number_of_threads>] [bg_mining] [ignore_battery]</source> - <translation type="unfinished"></translation> + <translation>start_mining [<antal_trådar>] [<bgbrytning>] [<ignorera_batteri>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1565"/> <source>Start mining in the daemon (bg_mining and ignore_battery are optional booleans).</source> - <translation type="unfinished"></translation> + <translation>Starta brytning i daemonen (bgbrytning och ignorera_batteri är valfri booleska värden).</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1568"/> <source>Stop mining in the daemon.</source> - <translation type="unfinished"></translation> + <translation>Stoppa brytning i daemonen.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1571"/> <source>set_daemon <host>[:<port>]</source> - <translation type="unfinished"></translation> + <translation>set_daemon <värddator>[:<port>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1572"/> <source>Set another daemon to connect to.</source> - <translation type="unfinished"></translation> + <translation>Ange en annan daemon att ansluta till.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1575"/> <source>Save the current blockchain data.</source> - <translation type="unfinished"></translation> + <translation>Spara aktuella blockkedjedata.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> <source>Synchronize the transactions and balance.</source> - <translation type="unfinished"></translation> + <translation>Synkronisera transaktionerna och saldot.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1581"/> <source>balance [detail]</source> - <translation type="unfinished"></translation> + <translation>balance [detail]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1582"/> <source>Show the wallet's balance of the currently selected account.</source> - <translation type="unfinished"></translation> + <translation>Visa plånbokens saldo för det aktiva kontot.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1585"/> <source>incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation type="unfinished"></translation> + <translation>incoming_transfers [available|unavailable] [verbose] [index=<N1>[, <N2>[, …]]]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1586"/> <source>Show the incoming transfers, all or filtered by availability and address index.</source> - <translation type="unfinished"></translation> + <translation>Visa inkommande överföringar: alla eller filtrerade efter tillgänglighet och adressindex.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1589"/> <source>payments <PID_1> [<PID_2> ... <PID_N>]</source> - <translation type="unfinished"></translation> + <translation>payments <BID_1> [<BID_2> … <BID_N>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1590"/> <source>Show the payments for the given payment IDs.</source> - <translation type="unfinished"></translation> + <translation>Visa betalningar för givna betalnings-ID.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1593"/> <source>Show the blockchain height.</source> - <translation type="unfinished"></translation> + <translation>Visa blockkedjans höjd.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1596"/> <source>transfer_original [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>transfer_original [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> <belopp> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1597"/> <source>Transfer <amount> to <address> using an older transaction building algorithm. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation type="unfinished"></translation> + <translation>Överför <belopp> till <adress> genom att använda en äldre algoritm för att bygga transaktioner. Om parametern "index=<N1>[, <N2>, …]" anges använder plånboken utgångar som tagits emot av adresser vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt adressindex att använda. Oavsett vilket kommer den att göra sitt bästa för att inte kombinera utgångar från flera adresser. <prioritet> är transaktionens prioritet. Ju högre prioritet, desto högre transaktionsavgift. Giltiga värden i prioritetsordning (från lägsta till högsta) är: unimportant, normal, elevated, priority. Om värdet utelämnas kommer standardvärdet att användas (se kommandot "set priority"). <ringstorlek> är det antal ingångar som ska inkluderas för att uppnå ospårbarhet. Flera betalningar kan göras på en gång genom att lägga till <adress_2> <belopp_2> osv (före betalnings-ID, om det inkluderas)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> <source>transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>transfer [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> <belopp> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1600"/> <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation type="unfinished"></translation> + <translation>Överför <belopp> till <adress>. Om parametern "index=<N1>[, <N2>, …]" anges använder plånboken utgångar som tagits emot av adresser vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt adressindex att använda. Oavsett vilket kommer den att göra sitt bästa för att inte kombinera utgångar från flera adresser. <prioritet> är transaktionens prioritet. Ju högre prioritet, desto högre transaktionsavgift. Giltiga värden i prioritetsordning (från lägsta till högsta) är: unimportant, normal, elevated, priority. Om värdet utelämnas kommer standardvärdet att användas (se kommandot "set priority"). <ringstorlek> är det antal ingångar som ska inkluderas för att uppnå ospårbarhet. Flera betalningar kan göras på en gång genom att lägga till <adress_2> <belopp_2> osv (före betalnings-ID, om det inkluderas)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> <source>locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <addr> <amount> <lockblocks> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>locked_transfer [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> <belopp> <låsblock> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation type="unfinished"></translation> + <translation>Överför <belopp> till <adress> och lås det i <låsblock> (max. 1000000). Om parametern "index=<N1>[, <N2>, …]" anges använder plånboken utgångar som tagits emot av adresser vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt adressindex att använda. Oavsett vilket kommer den att göra sitt bästa för att inte kombinera utgångar från flera adresser. <prioritet> är transaktionens prioritet. Ju högre prioritet, desto högre transaktionsavgift. Giltiga värden i prioritetsordning (från lägsta till högsta) är: unimportant, normal, elevated, priority. Om värdet utelämnas kommer standardvärdet att användas (se kommandot "set priority"). <ringstorlek> är det antal ingångar som ska inkluderas för att uppnå ospårbarhet. Flera betalningar kan göras på en gång genom att lägga till <adress_2> <belopp_2> osv (före betalnings-ID, om det inkluderas)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1607"/> <source>Send all unmixable outputs to yourself with ring_size 1</source> - <translation type="unfinished"></translation> + <translation>Skicka alla omixbara utgångar till dig själv med ringstorlek 1</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1609"/> <source>sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>sweep_all [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1610"/> <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used.</source> - <translation type="unfinished"></translation> + <translation>Skicka allt upplåst saldo till en adress. Om parametern "index<N1>[, <N2>, …]" anges sveper plånboken upp utgångar som tagits emot av adresserna vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt ett adressindex att använda.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> <source>sweep_below <amount_threshold> [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>sweep_below <tröskelbelopp> [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1614"/> <source>Send all unlocked outputs below the threshold to an address.</source> - <translation type="unfinished"></translation> + <translation>Skicka alla upplåsta utgångar under tröskelvärdet till en adress.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1617"/> <source>sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>sweep_single [<prioritet>] [<ringstorlek>] <nyckelavbildning> <adress> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1618"/> <source>Send a single output of the given key image to an address without change.</source> - <translation type="unfinished"></translation> + <translation>Skicka en enda utgång hos den givna nyckelavbildningen till en adress utan växel.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1621"/> <source>donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>donate [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <belopp> [<betalnings_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1622"/> <source>Donate <amount> to the development team (donate.getmonero.org).</source> - <translation type="unfinished"></translation> + <translation>Donera <belopp> till utvecklingsteamet (donate.getmonero.org).</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1625"/> <source>sign_transfer <file></source> - <translation type="unfinished"></translation> + <translation>sign_transfer <fil></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> <source>Sign a transaction from a <file>.</source> - <translation type="unfinished"></translation> + <translation>Signera en transaktion från <fil>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1629"/> <source>Submit a signed transaction from a file.</source> - <translation type="unfinished"></translation> + <translation>Skicka en signerad transaktion från en fil.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1632"/> <source>set_log <level>|{+,-,}<categories></source> - <translation type="unfinished"></translation> + <translation>set_log <nivå>|{+,-,}<kategorier></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1633"/> <source>Change the current log detail (level must be <0-4>).</source> - <translation type="unfinished"></translation> + <translation>Ändra detaljnivån för aktuell logg (nivå måste vara 0-4).</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> <source>account account new <label text with white spaces allowed> account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation type="unfinished"></translation> + account label <index> <label text with white spaces allowed> + account tag <tag_name> <account_index_1> [<account_index_2> ...] + account untag <account_index_1> [<account_index_2> ...] + account tag_description <tag_name> <description></source> + <translation>account + account new <etikettext med blanktecken tillåtna> + account switch <index> + account label <index> <etikettext med blanktecken tillåtna> + account tag <taggnamn> <kontoindex_1> [<kontoindex_2> …] + account untag <kontoindex_1> [<kontoindex_2> …] + account tag_description <taggnamn> <beskrivning></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1643"/> <source>If no arguments are specified, the wallet shows all the existing accounts along with their balances. If the "new" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty). -If the "switch" argument is specified, the wallet switches to the account specified by <index>. -If the "label" argument is specified, the wallet sets the label of the account specified by <index> to the provided label text. -If the "tag" argument is specified, a tag <tag_name> is assigned to the specified accounts <account_index_1>, <account_index_2>, .... -If the "untag" argument is specified, the tags assigned to the specified accounts <account_index_1>, <account_index_2> ..., are removed. -If the "tag_description" argument is specified, the tag <tag_name> is assigned an arbitrary text <description>.</source> - <translation type="unfinished"></translation> +If the "switch" argument is specified, the wallet switches to the account specified by <index>. +If the "label" argument is specified, the wallet sets the label of the account specified by <index> to the provided label text. +If the "tag" argument is specified, a tag <tag_name> is assigned to the specified accounts <account_index_1>, <account_index_2>, .... +If the "untag" argument is specified, the tags assigned to the specified accounts <account_index_1>, <account_index_2> ..., are removed. +If the "tag_description" argument is specified, the tag <tag_name> is assigned an arbitrary text <description>.</source> + <translation>Om inga argument anges visas plånbokens samtliga befintliga konton, tillsammans med deras respektive saldo. +Om argumentet "new" anges, skapar plånboken ett nytt konto med etiketten satt till med den angivna etikettexten (som kan vara tom). +Om argumentet "switch" anges, växlar plånboken till det konto som anges av <index>. +Om argumentet "label" anges, sätter plånboken etiketten för kontot som anges av <index> till den angivna etikettexten. +Om argumentet "tag" anges, så tilldelas taggen <taggnamn> till det angivna kontona <kontoindex_1>, <kontoindex_2>, … +Om argumentet "untag" anges, tas tilldelade taggar bort från de angivna kontona <kontoindex_1>, <kontoindex_2> … +Om argumentet "tag_description" anges, så tilldelas taggen <taggnamn> den godtyckliga texten <beskrivning>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1652"/> <source>address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed>]</source> - <translation type="unfinished"></translation> + <translation>address [new <etikettext med blanktecken tillåtna> | all | <index_min> [<index_max>] | label <index> <etikettext med blanktecken tillåtna>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1653"/> <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the walllet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> - <translation type="unfinished"></translation> + <translation>Om inga argument anges, eller om <index> anges, visar plånboken standardadressen eller den angivna adressen. Om argumentet "all" anges visar plånboken samtliga befintliga adresser i det aktiva kontot. Om argumentet "new " anges skapar plånboken en ny adress med den angivna etikettexten (som kan vara tom). Om argumentet "label" anges sätter plånboken etiketten för adressen som anges av <index> till den angivna etikettexten.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1656"/> <source>integrated_address [<payment_id> | <address>]</source> - <translation type="unfinished"></translation> + <translation>integrated_address [<betalnings-id> | <adress>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> <source>Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> - <translation type="unfinished"></translation> + <translation>Koda ett betalnings-ID till en integrerad adress för den aktuella plånbokens publika adress (om inget argument anges används ett slumpmässigt betalnings-ID), eller avkoda en integrerad adress till en standardadress och ett betalnings-ID</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1660"/> <source>address_book [(add ((<address> [pid <id>])|<integrated address>) [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation type="unfinished"></translation> + <translation>address_book [(add ((<adress> [pid <id>])|<integrerad adress>) [<beskrivning eventuellt med blanktecken>])|(delete <index>)]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1661"/> <source>Print all entries in the address book, optionally adding/deleting an entry to/from it.</source> - <translation type="unfinished"></translation> + <translation>Skriv ut alla poster i adressboken, och valfritt lägg till/ta bort en post i den.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> <source>Save the wallet data.</source> - <translation type="unfinished"></translation> + <translation>Spara plånboksdata.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1667"/> <source>Save a watch-only keys file.</source> - <translation type="unfinished"></translation> + <translation>Spara en fil med granskningsnycklar.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> <source>Display the private view key.</source> - <translation type="unfinished"></translation> + <translation>Visa privat granskningsnyckel.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1673"/> <source>Display the private spend key.</source> - <translation type="unfinished"></translation> + <translation>Visa privat spendernyckel.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1676"/> <source>Display the Electrum-style mnemonic seed</source> - <translation type="unfinished"></translation> + <translation>Visa det minnesbaserade startvärdet (Electrum-typ)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> <source>set <option> [<value>]</source> - <translation type="unfinished"></translation> + <translation>set <alternativ> [<värde>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1680"/> <source>Available options: seed language Set the wallet's seed language. - always-confirm-transfers <1|0> + always-confirm-transfers <1|0> Whether to confirm unsplit txes. - print-ring-members <1|0> + print-ring-members <1|0> Whether to print detailed information about ring members during confirmation. - store-tx-info <1|0> + store-tx-info <1|0> Whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference. - default-ring-size <n> + default-ring-size <n> Set the default ring size (default and minimum is 5). - auto-refresh <1|0> + auto-refresh <1|0> Whether to automatically synchronize new blocks from the daemon. - refresh-type <full|optimize-coinbase|no-coinbase|default> + refresh-type <full|optimize-coinbase|no-coinbase|default> Set the wallet's refresh behaviour. priority [0|1|2|3|4] Set the fee too default/unimportant/normal/elevated/priority. - confirm-missing-payment-id <1|0> - ask-password <1|0> - unit <monero|millinero|micronero|nanonero|piconero> + confirm-missing-payment-id <1|0> + ask-password <1|0> + unit <monero|millinero|micronero|nanonero|piconero> Set the default monero (sub-)unit. min-outputs-count [n] Try to keep at least that many outputs of value at least min-outputs-value. min-outputs-value [n] Try to keep at least min-outputs-count outputs of at least that value. - merge-destinations <1|0> + merge-destinations <1|0> Whether to merge multiple payments to the same destination address. - confirm-backlog <1|0> + confirm-backlog <1|0> Whether to warn if there is transaction backlog. confirm-backlog-threshold [n] Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. refresh-from-block-height [n] Set the height before which to ignore blocks. - auto-low-priority <1|0> + auto-low-priority <1|0> Whether to automatically use the low priority fee level when it's safe to do so.</source> - <translation type="unfinished"></translation> + <translation>Tillgängliga alternativ: + språk för startvärde + Ange plånbokens språk för startvärde. + always-confirm-transfers <1|0> + Om ej delade transaktioner ska bekräftas. + print-ring-members <1|0> + Om detaljerad information om ringmedlemmar ska skrivas ut vid bekräftelse. + store-tx-info <1|0> + Om information om utgående transaktion ska sparas (måladress, betalnings-ID, hemlig tx-nyckel) som referens. + default-ring-size <n> + Ange standardinställning för ringstorlek (standard och minimum är 5). + auto-refresh <1|0> + Om nya block ska synkas automatiskt från daemonen. + refresh-type <full|optimize-coinbase|no-coinbase|default> + Ange plånbokens uppdateringsbeteende. + priority [0|1|2|3|4] + Sätt avgiften till default/unimportant/normal/elevated/priority. + confirm-missing-payment-id <1|0> + ask-password <1|0> + unit <monero|millinero|micronero|nanonero|piconero> + Ange standardvärde för moneroenhet. + min-outputs-count [n] + Försök att behålla åtminstone så många utgångar med åtminstone värdet min-outputs-value. + min-outputs-value [n] + Försök att behålla åtminstone min-outputs-count utgångar med åtminstone det värdet. + merge-destinations <1|0> + Om flera betalningar till samma måladress ska sammanslås. + confirm-backlog <1|0> + Om en varning ska visas om det föreligger transaktionseftersläpning. + confirm-backlog-threshold [n] + Ange ett tröskelvärde för confirm-backlog för att endast varna om transaktionseftersläpningen är större än n block. + refresh-from-block-height [n] + Ange höjden upp till vilken block ska ignoreras. + auto-low-priority <1|0> + Om avgiftsnivån för låg prioritet automatiskt ska användas när detta är säkert att göra.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1717"/> <source>Display the encrypted Electrum-style mnemonic seed.</source> - <translation type="unfinished"></translation> + <translation>Visa det krypterade minnesbaserade startvärdet (Electrum-typ).</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> <source>Rescan the blockchain for spent outputs.</source> - <translation type="unfinished"></translation> + <translation>Genomsök blockkedjan efter spenderade utgångar.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1723"/> <source>get_tx_key <txid></source> - <translation type="unfinished"></translation> + <translation>get_tx_key <txid></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1724"/> <source>Get the transaction key (r) for a given <txid>.</source> - <translation type="unfinished"></translation> + <translation>Hämta transaktionsnyckel (r) för ett givet <txid>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1727"/> <source>check_tx_key <txid> <txkey> <address></source> - <translation type="unfinished"></translation> + <translation>check_tx_key <txid> <txkey> <adress></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1728"/> <source>Check the amount going to <address> in <txid>.</source> - <translation type="unfinished"></translation> + <translation>Kontrollera belopp som går till <adress> i <txid>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> <source>get_tx_proof <txid> <address> [<message>]</source> - <translation type="unfinished"></translation> + <translation>get_tx_proof <txid> <adress> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> <source>Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key.</source> - <translation type="unfinished"></translation> + <translation>Skapa en signatur som bevisar att pengar skickades till <adress> i <txid>, valfritt med kontrollsträngen <meddelande>, genom att använda antingen transaktionens hemliga nyckel (när <adress> inte är din plånboks adress) eller den hemliga granskningsnyckeln (annars), vilket inte lämnar ut den hemliga nyckeln.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1735"/> <source>check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> + <translation>check_tx_proof <txid> <adress> <signaturfil> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> <source>Check the proof for funds going to <address> in <txid> with the challenge string <message> if any.</source> - <translation type="unfinished"></translation> + <translation>Kontrollera beviset för pengar som skickats till <adress> i <txid> med kontrollsträngen <meddelande>, om den angivits.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1739"/> <source>get_spend_proof <txid> [<message>]</source> - <translation type="unfinished"></translation> + <translation>get_spend_proof <txid> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> <source>Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>.</source> - <translation type="unfinished"></translation> + <translation>Skapa en signatur som bevisar att du skapade <txid> genom att använda den hemliga spendernyckeln, valfritt med kontrollsträngen <meddelande>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> <source>check_spend_proof <txid> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> + <translation>check_spend_proof <txid> <signaturfil> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1744"/> <source>Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.</source> - <translation type="unfinished"></translation> + <translation>Kontrollera en signatur som bevisar att signeraren skapade <txid>, valfritt med kontrollsträngen <meddelande>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1747"/> <source>get_reserve_proof (all|<amount>) [<message>]</source> - <translation type="unfinished"></translation> + <translation>get_reserve_proof (all|<belopp>) [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1748"/> <source>Generate a signature proving that you own at least this much, optionally with a challenge string <message>. If 'all' is specified, you prove the entire sum of all of your existing accounts' balances. Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.</source> - <translation type="unfinished"></translation> + <translation>Skapa en signatur som bevisar att du äger åtminstone så här mycket, valfritt med kontrollsträngen <meddelande>. +Om 'all' anges, bevisar du totalsumman av alla dina befintliga kontons saldo. +Annars bevisar du reserven för det minsta möjliga belopp över <belopp> som är tillgängligt på ditt aktuella konto.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1753"/> <source>check_reserve_proof <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> + <translation>check_reserve_proof <adress> <signaturfil> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> <source>Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.</source> - <translation type="unfinished"></translation> + <translation>Kontrollera en signatur som bevisar att ägaren till <adress> har åtminstone så här mycket, valfritt med kontrollsträngen <meddelande>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1757"/> <source>show_transfers [in|out|pending|failed|pool] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation type="unfinished"></translation> + <translation>show_transfers [in|out|pending|failed|pool] [index=<N1>[, <N2>, …]] [<min_höjd> [<max_höjd>]]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1758"/> <source>Show the incoming/outgoing transfers within an optional height range.</source> - <translation type="unfinished"></translation> + <translation>Visa inkommande/utgående överföringar inom ett valfritt höjdintervall.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1761"/> <source>unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation type="unfinished"></translation> + <translation>unspent_outputs [index=<N1>[, <N2>, …]] [<min_belopp> [<max_belopp>]]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1762"/> <source>Show the unspent outputs of a specified address within an optional amount range.</source> - <translation type="unfinished"></translation> + <translation>Visa de ej spenderade utgångarna hos en angiven adress inom ett valfritt beloppsintervall.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> <source>Rescan the blockchain from scratch.</source> - <translation type="unfinished"></translation> + <translation>Genomsök blockkedjan från början.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1768"/> <source>set_tx_note <txid> [free text note]</source> - <translation type="unfinished"></translation> + <translation>set_tx_note <txid> [<fritextanteckning>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1769"/> <source>Set an arbitrary string note for a <txid>.</source> - <translation type="unfinished"></translation> + <translation>Ange en godtycklig stränganteckning för <txid>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1772"/> <source>get_tx_note <txid></source> - <translation type="unfinished"></translation> + <translation>get_tx_note <txid></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> <source>Get a string note for a txid.</source> - <translation type="unfinished"></translation> + <translation>Hämta en stränganteckning för ett txid.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1776"/> <source>set_description [free text note]</source> - <translation type="unfinished"></translation> + <translation>set_description [<fritextanteckning>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1777"/> <source>Set an arbitrary description for the wallet.</source> - <translation type="unfinished"></translation> + <translation>Ange en godtycklig beskrivning av plånboken.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1780"/> <source>Get the description of the wallet.</source> - <translation type="unfinished"></translation> + <translation>Hämta plånbokens beskrivning.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1783"/> <source>Show the wallet's status.</source> - <translation type="unfinished"></translation> + <translation>Visa plånbokens status.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1786"/> <source>Show the wallet's information.</source> - <translation type="unfinished"></translation> + <translation>Visa information om plånboken.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1789"/> <source>sign <file></source> - <translation type="unfinished"></translation> + <translation>sign <fil></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1790"/> <source>Sign the contents of a file.</source> - <translation type="unfinished"></translation> + <translation>Signera innehållet i en fil.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1793"/> <source>verify <filename> <address> <signature></source> - <translation type="unfinished"></translation> + <translation>verify <filnamn> <adress> <signatur></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> <source>Verify a signature on the contents of a file.</source> - <translation type="unfinished"></translation> + <translation>Verifiera en signatur av innehållet in en fil.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1797"/> <source>export_key_images <file></source> - <translation type="unfinished"></translation> + <translation>export_key_images <fil></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1798"/> <source>Export a signed set of key images to a <file>.</source> - <translation type="unfinished"></translation> + <translation>Exportera en signerad uppsättning nyckelavbildningar till <fil>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1801"/> <source>import_key_images <file></source> - <translation type="unfinished"></translation> + <translation>import_key_images <fil></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1802"/> <source>Import a signed key images list and verify their spent status.</source> - <translation type="unfinished"></translation> + <translation>Importera en signerad lista av nyckelavbildningar och verifiera deras spenderstatus.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1805"/> <source>export_outputs <file></source> - <translation type="unfinished"></translation> + <translation>export_outputs <fil></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1806"/> <source>Export a set of outputs owned by this wallet.</source> - <translation type="unfinished"></translation> + <translation>Exportera en uppsättning utgångar som ägs av denna plånbok.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1809"/> <source>import_outputs <file></source> - <translation type="unfinished"></translation> + <translation>import_outputs <fil></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> <source>Import a set of outputs owned by this wallet.</source> - <translation type="unfinished"></translation> + <translation>Importera en uppsättning utgångar som ägs av denna plånbok.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> <source>show_transfer <txid></source> - <translation type="unfinished"></translation> + <translation>show_transfer <txid></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1814"/> <source>Show information about a transfer to/from this address.</source> - <translation type="unfinished"></translation> + <translation>Visa information om en transktion till/från denna adress.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1817"/> <source>Change the wallet's password.</source> - <translation type="unfinished"></translation> + <translation>Ändra plånbokens lösenord.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> <source>Generate a new random full size payment id. These will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids.</source> - <translation type="unfinished"></translation> + <translation>Skapa ett nytt slumpmässigt betalnings-ID av normalstorlek. Dessa kommer att vara okrypterade på blockkedjan. Se integrated_address för krypterade korta betalnings-ID.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1823"/> <source>Print the information about the current fee and transaction backlog.</source> - <translation type="unfinished"></translation> + <translation>Skriv ut information om aktuell avgift och transaktionseftersläpning.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1825"/> <source>Export data needed to create a multisig wallet</source> - <translation type="unfinished"></translation> + <translation>Exportera data som krävs för att skapa en multisig-plånbok</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> <source>make_multisig <threshold> <string1> [<string>...]</source> - <translation type="unfinished"></translation> + <translation>make_multisig <tröskelvärde> <string1> [<sträng>…]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> <source>Turn this wallet into a multisig wallet</source> - <translation type="unfinished"></translation> + <translation>Gör denna plånbok till en multisig-plånbok</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1831"/> <source>finalize_multisig <string> [<string>...]</source> - <translation type="unfinished"></translation> + <translation>finalize_multisig <sträng> [<sträng>…]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1832"/> <source>Turn this wallet into a multisig wallet, extra step for N-1/N wallets</source> - <translation type="unfinished"></translation> + <translation>Gör denna plånbok till en multisig-plånbok, extra steg för plånböcker med N-1/N</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1835"/> <source>export_multisig_info <filename></source> - <translation type="unfinished"></translation> + <translation>export_multisig_info <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1836"/> <source>Export multisig info for other participants</source> - <translation type="unfinished"></translation> + <translation>Exportera multisig-info för andra deltagare</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> <source>import_multisig_info <filename> [<filename>...]</source> - <translation type="unfinished"></translation> + <translation>import_multisig_info <filnamn> [<filnamn>…]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1840"/> <source>Import multisig info from other participants</source> - <translation type="unfinished"></translation> + <translation>Importera multisig-info från andra deltagare</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1843"/> <source>sign_multisig <filename></source> - <translation type="unfinished"></translation> + <translation>sign_multisig <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1844"/> <source>Sign a multisig transaction from a file</source> - <translation type="unfinished"></translation> + <translation>Signera en a multisig-transaktion från en fil</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1847"/> <source>submit_multisig <filename></source> - <translation type="unfinished"></translation> + <translation>submit_multisig <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1848"/> <source>Submit a signed multisig transaction from a file</source> - <translation type="unfinished"></translation> + <translation>Skicka en signerad multisig-transaktion från en fil</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1851"/> <source>export_raw_multisig_tx <filename></source> - <translation type="unfinished"></translation> + <translation>export_raw_multisig_tx <filnamn></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1852"/> <source>Export a signed multisig transaction to a file</source> - <translation type="unfinished"></translation> + <translation>Exportera en signerad multisig-transaktion till en fil</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> <source>help [<command>]</source> - <translation type="unfinished"></translation> + <translation>help [<kommando>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> <source>Show the help section or the documentation about a <command>.</source> - <translation type="unfinished"></translation> + <translation>Visa hjälpavsnittet eller dokumentationen för <kommando>.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1917"/> <source>integer >= </source> - <translation type="unfinished"></translation> + <translation>heltal >= </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1930"/> <source>block height</source> - <translation type="unfinished"></translation> + <translation>blockhöjd</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2012"/> <source>No wallet found with that name. Confirm creation of new wallet named: </source> - <translation type="unfinished"></translation> + <translation>Ingen plånbok med det namnet kunde hittas. Bekräfta skapande av ny plånbok med namn: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name" and --generate-from-json="jsonfilename"</source> - <translation type="unfinished"></translation> + <translation>det går inte att ange fler än en av --generate-new-wallet="plånboksnamn", --wallet-file="plånboksnamn", --generate-from-view-key="plånboksnamn", --generate-from-spend-key="plånboksnamn", --generate-from-keys="plånboksnamn", --generate-from-multisig-keys="plånboksnamn" och --generate-from-json="json-filnamn"</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2084"/> <source>can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic</source> - <translation type="unfinished"></translation> + <translation>det går inte att ange både --restore-deterministic-wallet eller --restore-multisig-wallet och --non-deterministic</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2090"/> <source>--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file</source> - <translation type="unfinished"></translation> + <translation>--restore-multisig-wallet använder --generate-new-wallet, inte --wallet-file</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> <source>specify a recovery parameter with the --electrum-seed="multisig seed here"</source> - <translation type="unfinished"></translation> + <translation>ange en återställningsparameter med --electrum-seed="startvärde för multisig"</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2133"/> <source>Multisig seed failed verification</source> - <translation type="unfinished"></translation> + <translation>Startvärde för multisig kunde inte verifieras</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2149"/> <source>Enter seed encryption passphrase, empty if none</source> - <translation type="unfinished"></translation> + <translation>Ange lösenfras för kryptering av startvärde, lämna tomt om ingen</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2185"/> <location filename="../src/simplewallet/simplewallet.cpp" line="2259"/> <source>This address is a subaddress which cannot be used here.</source> - <translation type="unfinished"></translation> + <translation>Denna adress är en underadress som inte kan användas här.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2337"/> <source>Error: expected M/N, but got: </source> - <translation type="unfinished"></translation> + <translation>Fel: förväntade M/N, men fick: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2342"/> <source>Error: expected N > 1 and N <= M, but got: </source> - <translation type="unfinished"></translation> + <translation>Fel: förväntade N > 1 och N <= M, men fick: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2347"/> <source>Error: M/N is currently unsupported. </source> - <translation type="unfinished"></translation> + <translation>Fel: M/N stöds för närvarande inte. </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2350"/> <source>Generating master wallet from %u of %u multisig wallet keys</source> - <translation type="unfinished"></translation> + <translation>Skapar huvudplånbok från %u av %u multisig-plånboksnycklar</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2379"/> <source>failed to parse secret view key</source> - <translation type="unfinished">det gick inte att parsa hemlig visningsnyckel</translation> + <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2388"/> <source>failed to verify secret view key</source> - <translation type="unfinished">det gick inte att verifiera hemlig visningsnyckel</translation> + <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2408"/> <source>Secret spend key (%u of %u):</source> - <translation type="unfinished"></translation> + <translation>Hemlig spendernyckel (%u av %u):</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> <source>Error: M/N is currently unsupported</source> - <translation type="unfinished"></translation> + <translation>Fel: M/N stöds för närvarande inte</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2550"/> <source>Restore height </source> - <translation type="unfinished"></translation> + <translation>Återställningshöjd </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2551"/> <source>Still apply restore height? (Y/Yes/N/No): </source> - <translation type="unfinished"></translation> + <translation>Ska återställningshöjd fortfarande appliceras? (J/Ja/N/Nej): </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2582"/> <source>Warning: using an untrusted daemon at %s, privacy will be lessened</source> - <translation type="unfinished"></translation> + <translation>Varning: använder en ej betrodd daemon på %s; sekretessen kommer att vara mindre</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or change the daemon address using the 'set_daemon' command.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2680"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2685"/> - <source>invalid language choice entered. Please try again. -</source> - <translation type="unfinished"></translation> + <translation>Antingen har daemonen inte startat eller så angavs fel port. Se till att daemonen körs eller byt daemonadress med kommandot 'set_daemon'.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2768"/> <source>Your wallet has been generated! To start synchronizing with the daemon, use the "refresh" command. Use the "help" command to see the list of available commands. -Use "help <command>" to see a command's documentation. +Use "help <command>" to see a command's documentation. Always use the "exit" command when closing monero-wallet-cli to save your current session's state. Otherwise, you might need to synchronize your wallet again (your wallet keys are NOT at risk in any case). </source> - <translation type="unfinished"></translation> + <translation>Din plånbok har skapats! +Använd kommandot "refresh" för att starta synkronisering med daemonen. +Använd kommandot "help" för att visa en lista över tillgängliga kommandon. +Använd "help <kommando>" för att visa dokumentation för kommandot. +Använd alltid kommandot "exit" när du stänger monero-wallet-cli så att ditt aktuella sessionstillstånd sparas. Annars kan du bli tvungen att synkronisera +din plånbok igen (din plånboks nycklar är dock INTE hotade i vilket fall som helst). +</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2850"/> <source>failed to generate new mutlisig wallet</source> - <translation type="unfinished"></translation> + <translation>det gick inte att skapa ny multisig-plånbok</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> <source>Generated new %u/%u multisig wallet: </source> - <translation type="unfinished"></translation> + <translation>Skapa ny %u/%u-multisig-plånbok: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> <source>Opened %u/%u multisig wallet%s</source> - <translation type="unfinished"></translation> + <translation>Öppnade %u/%u-multisig-plånbok%s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> - <source>Use "help <command>" to see a command's documentation. + <source>Use "help <command>" to see a command's documentation. </source> - <translation type="unfinished"></translation> + <translation>Använd "help <kommando>" för att visa dokumentation för kommandot. +</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3000"/> <source>wallet is multisig and cannot save a watch-only version</source> - <translation type="unfinished"></translation> + <translation>plånboken är multisig och kan inte spara en granskningsversion</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>missing daemon URL argument</source> - <translation type="unfinished"></translation> + <translation>argument för URL till daemon saknas</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3116"/> <source>Unexpected array length - Exited simple_wallet::set_daemon()</source> - <translation type="unfinished"></translation> + <translation>Oväntad matrislängd - Lämnade simple_wallet::set_daemon()</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3130"/> <source>This does not seem to be a valid daemon URL.</source> - <translation type="unfinished"></translation> + <translation>Detta verkar inte vara en giltig daemon-URL.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <location filename="../src/simplewallet/simplewallet.cpp" line="3184"/> <source>txid </source> - <translation type="unfinished"></translation> + <translation>txid </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3168"/> <location filename="../src/simplewallet/simplewallet.cpp" line="3186"/> <source>idx </source> - <translation type="unfinished"></translation> + <translation>idx </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3299"/> <source> (Some owned outputs have partial key images - import_multisig_info needed)</source> - <translation type="unfinished"></translation> + <translation> (Några ägda utgångar har partiella nyckelavbildningar - import_multisig_info krävs)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> <source>Currently selected account: [</source> - <translation type="unfinished"></translation> + <translation>Aktuellt valt konto: [</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> <source>] </source> - <translation type="unfinished"></translation> + <translation>] </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> <source>Tag: </source> - <translation type="unfinished"></translation> + <translation>Tagg: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> <source>(No tag assigned)</source> - <translation type="unfinished"></translation> + <translation>(Ingen tagg tilldelad)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3309"/> <source>Balance per address:</source> - <translation type="unfinished"></translation> + <translation>Saldo per adress:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <source>Address</source> - <translation type="unfinished"></translation> + <translation>Adress</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> <source>Balance</source> - <translation type="unfinished"></translation> + <translation>Saldo</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> <source>Unlocked balance</source> - <translation type="unfinished"></translation> + <translation>Upplåst saldo</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <source>Outputs</source> - <translation type="unfinished"></translation> + <translation>Utgångar</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> <source>Label</source> - <translation type="unfinished"></translation> + <translation>Etikett</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3318"/> <source>%8u %6s %21s %21s %7u %21s</source> - <translation type="unfinished"></translation> + <translation>%8u %6s %21s %21s %7u %21s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3327"/> <source>usage: balance [detail]</source> - <translation type="unfinished"></translation> + <translation>användning: balance [detail]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> <location filename="../src/simplewallet/simplewallet.cpp" line="3381"/> <source>usage: incoming_transfers [available|unavailable] [verbose] [index=<N>]</source> - <translation type="unfinished"></translation> + <translation>användning: incoming_transfers [available|unavailable] [verbose] [index=<N>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> <source>spent</source> - <translation>spenderad</translation> + <translation>spenderat</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> @@ -2243,7 +2364,7 @@ your wallet again (your wallet keys are NOT at risk in any case). <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> <source>addr index</source> - <translation type="unfinished"></translation> + <translation>addr index</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> @@ -2261,20 +2382,9 @@ your wallet again (your wallet keys are NOT at risk in any case). <translation>Inga inkommande otillgängliga överföringar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> - <source>Transaction successfully saved to </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> - <source>, txid </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> - <source>Failed to save transaction to </source> - <translation type="unfinished"></translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="3442"/> + <source>expected at least one payment ID</source> + <translation>åtminstone ett betalnings-ID förväntades</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> @@ -2376,6 +2486,18 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <translation>, vilket kan bryta ringsignaturens anonymitet. Se till att detta är avsiktligt!</translation> </message> <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4184"/> + <source>Ring size must not be 0</source> + <translation>Ringstorlek för inte vara 0</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4196"/> + <source>ring size %u is too small, minimum is %u</source> + <translation>ringstorlek %uär för liten, minimum är %u</translation> + </message> + <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3724"/> <source>wrong number of arguments</source> <translation>fel antal argument</translation> @@ -2391,7 +2513,23 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <location filename="../src/simplewallet/simplewallet.cpp" line="3872"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> <source>No outputs found, or daemon is not ready</source> - <translation>Inga utgångar hittades, eller så är daemonen inte redo</translation> + <translation>Inga utgångar hittades, eller så är daemonen inte klar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> + <source>Transaction successfully saved to </source> + <translation>Transaktionen sparades till </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> + <source>, txid </source> + <translation>, txid </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> + <source>Failed to save transaction to </source> + <translation>Det gick inte att spara transaktion till </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4081"/> @@ -2419,12 +2557,12 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> <source>usage: show_transfer <txid></source> - <translation>användning: show_transfer <transaktions-ID></translation> + <translation>användning: show_transfer <txid></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6673"/> <source>Double spend seen on the network: this transaction may or may not end up being mined</source> - <translation type="unfinished"></translation> + <translation>En dubbelspendering upptäcktes på nätverket: denna transaktion kanske aldrig blir verifierad</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6708"/> @@ -2445,13 +2583,13 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <location filename="../src/simplewallet/simplewallet.cpp" line="541"/> <location filename="../src/simplewallet/simplewallet.cpp" line="608"/> <source>wallet is watch-only and has no seed</source> - <translation>plånboken är enbart för granskning och saknar frö</translation> + <translation>plånboken är enbart för granskning och har inget startvärde</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="557"/> <location filename="../src/simplewallet/simplewallet.cpp" line="613"/> <source>wallet is non-deterministic and has no seed</source> - <translation>plånboken är icke-deterministisk och saknar frö</translation> + <translation>plånboken är icke-deterministisk och har inget startvärde</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1226"/> @@ -2462,7 +2600,7 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> <source>could not change default priority</source> - <translation>Det gick inte att ändra standardinställning för prioritet</translation> + <translation>det gick inte att ändra standardinställning för prioritet</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1919"/> @@ -2487,7 +2625,7 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1998"/> <source>Key file found but not wallet file. Regenerating...</source> - <translation>Nyckelfil hittades men inte plånboksfilen. Återskapar …</translation> + <translation>Nyckelfilen hittades men inte plånboksfilen. Återskapar …</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2004"/> @@ -2502,7 +2640,7 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2141"/> <source>Electrum-style word list failed verification</source> - <translation>det gick inte att verifiera ordlista av Electrum-typ</translation> + <translation>Det gick inte att verifiera ordlista av Electrum-typ</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2174"/> @@ -2516,7 +2654,7 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <location filename="../src/simplewallet/simplewallet.cpp" line="2373"/> <location filename="../src/simplewallet/simplewallet.cpp" line="2413"/> <source>No data supplied, cancelled</source> - <translation>Ingen data angiven, avbryter</translation> + <translation>Inga data angivna, avbryter</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2180"/> @@ -2538,20 +2676,20 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> <location filename="../src/simplewallet/simplewallet.cpp" line="2290"/> <source>failed to parse view key secret key</source> - <translation>det gick inte att parsa hemlig visningsnyckel</translation> + <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2210"/> <location filename="../src/simplewallet/simplewallet.cpp" line="2308"/> <source>failed to verify view key secret key</source> - <translation>det gick inte att verifiera hemlig visningsnyckel</translation> + <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2214"/> <location filename="../src/simplewallet/simplewallet.cpp" line="2312"/> <location filename="../src/simplewallet/simplewallet.cpp" line="2393"/> <source>view key does not match standard address</source> - <translation>visningsnyckel matchar inte standardadress</translation> + <translation>granskningsnyckel matchar inte standardadress</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2219"/> @@ -2596,14 +2734,22 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <translation>plånbok är null</translation> </message> <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2680"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2685"/> + <source>invalid language choice entered. Please try again. +</source> + <translation>ogiltigt språkval har angivits. Försök igen. +</translation> + </message> + <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2753"/> <source>View key: </source> - <translation>Visningsnyckel: </translation> + <translation>Granskningsnyckel: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2935"/> <source>You may want to remove the file "%s" and try again</source> - <translation>Du kan också vilja ta bort filen "%s" och försöka igen</translation> + <translation>Du kan också prova att bort filen "%s" och försöka igen</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2963"/> @@ -2647,7 +2793,7 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> <source>pubkey</source> - <translation>öppen nyckel</translation> + <translation>publik nyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> @@ -2691,19 +2837,14 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <translation>-</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3442"/> - <source>expected at least one payment ID</source> - <translation type="unfinished"></translation> - </message> - <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> - <translation>betalnings-ID har ogiltigt format, en 16- eller 64-teckens hex-sträng förväntades: </translation> + <translation>betalnings-ID har ogiltigt format. En hexadecimal sträng med 16 eller 64 tecken förväntades: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3546"/> <source>failed to get spent status</source> - <translation>det gick inte att hämta spenderingsstatus</translation> + <translation>det gick inte att hämta spenderstatus</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> @@ -2716,18 +2857,6 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <translation>block som ligger väldigt nära varandra i tiden</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4184"/> - <source>Ring size must not be 0</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4196"/> - <source>ring size %u is too small, minimum is %u</source> - <translation type="unfinished"></translation> - </message> - <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3778"/> <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> <translation>Låsta block för högt, max 1000000 (˜~4 år)</translation> @@ -2736,14 +2865,14 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <location filename="../src/simplewallet/simplewallet.cpp" line="5077"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5188"/> <source>Good signature</source> - <translation>Bra signatur</translation> + <translation>Godkänd signatur</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5104"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5190"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> <source>Bad signature</source> - <translation>Dålig signatur</translation> + <translation>Felaktig signatur</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6046"/> @@ -2763,7 +2892,7 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6098"/> <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation>användning: address_book [(add (<adress> [pid <långt eller kort betalnings-ID>])|<Integrerad adress> [<beskrivning eventuellt med blanktecken>])|(delete <index>)]</translation> + <translation>användning: address_book [(add (<adress> [pid <långt eller kort betalnings-ID>])|<integrerad adress> [<beskrivning eventuellt med blanktecken>])|(delete <index>)]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6128"/> @@ -2805,7 +2934,7 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> <source>usage: set_tx_note [txid] free text note</source> - <translation>användning: set_tx_note [txid] fri textanteckning</translation> + <translation>användning: set_tx_note [txid] fritextanteckning</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6201"/> @@ -2833,89 +2962,89 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5039"/> <source>usage: check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> + <translation>användning: check_tx_proof <txid> <adress> <signaturfil> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5066"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5181"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5278"/> <source>failed to load signature file</source> - <translation type="unfinished"></translation> + <translation>det gick inte att läsa in signaturfil</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5117"/> <source>usage: get_spend_proof <txid> [<message>]</source> - <translation type="unfinished"></translation> + <translation>användning: get_spend_proof <txid> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5123"/> <source>wallet is watch-only and cannot generate the proof</source> - <translation type="unfinished"></translation> + <translation>plånboken är enbart för granskning och kan inte skapa beviset</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5161"/> <source>usage: check_spend_proof <txid> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> + <translation>användning: check_spend_proof <txid> <signaturfil> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5202"/> <source>usage: get_reserve_proof (all|<amount>) [<message>]</source> - <translation type="unfinished"></translation> + <translation>användning: get_reserve_proof (all|<belopp>) [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5208"/> <source>The reserve proof can be generated only by a full wallet</source> - <translation type="unfinished"></translation> + <translation>Beviset på reserv kan endast skapas av en standardplånbok</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5253"/> <source>usage: check_reserve_proof <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> + <translation>användning: check_reserve_proof <adress> <signaturfil> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5271"/> <source>Address must not be a subaddress</source> - <translation type="unfinished"></translation> + <translation>Adressen får inte vara en underadress</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5289"/> <source>Good signature -- total: %s, spent: %s, unspent: %s</source> - <translation type="unfinished"></translation> + <translation>Godkänd signatur -- summa: %s, spenderat: %s, ej spenderat: %s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5353"/> <source>usage: show_transfers [in|out|all|pending|failed] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation type="unfinished"></translation> + <translation>användning: show_transfers [in|out|all|pending|failed] [index=<N1>[, <N2>, …]] [<minhöjd> [<maxhöjd>]]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5490"/> <source>[Double spend seen on the network: this transaction may or may not end up being mined] </source> - <translation type="unfinished"></translation> + <translation>[En dubbelspendering upptäcktes på nätverket: denna transaktion kanske aldrig blir verifierad] </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5526"/> <source>usage: unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation type="unfinished"></translation> + <translation>användning: unspent_outputs [index=<N1>[, <N2>, …]] [<min_belopp> [<max_belopp>]]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5586"/> <source>There is no unspent output in the specified address</source> - <translation type="unfinished"></translation> + <translation>Det finns ingen ej spenderad utgång i den angivna adressen</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5699"/> <source> (no daemon)</source> - <translation type="unfinished"></translation> + <translation> (ingen daemon)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5701"/> <source> (out of sync)</source> - <translation type="unfinished"></translation> + <translation> (inte synkroniserad)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5758"/> <source>(Untitled account)</source> - <translation type="unfinished"></translation> + <translation>(Ej namngivet konto)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5771"/> @@ -2925,13 +3054,13 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> <location filename="../src/simplewallet/simplewallet.cpp" line="5990"/> <location filename="../src/simplewallet/simplewallet.cpp" line="6013"/> <source>failed to parse index: </source> - <translation type="unfinished"></translation> + <translation>det gick inte att parsa index: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5995"/> <source>specify an index between 0 and </source> - <translation type="unfinished"></translation> + <translation>ange ett index mellan 0 och </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5873"/> @@ -2939,169 +3068,178 @@ Varning: Några ingångsnycklar som spenderas kommer från </translation> account account new <label text with white spaces allowed> account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation type="unfinished"></translation> + account label <index> <label text with white spaces allowed> + account tag <tag_name> <account_index_1> [<account_index_2> ...] + account untag <account_index_1> [<account_index_2> ...] + account tag_description <tag_name> <description></source> + <translation>användning: + account + account new <etikettext med blanktecken tillåtna> + account switch <index> + account label <index> <etikettext med blanktecken tillåtna> + account tag <taggnamn> <kontoindex_1> [<kontoindex_2> …] + account untag <kontoindex_1> [<kontoindex_2> …] + account tag_description <taggnamn> <beskrivning></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> <source> Grand total: Balance: </source> - <translation type="unfinished"></translation> + <translation> +Totalsumma: + Saldo: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> <source>, unlocked balance: </source> - <translation type="unfinished"></translation> + <translation>, upplåst saldo: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5909"/> <source>Untagged accounts:</source> - <translation type="unfinished"></translation> + <translation>Otaggade konton:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5915"/> <source>Tag %s is unregistered.</source> - <translation type="unfinished"></translation> + <translation>Taggen %s har inte registrerats.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5918"/> <source>Accounts with tag: </source> - <translation type="unfinished"></translation> + <translation>Konton med tagg: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> <source>Tag's description: </source> - <translation type="unfinished"></translation> + <translation>Taggens beskrivning: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> <source>Account</source> - <translation type="unfinished"></translation> + <translation>Konto</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5927"/> <source> %c%8u %6s %21s %21s %21s</source> - <translation type="unfinished"></translation> + <translation> %c%8u %6s %21s %21s %21s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5937"/> <source>----------------------------------------------------------------------------------</source> - <translation type="unfinished"></translation> + <translation>----------------------------------------------------------------------------------</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5938"/> <source>%15s %21s %21s</source> - <translation type="unfinished"></translation> + <translation>%15s %21s %21s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> <source>Primary address</source> - <translation type="unfinished"></translation> + <translation>Primär adress</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> <source>(used)</source> - <translation type="unfinished"></translation> + <translation>(används)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5982"/> <source>(Untitled address)</source> - <translation type="unfinished"></translation> + <translation>(Ej namngiven adress)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6022"/> <source><index_min> is already out of bound</source> - <translation type="unfinished"></translation> + <translation><index_min> är redan utanför tillåtet intervall</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6027"/> <source><index_max> exceeds the bound</source> - <translation type="unfinished"></translation> + <translation><index_max> är utanför tillåtet intervall</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6035"/> <source>usage: address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed> ]</source> - <translation type="unfinished"></translation> + <translation>användning: address [new <etikettext med blanktecken tillåtna> | all | <index_min> [<index_max>] | label <index> <etikettext med blanktecken tillåtna>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6053"/> <location filename="../src/simplewallet/simplewallet.cpp" line="6065"/> <source>Integrated addresses can only be created for account 0</source> - <translation type="unfinished"></translation> + <translation>Integrerade adresser kan bara skapas för konto 0</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6077"/> <source>Integrated address: %s, payment ID: %s</source> - <translation type="unfinished"></translation> + <translation>Integrerad adress: %s, betalnings-ID: %s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> <source>Subaddress: </source> - <translation type="unfinished"></translation> + <translation>Underadress: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6242"/> <source>usage: get_description</source> - <translation type="unfinished"></translation> + <translation>användning: get_description</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6248"/> <source>no description found</source> - <translation type="unfinished"></translation> + <translation>ingen beskrivning hittades</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6250"/> <source>description found: </source> - <translation type="unfinished"></translation> + <translation>beskrivning hittades: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6285"/> <source>Filename: </source> - <translation type="unfinished"></translation> + <translation>Filnamn: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> <source>Watch only</source> - <translation type="unfinished"></translation> + <translation>Endast granskning</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6292"/> <source>%u/%u multisig%s</source> - <translation type="unfinished"></translation> + <translation>%u/%u multisig%s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6294"/> <source>Normal</source> - <translation type="unfinished"></translation> + <translation>Normal</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> <source>Type: </source> - <translation type="unfinished"></translation> + <translation>Typ: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> <source>Testnet: </source> - <translation type="unfinished"></translation> + <translation>Testnet: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> <source>Yes</source> - <translation type="unfinished"></translation> + <translation>Ja</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> <source>No</source> - <translation type="unfinished"></translation> + <translation>Nej</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6314"/> <source>This wallet is multisig and cannot sign</source> - <translation type="unfinished"></translation> + <translation>Plånboken är multisig och kan inte signera</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6335"/> @@ -3111,12 +3249,12 @@ Grand total: <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6360"/> <source>Bad signature from </source> - <translation>Dålig signatur från </translation> + <translation>Felaktig signatur från </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6364"/> <source>Good signature from </source> - <translation>Bra signatur från </translation> + <translation>Godkänd signatur från </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6373"/> @@ -3186,7 +3324,7 @@ Grand total: <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4716"/> <source>Change goes to more than one address</source> - <translation>Växel går till mer än en adress</translation> + <translation>Växel går till fler än en adress</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4757"/> @@ -3206,79 +3344,9 @@ Grand total: <translation>Transaktionen signerades till fil </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4424"/> - <source>failed to parse Payment ID</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4440"/> - <source>usage: sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4447"/> - <source>failed to parse key image</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4499"/> - <source>No outputs found</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4504"/> - <source>Multiple transactions are created, which is not supposed to happen</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> - <source>The transaction uses multiple or no inputs, which is not supposed to happen</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4586"/> - <source>missing threshold amount</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4601"/> - <source>donations are not enabled on the testnet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> - <source>usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4748"/> - <source> dummy output(s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4763"/> - <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> - <source>This is a multisig wallet, it can only sign with sign_multisig</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4797"/> - <source>usage: sign_transfer [export]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4836"/> - <source>Transaction raw hex data exported to </source> - <translation type="unfinished"></translation> - </message> - <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4876"/> <source>usage: get_tx_key <txid></source> - <translation>användning: get_tx_key <transaktions-ID></translation> + <translation>användning: get_tx_key <txid></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4884"/> @@ -3291,7 +3359,7 @@ Grand total: <location filename="../src/simplewallet/simplewallet.cpp" line="6208"/> <location filename="../src/simplewallet/simplewallet.cpp" line="6578"/> <source>failed to parse txid</source> - <translation>det gick inte att parsa transaktions-id</translation> + <translation>det gick inte att parsa txid</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4898"/> @@ -3306,21 +3374,21 @@ Grand total: <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4912"/> <source>usage: get_tx_proof <txid> <address> [<message>]</source> - <translation type="unfinished"></translation> + <translation>användning: get_tx_proof <txid> <adress> [<meddelande>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4937"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5147"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5239"/> <source>signature file saved to: </source> - <translation type="unfinished"></translation> + <translation>signaturfilen sparades till: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4939"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5149"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5241"/> <source>failed to save signature file</source> - <translation type="unfinished"></translation> + <translation>det gick inte att spara signaturfilen</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4953"/> @@ -3331,7 +3399,7 @@ Grand total: <location filename="../src/simplewallet/simplewallet.cpp" line="4976"/> <location filename="../src/simplewallet/simplewallet.cpp" line="4985"/> <source>failed to parse tx key</source> - <translation>det gick inte att parsa transaktionsnyckeln</translation> + <translation>det gick inte att parsa txnyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4943"/> @@ -3350,13 +3418,13 @@ Grand total: <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> <source>in txid</source> - <translation>i transaktions-id</translation> + <translation>i txid</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5026"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5099"/> <source>received nothing in txid</source> - <translation>tog emot ingenting i transaktions-id</translation> + <translation>tog emot ingenting i txid</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5010"/> @@ -3368,23 +3436,23 @@ Grand total: <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5089"/> <source>This transaction has %u confirmations</source> - <translation>Transaktionen har %u bekräftelser</translation> + <translation>Denna transaktion har %u bekräftelser</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5020"/> <location filename="../src/simplewallet/simplewallet.cpp" line="5093"/> <source>WARNING: failed to determine number of confirmations!</source> - <translation>VARNING: det gick inte att avgöra antal bekräftelser!</translation> + <translation>VARNING: det gick inte att bestämma antal bekräftelser!</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5401"/> <source>bad min_height parameter:</source> - <translation>dålig parameter för min_height:</translation> + <translation>felaktig parameter för min_höjd:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5413"/> <source>bad max_height parameter:</source> - <translation>dålig parameter för max_height:</translation> + <translation>felaktig parameter för max_höjd:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> @@ -3405,7 +3473,7 @@ Grand total: <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> <source>pending</source> - <translation>väntar</translation> + <translation>väntande</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5560"/> @@ -3499,9 +3567,9 @@ Utgångar per *: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> - <source>+--> block height + <source>+--> block height </source> - <translation>+--> blockhöjd + <translation>+--> blockhöjd </translation> </message> <message> @@ -3543,83 +3611,83 @@ Utgångar per *: </translation> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="70"/> <source>Base filename (-1, -2, etc suffixes will be appended as needed)</source> - <translation type="unfinished"></translation> + <translation>Basfilnamn (suffix -1, -2, osv. läggs till efter behov)</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="71"/> <source>Give threshold and participants at once as M/N</source> - <translation type="unfinished"></translation> + <translation>Ange tröskelvärde och deltagare på en gång som M/N</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="72"/> <source>How many participants wil share parts of the multisig wallet</source> - <translation type="unfinished"></translation> + <translation>Hur många deltagare kommer att dela delar av multisig-plånboken</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="73"/> <source>How many signers are required to sign a valid transaction</source> - <translation type="unfinished"></translation> + <translation>Hur många signerare krävs för att signera en giltig transaktion</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="74"/> <source>Create testnet multisig wallets</source> - <translation type="unfinished"></translation> + <translation>Skapa multisig-plånböcker för testnet</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="81"/> <source>Generating %u %u/%u multisig wallets</source> - <translation type="unfinished"></translation> + <translation>Skapar %u %u/%u multisig-plånböcker</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="138"/> <source>Error verifying multisig extra info</source> - <translation type="unfinished"></translation> + <translation>Ett fel uppstod när extra multisig-info verifierades</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="146"/> <source>Error finalizing multisig</source> - <translation type="unfinished"></translation> + <translation>Ett fel uppstod vid slutförande av multisig</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="153"/> <source>Generated multisig wallets for address </source> - <translation type="unfinished"></translation> + <translation>Skapade multisig-plånböcker för adress </translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="157"/> <source>Error creating multisig wallets: </source> - <translation type="unfinished"></translation> + <translation>Ett fel uppstod när multisig-plånböcker skapades: </translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="176"/> <source>This program generates a set of multisig wallets - use this simpler scheme only if all the participants trust each other</source> - <translation type="unfinished"></translation> + <translation>Programmet skapar en uppsättning multisig-plånböcker - använd endast detta enklare system om alla deltagare litar på varandra</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="194"/> <source>Error: expected N/M, but got: </source> - <translation type="unfinished"></translation> + <translation>Fel: förväntade N/M, men fick: </translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="202"/> <location filename="../src/gen_multisig/gen_multisig.cpp" line="211"/> <source>Error: either --scheme or both of --threshold and --participants may be given</source> - <translation type="unfinished"></translation> + <translation>Fel: antingen --scheme eller både --threshold och --participants får anges</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="218"/> <source>Error: expected N > 1 and N <= M, but got N==%u and M==%d</source> - <translation type="unfinished"></translation> + <translation>Fel: förväntade N > 1 och N <= M, men fick N=%u och M=%d</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="227"/> <source>Error: --filename-base is required</source> - <translation type="unfinished"></translation> + <translation>Fel: --filename-base måste anges</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="233"/> <source>Error: unsupported scheme: only N/N and N-1/N are supported</source> - <translation type="unfinished"></translation> + <translation>Fel: systemet stöds inte: bara N/N och N-1/N stöds</translation> </message> </context> <context> @@ -3632,12 +3700,12 @@ Utgångar per *: </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> <source>Generate incoming-only wallet from view key</source> - <translation>Skapa granskningsplånbok från visningsnyckel</translation> + <translation>Skapa granskningsplånbok från granskningsnyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> <source>Generate deterministic wallet from spend key</source> - <translation type="unfinished"></translation> + <translation>Skapa deterministisk plånbok från spendernyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> @@ -3647,32 +3715,32 @@ Utgångar per *: </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="119"/> <source>Generate a master wallet from multisig wallet keys</source> - <translation type="unfinished"></translation> + <translation>Skapa en huvudplånbok från multisig-plånboksnycklar</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> <source>Language for mnemonic</source> - <translation type="unfinished"></translation> + <translation>Språk för minnesbaserat startvärde</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> <source>Specify Electrum seed for wallet recovery/creation</source> - <translation>Ange Electrum-frö för att återställa/skapa plånbok</translation> + <translation>Ange Electrum-startvärde för att återställa/skapa plånbok</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> <source>Recover wallet using Electrum-style mnemonic seed</source> - <translation>Återställ plånbok genom användning av minnesfrö (Electrum-typ)</translation> + <translation>Återställ plånbok genom att använda minnesbaserat startvärde (Electrum-typ)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> <source>Recover multisig wallet using Electrum-style mnemonic seed</source> - <translation type="unfinished"></translation> + <translation>Återställ multisig-plånbok genom att använda minnesbaserat startvärde (Electrum-typ)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Generate non-deterministic view and spend keys</source> - <translation>Skapa non-deterministic visnings- och spendernyckel</translation> + <translation>Skapa icke-deterministisk granskningsnyckel och spendernyckel</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> @@ -3692,7 +3760,7 @@ Utgångar per *: </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> <source>The newly created transaction will not be relayed to the monero network</source> - <translation type="unfinished"></translation> + <translation>Den nyss skapade transaktionen kommer inte att skickas vidare till monero-nätverket</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="171"/> @@ -3702,7 +3770,7 @@ Utgångar per *: </translation> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="180"/> <source>possibly lost connection to daemon</source> - <translation>anslutning till daemonen kan ha tappats</translation> + <translation>anslutning till daemonen kan ha förlorats</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="197"/> @@ -3713,7 +3781,8 @@ Utgångar per *: </translation> <location filename="../src/simplewallet/simplewallet.cpp" line="6787"/> <source>This is the command line monero wallet. It needs to connect to a monero daemon to work correctly.</source> - <translation type="unfinished"></translation> + <translation>Detta är kommandoradsplånboken för Monero. Den måste ansluta till en Monero- +daemon för att fungera korrekt.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="6801"/> @@ -3726,12 +3795,12 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="113"/> <source>Use daemon instance at <host>:<port></source> - <translation>Använd daemoninstans på <värddator>:<port></translation> + <translation>Använd daemonen på <värddator>:<port></translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="114"/> <source>Use daemon instance at host <arg> instead of localhost</source> - <translation>Använd daemon-instansen på värddator <arg> istället för localhost</translation> + <translation>Använd daemonen på värddatorn <arg> istället för localhost</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="116"/> @@ -3741,7 +3810,7 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="117"/> <source>Use daemon instance at port <arg> instead of 18081</source> - <translation>Använd daemon-instansen på port <arg> istället för 18081</translation> + <translation>Använd daemonen på port <arg> istället för 18081</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="119"/> @@ -3761,7 +3830,7 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="204"/> <source>can't specify more than one of --password and --password-file</source> - <translation>det går inte att ange mer än en av --password och --password-file</translation> + <translation>det går inte att ange fler än en av --password och --password-file</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="217"/> @@ -3786,7 +3855,7 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="224"/> <source>no password specified; use --prompt-for-password to prompt for a password</source> - <translation type="unfinished"></translation> + <translation>inget lösenord har angivits; använd --prompt-for-password för att fråga efter lösenord</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="246"/> @@ -3801,14 +3870,14 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="269"/> <source>failed to parse view key secret key</source> - <translation>det gick inte att parsa hemlig visningsnyckel</translation> + <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="274"/> <location filename="../src/wallet/wallet2.cpp" line="339"/> <location filename="../src/wallet/wallet2.cpp" line="380"/> <source>failed to verify view key secret key</source> - <translation>det gick inte att verifiera hemlig visningsnyckel</translation> + <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="285"/> @@ -3825,12 +3894,12 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="302"/> <source>Electrum-style word list failed verification</source> - <translation>det gick inte att verifiera ordlista av Electrum-typ</translation> + <translation>Det gick inte att verifiera ordlista av Electrum-typ</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="319"/> <source>At least one of Electrum-style word list and private view key and private spend key must be specified</source> - <translation type="unfinished"></translation> + <translation>Åtminstone en av ordlista av Electrum-typ och privat granskningsnyckel och privat spendernyckel måste anges</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="323"/> @@ -3845,7 +3914,7 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="342"/> <source>view key does not match standard address</source> - <translation>visningsnyckel matchar inte standardadress</translation> + <translation>granskningsnyckel matchar inte standardadress</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="352"/> @@ -3860,12 +3929,12 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet2.cpp" line="392"/> <source>failed to parse address: </source> - <translation type="unfinished"></translation> + <translation>det gick inte att parsa adressen: </translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="398"/> <source>Address must be specified in order to create watch-only wallet</source> - <translation type="unfinished"></translation> + <translation>Adress måste anges för att kunna skapa granskningsplånbok</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="413"/> @@ -3882,12 +3951,12 @@ daemon to work correctly.</source> <location filename="../src/wallet/wallet2.cpp" line="3599"/> <location filename="../src/wallet/wallet2.cpp" line="3955"/> <source>Primary account</source> - <translation type="unfinished"></translation> + <translation>Primärt konto</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="7914"/> <source>No funds received in this tx.</source> - <translation type="unfinished"></translation> + <translation>Inga pengar togs emot i denna tx.</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="8607"/> @@ -3905,12 +3974,12 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="175"/> <source>Failed to create directory </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att skapa mapp </translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="177"/> <source>Failed to create directory %s: %s</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att skapa mapp %s: %s</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> @@ -3935,7 +4004,7 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="217"/> <source>Error writing to file </source> - <translation>Fel vid skrivning till fil </translation> + <translation>Ett fel uppstod vid skrivning till fil </translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="220"/> @@ -3945,23 +4014,24 @@ daemon to work correctly.</source> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="443"/> <source>Tag %s is unregistered.</source> - <translation type="unfinished"></translation> + <translation>Taggen %s har inte registrerats.</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2435"/> <source>Transaction not possible. Available only %s, transaction amount %s = %s + %s (fee)</source> - <translation type="unfinished"></translation> + <translation>Transaktion är inte möjlig. Endast tillgängligt %s, transaktionsbelopp %s = %s + %s (avgift)</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2870"/> <source>This is the RPC monero wallet. It needs to connect to a monero daemon to work correctly.</source> - <translation type="unfinished"></translation> + <translation>Detta är RPC-plånboken för monero. Den måste ansluta till en Monero- +daemon för att fungera korrekt.</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2893"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> - <translation>Det går inte att ange mer än en av --wallet-file och --generate-from-json</translation> + <translation>Det går inte att ange fler än en av --wallet-file och --generate-from-json</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2905"/> @@ -3977,48 +4047,48 @@ daemon to work correctly.</source> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2942"/> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2975"/> <source>Saving wallet...</source> - <translation type="unfinished"></translation> + <translation>Sparar plånbok …</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2944"/> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2977"/> <source>Successfully saved</source> - <translation type="unfinished"></translation> + <translation>Plånboken sparades</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2947"/> <source>Successfully loaded</source> - <translation type="unfinished"></translation> + <translation>Plånboken lästes in</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2951"/> + <source>Wallet initialization failed: </source> + <translation>Det gick inte att initiera plånbok: </translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2958"/> <source>Failed to initialize wallet RPC server</source> - <translation type="unfinished"></translation> + <translation>Det gick inte att initiera RPC-servern för plånbok</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2962"/> <source>Starting wallet RPC server</source> - <translation type="unfinished"></translation> + <translation>Startar RPC-server för plånboken</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2969"/> <source>Failed to run wallet: </source> - <translation type="unfinished"></translation> + <translation>Det gick inte att köra plånboken: </translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2972"/> <source>Stopped wallet RPC server</source> - <translation type="unfinished"></translation> + <translation>Stoppade RPC-server för plånboken</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="2981"/> <source>Failed to save wallet: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2951"/> - <source>Wallet initialization failed: </source> - <translation>Det gick inte att initiera plånbok: </translation> + <translation>Det gick inte spara plånboken: </translation> </message> </context> <context> @@ -4064,7 +4134,8 @@ daemon to work correctly.</source> <location filename="../src/wallet/wallet_args.cpp" line="138"/> <source>This is the command line monero wallet. It needs to connect to a monero daemon to work correctly.</source> - <translation type="unfinished"></translation> + <translation>Detta är kommandoradsplånboken för Monero. Den måste ansluta till en Monero- +daemon för att fungera korrekt.</translation> </message> <message> <location filename="../src/wallet/wallet_args.cpp" line="161"/> diff --git a/utils/systemd/monerod.service b/utils/systemd/monerod.service index 696be4c33..5f37e54b2 100644 --- a/utils/systemd/monerod.service +++ b/utils/systemd/monerod.service @@ -8,12 +8,28 @@ Group=monero WorkingDirectory=~ RuntimeDirectory=monero +# Clearnet config +# Type=forking PIDFile=/run/monero/monerod.pid - ExecStart=/usr/bin/monerod --config-file /etc/monerod.conf \ --detach --pidfile /run/monero/monerod.pid +# Tor config +# +## We have to use simple, not forking, because we cannot pass --detach +## because stderr/stdout is not available when detached, but torsocks +## attempts to write to it, and fails with 'invalid argument', causing +## monerod to fail. +#Type=simple +#Environment=DNS_PUBLIC=tcp +## The following is needed only when accessing wallet from a different +## host in the LAN, VPN, etc, the RPC must bind to 0.0.0.0, but +## by default torsocks only allows binding to localhost. +#Environment=TORSOCKS_ALLOW_INBOUND=1 +#ExecStart=/usr/bin/torsocks /usr/bin/monerod --config-file /etc/monerod.conf \ +# --non-interactive + Restart=always [Install] |