示例#1
0
        public bool testKeys(byte[] plain, IxianKeyPair key_pair)
        {
            Logging.info("Testing generated keys.");
            // Try if RSACryptoServiceProvider considers them a valid key
            if (rsaKeyFromBytes(key_pair.privateKeyBytes) == null)
            {
                Logging.warn("RSA key is considered invalid by RSACryptoServiceProvider!");
                return(false);
            }

            byte[] encrypted = encryptWithRSA(plain, key_pair.publicKeyBytes);
            byte[] signature = getSignature(plain, key_pair.privateKeyBytes);

            if (!decryptWithRSA(encrypted, key_pair.privateKeyBytes).SequenceEqual(plain))
            {
                Logging.warn(string.Format("Error decrypting data while testing keys."));
                return(false);
            }

            if (!verifySignature(plain, key_pair.publicKeyBytes, signature))
            {
                Logging.warn(string.Format("Error verifying signature while testing keys."));
                return(false);
            }


            return(true);
        }
示例#2
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);
            }
        }
示例#3
0
        // Generates keys for RSA signing
        public IxianKeyPair generateKeys(int keySize, bool skip_header = false)
        {
            try
            {
                IxianKeyPair             kp  = new IxianKeyPair();
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySize);
                kp.privateKeyBytes = rsaKeyToBytes(rsa, true, skip_header);
                kp.publicKeyBytes  = rsaKeyToBytes(rsa, false, skip_header);

                byte[] plain = Encoding.UTF8.GetBytes("Plain text string");
                if (!testKeys(plain, kp))
                {
                    return(null);
                }
                return(kp);
            }
            catch (Exception e)
            {
                Logging.warn(string.Format("Exception while generating signature keys: {0}", e.ToString()));
                return(null);
            }
        }
示例#4
0
 public bool testKeys(byte[] plaintext, IxianKeyPair kp)
 {
     return(_cryptoLib.testKeys(plaintext, kp));
 }
示例#5
0
        // Generate a new wallet with matching private/public key pairs
        public bool generateWallet(string password)
        {
            Logging.flush();

            walletVersion  = 2;
            walletPassword = password;

            Logging.log(LogSeverity.info, "Generating primary wallet keys, this may take a while, please wait...");

            //IxianKeyPair kp = generateNewKeyPair(false);
            IxianKeyPair kp = CryptoManager.lib.generateKeys(ConsensusConfig.defaultRsaKeySize);

            if (kp == null)
            {
                Logging.error("Error creating wallet, unable to generate a new keypair.");
                return(false);
            }

            privateKey = kp.privateKeyBytes;
            publicKey  = kp.publicKeyBytes;

            Address addr = new Address(publicKey);

            lastAddress = address = addr.address;

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

            kp.addressBytes = address;

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


            Logging.info(String.Format("Public Key: {0}", Crypto.hashToString(publicKey)));
            Logging.info(String.Format("Public Node Address: {0}", Base58Check.Base58CheckEncoding.EncodePlain(address)));

            // Wait for any pending log messages to be written
            Logging.flush();

            Console.WriteLine();
            Console.Write("Your IXIAN address is ");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(Base58Check.Base58CheckEncoding.EncodePlain(address));
            Console.ResetColor();
            Console.WriteLine();

            // Write the new wallet data to the file
            if (writeWallet(password))
            {
                backup();
                return(true);
            }
            return(false);
        }
示例#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, true);
                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, true);
                byte[] dec_public_key  = CryptoManager.lib.decryptWithPassword(enc_public_key, password, true);
                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, true);
                }

                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, true);

            return(true);
        }
示例#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, false);
                publicKey      = CryptoManager.lib.decryptWithPassword(b_publicKey, password, false);
                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, false);
                    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);
        }
示例#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, ConsensusConfig.defaultRsaKeySize, 65537);

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

            if (!IXICore.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);
        }