public string GetPassphraseHash(byte[] seedguid, int version) { //use as seed string hex = HexString.FromByteArray(seedguid); byte[] il = HexString.ToByteArray(hex.Substring(0, 64)); byte[] ir = HexString.ToByteArray(hex.Substring(64, 64)); var bip32 = new BIP32(secp256k1); try { bip32.eckey = new ECKeyPair(il,null,false,false,secp256k1); bip32.eckey.compress(true); bip32.chain_code = ir; bip32.child_index = 0; bip32.parent_fingerprint = HexString.ToByteArray("00000000"); bip32.version = version; bip32.depth = 0; bip32.BuildExtendedPublicKey(); bip32.BuildExtendedPrivateKey(); } catch (Exception ex) { } return bip32.ExtendedPrivateKeyString("base58"); }
public BIP32 DeriveChild(uint i) { DateTime start = DateTime.Now; BIP32 ret = new BIP32(secp256k1); byte[] ib; using (MemoryStream ms = new MemoryStream()) using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write((byte)((i >> 24) & 0xff)); bw.Write((byte)((i >> 16) & 0xff)); bw.Write((byte)((i >> 8) & 0xff)); bw.Write((byte)(i & 0xff)); ib = ms.ToArray(); } bool use_private = (i & 0x80000000) != 0; bool is_private = (this.version == BITCOIN_MAINNET_PRIVATE || this.version == BITCOIN_TESTNET_PRIVATE); if (use_private && (this.eckey.privKey == null || !is_private)) throw new Exception("Cannot do private key derivation without private key"); if (this.eckey.privKey != null) { byte[] data = null; using (MemoryStream ms = new MemoryStream()) using (BinaryWriter bw = new BinaryWriter(ms)) { if (use_private) { bw.Write((byte)0); bw.Write(this.eckey.privKey); bw.Write(ib); data = ms.ToArray(); } else { //bw.Write((byte)0); bw.Write(this.eckey.pubKey); bw.Write(ib); data = ms.ToArray(); } } HMACSHA512 hmacsha = new HMACSHA512(this.chain_code); byte[] hash = hmacsha.ComputeHash(data); string hhash = HexString.FromByteArray(hash); byte[] ir = HexString.ToByteArray(hhash.Substring(64, 64)); string ilb = hhash.Substring(0, 64); string pkb = HexString.FromByteArray(this.eckey.privKey); string k = secp256k1.AddPrivate(pkb, ilb); ret.chain_code = ir; byte[] derkey = HexString.ToByteArray(k); if (derkey.Length == 31) { List<byte> tmp = derkey.ToList(); tmp.Insert(0, (byte)0); derkey = tmp.ToArray(); } ret.eckey = new ECKeyPair(derkey, null, false, false, secp256k1); ret.eckey.compress(true); } else { byte[] data = null; using (MemoryStream ms = new MemoryStream()) using (BinaryWriter bw = new BinaryWriter(ms)) { if (use_private) { bw.Write((byte)0); bw.Write(this.eckey.privKey); bw.Write(ib); data = ms.ToArray(); } else { //bw.Write((byte)3); bw.Write(this.eckey.pubKey); bw.Write(ib); data = ms.ToArray(); } } HMACSHA512 hmacsha = new HMACSHA512(this.chain_code); byte[] hash = hmacsha.ComputeHash(data); string test = HexString.FromByteArray(hash); byte[] ir = HexString.ToByteArray(test.Substring(64, 64)); string bil = test.Substring(0, 64); string bpub = HexString.FromByteArray(this.eckey.pubKey); string point = secp256k1.AddPublic(bpub, bil); ret.chain_code = ir; ret.eckey = new ECKeyPair(null, HexString.ToByteArray(point)); ret.eckey.compress(true); } ret.child_index = i; //this is why we need the pub key hash //for the fingerprint start = DateTime.Now; Address add = new Address(this.eckey.pubKey); Console.WriteLine("New Address:" + DateTime.Now.Subtract(start).TotalMilliseconds); ret.parent_fingerprint = add.PubKeyHash.hash.Take(4).ToArray(); ret.version = this.version; ret.depth = this.depth + 1; ret.BuildExtendedPublicKey(); ret.BuildExtendedPrivateKey(); return ret; }