Beispiel #1
0
 public Wallet(NetworkInfo networkInfo, byte[] address, byte[] privateKey, byte[] publicKey)
 {
     Trace.Assert(networkInfo != null);
     Trace.Assert(privateKey != null);
     Trace.Assert(publicKey != null);
     this.networkInfo = networkInfo;
     this.address     = address;
     this.privateKey  = privateKey;
     this.publicKey   = publicKey;
 }
Beispiel #2
0
 /// Creates a new [Wallet] instance based on the existent [wallet] for
 /// the given [networkInfo].
 public static Wallet convert(Wallet wallet, NetworkInfo networkInfo)
 {
     return(new Wallet(networkInfo: networkInfo, address: wallet.address, privateKey: wallet.privateKey, publicKey: wallet.publicKey));
 }
Beispiel #3
0
        // This are implented as static constructors to translate Dart factory

        /// Derives the private key from the given [mnemonic] using the specified
        /// [networkInfo].
        public static Wallet derive(List <String> mnemonic, NetworkInfo networkInfo, String lastDerivationPathSegment = "0")
        {
            Mnemonic bip39;

            // Get the mnemonic as a single concatenated string
            String mnemonicString = String.Join(' ', mnemonic);

            // Check the mnemonic
            try
            {
                bip39 = new Mnemonic(mnemonicString);
            }
            catch (ArgumentException e)
            {
                System.ArgumentException argEx = new System.ArgumentException($"Invalid mnemonic string - Exception ${e.Message} - '${mnemonicString}'");
                throw argEx;
            }
            // Get the seed - byte[]. !!!Note the empty password - OK!
            byte[] seed = bip39.DeriveSeed();
            // Using the seed in a BIP32 instance
            ExtKey root = new ExtKey(seed);
            // Check for correct lastDerivationPathSegment
            int  segValue  = -1;
            bool isNumeric = int.TryParse(lastDerivationPathSegment, out segValue);

            if ((isNumeric == false) || (segValue < 0))
            {
                // Exception - derivation path not valid!
                System.ArgumentException argEx = new System.ArgumentException($"Argument Exception - Invalid Derivation Path: '{lastDerivationPathSegment}'");
                throw argEx;
            }
            //  Create the Keypath - with the last Path Segment
            String  derivedPathString = $"{DERIVATION_PATH}/{lastDerivationPathSegment}";
            KeyPath derivationPath    = new KeyPath(derivedPathString);
            // Get the node
            ExtKey derivedNode = root.Derive(derivationPath);

            // Get the private key
            byte[] privateKey = derivedNode.PrivateKey.ToBytes();

            // Get the curve data
            X9ECParameters secp256k1 = ECNamedCurveTable.GetByName("secp256k1");
            ECPoint        point     = secp256k1.G;

            // Compute the curve point associated to the private key
            BigInteger bigInt     = new BigInteger(HexEncDec.ByteArrayToString(privateKey), (int)16);
            ECPoint    curvePoint = point.Multiply(bigInt);

            // Get the public key - Be Careful, this MUST be compressed format!!!
            byte[] publicKeyBytes = curvePoint.GetEncoded(true);

            // Get the address
            Sha256Digest sha256digest = new Sha256Digest();

            sha256digest.BlockUpdate(publicKeyBytes, 0, publicKeyBytes.Length);
            // byte[] sha256digestOut = new byte[sha256digest.GetByteLength()];
            byte[] sha256digestOut = new byte[sha256digest.GetDigestSize()];
            sha256digest.DoFinal(sha256digestOut, 0);

            RipeMD160Digest ripeMD160Digest = new RipeMD160Digest();

            ripeMD160Digest.BlockUpdate(sha256digestOut, 0, sha256digestOut.Length);
            // byte[] address = new byte[ripeMD160Digest.GetByteLength()];
            byte[] address = new byte[ADDRESS_LENGTH];
            ripeMD160Digest.DoFinal(address, 0);

            // Return the key bytes
            return(new Wallet(address: address, publicKey: publicKeyBytes, privateKey: privateKey, networkInfo: networkInfo));
        }