public PubKey Derivate(byte[] cc, uint nChild, out byte[] ccChild) { if (!IsCompressed) { throw new InvalidOperationException("The pubkey must be compressed"); } if ((nChild >> 31) != 0) { throw new InvalidOperationException("A public key can't derivate an hardened child"); } #if HAS_SPAN Span <byte> vout = stackalloc byte[64]; vout.Clear(); Span <byte> pubkey = stackalloc byte[33]; this.ToBytes(pubkey, out _); Hashes.BIP32Hash(cc, nChild, pubkey[0], pubkey.Slice(1), vout); ccChild = new byte[32];; vout.Slice(32, 32).CopyTo(ccChild); return(new PubKey(this.ECKey.AddTweak(vout.Slice(0, 32)), true)); #else byte[] lr = null; byte[] l = new byte[32]; byte[] r = new byte[32]; var pubKey = ToBytes(); lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray()); Array.Copy(lr, l, 32); Array.Copy(lr, 32, r, 0, 32); ccChild = r; BigInteger N = ECKey.CURVE.N; BigInteger parse256LL = new BigInteger(1, l); if (parse256LL.CompareTo(N) >= 0) { throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again."); } var q = ECKey.CURVE.G.Multiply(parse256LL).Add(ECKey.GetPublicKeyParameters().Q); if (q.IsInfinity) { throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again."); } q = q.Normalize(); var p = new NBitcoin.BouncyCastle.Math.EC.FpPoint(ECKey.CURVE.Curve, q.XCoord, q.YCoord, true); return(new PubKey(p.GetEncoded())); #endif }
/// <summary> /// Exchange shared secret through ECDH /// </summary> /// <param name="key">Private key</param> /// <returns>Shared secret</returns> public byte[] GetSharedSecret(Key key) { var pub = _ECKey.GetPublicKeyParameters(); var privKey = key._ECKey.PrivateKey; if (!pub.Parameters.Equals(privKey.Parameters)) { throw new InvalidOperationException("ECDH public key has wrong domain parameters"); } ECPoint q = pub.Q.Multiply(privKey.D).Normalize(); if (q.IsInfinity) { throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH"); } var pubkey = ECKey.Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()).GetEncoded(true); return(Hashes.SHA256(pubkey)); }
public PubKey Derivate(byte[] cc, uint nChild, out byte[] ccChild) { byte[] lr = null; var l = new byte[32]; var r = new byte[32]; if (nChild >> 31 == 0) { var pubKey = ToBytes(); lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray()); } else { throw new InvalidOperationException("A public key can't derivate an hardened child"); } Array.Copy(lr, l, 32); Array.Copy(lr, 32, r, 0, 32); ccChild = r; var N = ECKey.CURVE.N; var parse256LL = new BigInteger(1, l); if (parse256LL.CompareTo(N) >= 0) { throw new InvalidOperationException( "You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again."); } var q = ECKey.CURVE.G.Multiply(parse256LL).Add(ECKey.GetPublicKeyParameters().Q); if (q.IsInfinity) { throw new InvalidOperationException( "You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again."); } q = q.Normalize(); var p = new FpPoint(ECKey.CURVE.Curve, q.XCoord, q.YCoord, true); return(new PubKey(p.GetEncoded())); }
public PubKey Derivate(byte[] cc, uint nChild, out byte[] ccChild) { byte[] lr = null; byte[] l = new byte[32]; byte[] r = new byte[32]; if ((nChild >> 31) == 0) { var pubKey = ToBytes(); lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray()); } else { throw new InvalidOperationException("Impossible to derivate a child key from a hardened one"); } Array.Copy(lr, l, 32); Array.Copy(lr, 32, r, 0, 32); ccChild = r; BigInteger N = ECKey.CURVE.N; BigInteger kPar = new BigInteger(1, this.vch); BigInteger parse256LL = new BigInteger(1, l); if (parse256LL.CompareTo(N) >= 0) { throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again."); } var q = ECKey.CURVE.G.Multiply(parse256LL).Add(_Key.GetPublicKeyParameters().Q); if (q.IsInfinity) { throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again."); } var p = new NBitcoin.BouncyCastle.Math.EC.FpPoint(ECKey.CURVE.Curve, q.X, q.Y, true); return(new PubKey(p.GetEncoded())); }