Beispiel #1
0
        public Address generateNewAddress_v1(Address key_primary_address, byte[] last_nonce, bool add_to_pool = true)
        {
            lock (myKeys)
            {
                if (!myKeys.ContainsKey(key_primary_address.address))
                {
                    return(null);
                }

                IxianKeyPair kp = myKeys[key_primary_address.address];

                byte[] base_nonce = Crypto.sha512sqTrunc(kp.privateKeyBytes, publicKey.Length, 64);

                if (last_nonce == null)
                {
                    last_nonce = kp.lastNonceBytes;
                }

                List <byte> new_nonce = base_nonce.ToList();
                if (last_nonce != null)
                {
                    new_nonce.AddRange(last_nonce);
                }
                byte[] new_nonce_bytes = Crypto.sha512sqTrunc(new_nonce.ToArray(), 0, 0, 16);

                Address new_address = new Address(key_primary_address.address, new_nonce_bytes);

                if (add_to_pool)
                {
                    kp.lastNonceBytes = new_nonce_bytes;
                    lock (myAddresses)
                    {
                        AddressData ad = new AddressData()
                        {
                            nonce = kp.lastNonceBytes, keyPair = kp
                        };
                        myAddresses.Add(new_address.address, ad);
                        lastAddress = new_address.address;
                    }
                }

                return(new_address);
            }
        }
Beispiel #2
0
 public SortedDictionary <byte[], IxiNumber> generateFromListFromAddress(byte[] from_address, IxiNumber total_amount_with_fee, bool full_pubkey = false)
 {
     lock (myAddresses)
     {
         SortedDictionary <byte[], IxiNumber> tmp_from_list = new SortedDictionary <byte[], IxiNumber>(new ByteArrayComparer());
         if (full_pubkey)
         {
             if (!myAddresses.ContainsKey(from_address))
             {
                 return(null);
             }
             AddressData ad = myAddresses[from_address];
             tmp_from_list.Add(ad.nonce, total_amount_with_fee);
         }
         else
         {
             tmp_from_list.Add(new byte[1] {
                 0
             }, total_amount_with_fee);
         }
         return(tmp_from_list);
     }
 }
Beispiel #3
0
        public static Transaction multisigChangeReqSigs(byte sigs, IxiNumber tx_fee, byte[] tx_from, ulong tx_blockHeight)
        {
            Transaction t = new Transaction((int)Transaction.Type.ChangeMultisigWallet, new IxiNumber(0), tx_fee, tx_from, tx_from, null, tx_from, tx_blockHeight);

            // TODO TODO TODO TODO TODO TODO make this compatible with wallet v3

            AddressData ad = findMyMultisigAddressData(tx_from);

            if (ad == null)
            {
                return(null);
            }

            t.AddMultisigChReqSigs(sigs, ad.keyPair.publicKeyBytes, ad.nonce);

            t.fee = t.calculateMinimumFee(tx_fee);
            t.fromList[t.fromList.First().Key] = t.fee;

            t.generateChecksums();

            t.signature = t.getSignature(t.checksum, ad.keyPair.privateKeyBytes);

            return(t);
        }
Beispiel #4
0
        public static Transaction multisigTransaction(IxiNumber tx_fee, SortedDictionary <byte[], IxiNumber> tx_to_list, byte[] tx_from, ulong tx_blockHeight)
        {
            Transaction t = new Transaction((int)Transaction.Type.MultisigTX, tx_fee, tx_to_list, tx_from, null, tx_from, tx_blockHeight);

            // TODO TODO TODO TODO TODO TODO make this compatible with wallet v3

            AddressData ad = findMyMultisigAddressData(tx_from);

            if (ad == null)
            {
                return(null);
            }

            t.AddMultisigOrig(null, ad.keyPair.publicKeyBytes, ad.nonce);

            t.fee = t.calculateMinimumFee(tx_fee);
            t.fromList[t.fromList.First().Key] = t.amount + t.fee;

            t.generateChecksums();

            t.signature = t.getSignature(t.checksum, ad.keyPair.privateKeyBytes);

            return(t);
        }
Beispiel #5
0
        public static AddressData findMyMultisigAddressData(byte[] multisig_address)
        {
            AddressData ad = Node.walletStorage.getAddress(multisig_address);

            if (ad != null)
            {
                return(ad);
            }

            Wallet w = Node.walletState.getWallet(multisig_address);

            if (w == null)
            {
                return(null);
            }

            if (w.allowedSigners != null)
            {
                foreach (var entry in w.allowedSigners)
                {
                    AddressData tmp_ad = Node.walletStorage.getAddress(entry);
                    if (tmp_ad != null)
                    {
                        return(tmp_ad);
                    }
                }
            }

            if (Config.isTestNet)
            {
                // exploit test
                return(Node.walletStorage.getAddress(Node.walletStorage.getPrimaryAddress()));
            }

            return(null);
        }
Beispiel #6
0
        protected bool readWallet_v3(BinaryReader reader, string password)
        {
            // Read the master seed
            int b_master_seed_length = reader.ReadInt32();

            byte[] b_master_seed = reader.ReadBytes(b_master_seed_length);

            try
            {
                // Decrypt
                masterSeed     = CryptoManager.lib.decryptWithPassword(b_master_seed, password);
                seedHash       = Crypto.sha512sqTrunc(masterSeed);
                walletPassword = password;
            }
            catch (Exception)
            {
                Logging.error(string.Format("Unable to decrypt wallet, an incorrect password was used."));
                Logging.flush();
                return(false);
            }

            int key_count = reader.ReadInt32();

            for (int i = 0; i < key_count; i++)
            {
                int len = reader.ReadInt32();
                if (reader.BaseStream.Position + len > reader.BaseStream.Length)
                {
                    Logging.error("Wallet file is corrupt, expected more data than available.");
                    break;
                }
                byte[] enc_private_key = reader.ReadBytes(len);

                len = reader.ReadInt32();
                if (reader.BaseStream.Position + len > reader.BaseStream.Length)
                {
                    Logging.error("Wallet file is corrupt, expected more data than available.");
                    break;
                }
                byte[] enc_public_key = reader.ReadBytes(len);

                len = reader.ReadInt32();
                if (reader.BaseStream.Position + len > reader.BaseStream.Length)
                {
                    Logging.error("Wallet file is corrupt, expected more data than available.");
                    break;
                }
                byte[] enc_nonce = null;
                if (len > 0)
                {
                    enc_nonce = reader.ReadBytes(len);
                }

                byte[] dec_private_key = CryptoManager.lib.decryptWithPassword(enc_private_key, password);
                byte[] dec_public_key  = CryptoManager.lib.decryptWithPassword(enc_public_key, password);
                byte[] tmp_address     = (new Address(dec_public_key)).address;

                IxianKeyPair kp = new IxianKeyPair();
                kp.privateKeyBytes = dec_private_key;
                kp.publicKeyBytes  = dec_public_key;
                kp.addressBytes    = tmp_address;
                if (enc_nonce != null)
                {
                    kp.lastNonceBytes = CryptoManager.lib.decryptWithPassword(enc_nonce, password);
                }

                if (privateKey == null)
                {
                    privateKey  = dec_private_key;
                    publicKey   = dec_public_key;
                    lastAddress = address = tmp_address;
                }

                lock (myKeys)
                {
                    myKeys.Add(tmp_address, kp);
                }
                lock (myAddresses)
                {
                    AddressData ad = new AddressData()
                    {
                        nonce = new byte[1] {
                            0
                        }, keyPair = kp
                    };
                    myAddresses.Add(tmp_address, ad);
                }
            }

            int seed_len = reader.ReadInt32();

            byte[] enc_derived_seed = reader.ReadBytes(seed_len);
            derivedMasterSeed = CryptoManager.lib.decryptWithPassword(enc_derived_seed, password);

            return(true);
        }
Beispiel #7
0
        protected bool readWallet_v1(BinaryReader reader, string password)
        {
            // Read the encrypted keys
            int b_privateKeyLength = reader.ReadInt32();

            byte[] b_privateKey = reader.ReadBytes(b_privateKeyLength);

            int b_publicKeyLength = reader.ReadInt32();

            byte[] b_publicKey = reader.ReadBytes(b_publicKeyLength);

            byte[] b_last_nonce = null;
            if (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                int b_last_nonceLength = reader.ReadInt32();
                b_last_nonce = reader.ReadBytes(b_last_nonceLength);
            }

            try
            {
                // Decrypt
                privateKey     = CryptoManager.lib.decryptWithPassword(b_privateKey, password);
                publicKey      = CryptoManager.lib.decryptWithPassword(b_publicKey, password);
                walletPassword = password;
            }
            catch (Exception)
            {
                Logging.error(string.Format("Unable to decrypt wallet, an incorrect password was used."));
                Logging.flush();
                return(false);
            }

            Address addr = new Address(publicKey);

            lastAddress = address = addr.address;

            masterSeed        = address;
            seedHash          = address;
            derivedMasterSeed = masterSeed;

            IxianKeyPair kp = new IxianKeyPair();

            kp.privateKeyBytes = privateKey;
            kp.publicKeyBytes  = publicKey;
            kp.addressBytes    = address;
            lock (myKeys)
            {
                myKeys.Add(address, kp);
            }
            lock (myAddresses)
            {
                AddressData ad = new AddressData()
                {
                    nonce = new byte[1] {
                        0
                    }, keyPair = kp
                };
                myAddresses.Add(address, ad);

                if (b_last_nonce != null)
                {
                    byte[] last_nonce_bytes   = CryptoManager.lib.decryptWithPassword(b_last_nonce, walletPassword);
                    bool   last_address_found = false;
                    while (last_address_found == false)
                    {
                        if (kp.lastNonceBytes != null && last_nonce_bytes.SequenceEqual(kp.lastNonceBytes))
                        {
                            last_address_found = true;
                        }
                        else
                        {
                            generateNewAddress(addr, null, true, false);
                        }
                    }
                }
            }
            return(true);
        }
Beispiel #8
0
        public IxianKeyPair generateNewKeyPair(bool writeToFile = true)
        {
            if (walletVersion < 3)
            {
                lock (myKeys)
                {
                    return(myKeys.First().Value);
                }
            }

            IXICore.CryptoKey.KeyDerivation kd = new IXICore.CryptoKey.KeyDerivation(masterSeed);

            int key_count = 0;

            lock (myKeys)
            {
                key_count = myKeys.Count();
            }

            IxianKeyPair kp = kd.deriveKey(key_count, CoreConfig.defaultRsaKeySize, 65537);

            if (kp == null)
            {
                Logging.error("An error occured generating new key pair, unable to derive key.");
                return(null);
            }

            if (!DLT.CryptoManager.lib.testKeys(Encoding.Unicode.GetBytes("TEST TEST"), kp))
            {
                Logging.error("An error occured while testing the newly generated keypair, unable to produce a valid address.");
                return(null);
            }
            Address addr = new Address(kp.publicKeyBytes);

            if (addr.address == null)
            {
                Logging.error("An error occured generating new key pair, unable to produce a valid address.");
                return(null);
            }
            lock (myKeys)
            {
                lock (myAddresses)
                {
                    if (!writeToFile)
                    {
                        myKeys.Add(addr.address, kp);
                        AddressData ad = new AddressData()
                        {
                            nonce = kp.lastNonceBytes, keyPair = kp
                        };
                        myAddresses.Add(addr.address, ad);
                    }
                    else
                    {
                        if (writeWallet(walletPassword))
                        {
                            myKeys.Add(addr.address, kp);
                            AddressData ad = new AddressData()
                            {
                                nonce = kp.lastNonceBytes, keyPair = kp
                            };
                            myAddresses.Add(addr.address, ad);
                        }
                        else
                        {
                            Logging.error("An error occured while writing wallet file.");
                            return(null);
                        }
                    }
                }
            }

            return(kp);
        }