예제 #1
0
파일: PubKey.cs 프로젝트: nikropht/NBitcoin
 public PubKey(byte[] vch)
 {
     if(!IsValidSize(vch.Length))
     {
         throw new FormatException("Invalid public key size");
     }
     this.vch = vch.ToArray();
     _Key = new ECKey(vch, false);
 }
예제 #2
0
파일: PubKey.cs 프로젝트: vebin/NBitcoin
		/// <summary>
		/// Create a new Public key from byte array
		/// </summary>
		/// <param name="bytes">byte array</param>
		/// <param name="unsafe">If false, make internal copy of bytes and does perform only a costly check for PubKey format. If true, the bytes array is used as is and only PubKey.QuickCheck is used for validating the format. </param>	 
		public PubKey(byte[] bytes, bool @unsafe)
		{
			if(bytes == null)
				throw new ArgumentNullException("bytes");
			if(!Check(bytes, false))
			{
				throw new FormatException("Invalid public key");
			}
			if(@unsafe)
				this.vch = bytes;
			else
			{
				this.vch = bytes.ToArray();
				try
				{
					_ECKey = new ECKey(bytes, false);
				}
				catch(Exception ex)
				{
					throw new FormatException("Invalid public key", ex);
				}
			}
		}
예제 #3
0
 public void Sign(ECKey key)
 {
     simpleRlpSigner.Sign(key);
 }
예제 #4
0
파일: Key.cs 프로젝트: woutersmit/NBitcoin
		private void SetBytes(byte[] data, int count, bool fCompressedIn)
		{
			vch = data.SafeSubarray(0, count);
			IsCompressed = fCompressedIn;
			_ECKey = new ECKey(vch, true);
		}
예제 #5
0
파일: Key.cs 프로젝트: woutersmit/NBitcoin
		public void ReadWrite(BitcoinStream stream)
		{
			stream.ReadWrite(ref vch);
			if(!stream.Serializing)
			{
				_ECKey = new ECKey(vch, true);
			}
		}
예제 #6
0
 public static string GetPublicAddress(string privateKey)
 {
     var key = new ECKey(privateKey.HexToByteArray(), true);
     return key.GetPublicAddress();
 }
예제 #7
0
 public void ShouldGenerateECKey()
 {
     var ecKey = EthECKey.GenerateKey();
     var key = ecKey.GetPrivateKeyAsBytes();
     var regeneratedKey = new ECKey(key, true);
     Assert.Equal(key.ToHex(), regeneratedKey.GetPrivateKeyAsBytes().ToHex());
     Assert.Equal(ecKey.GetPublicAddress(), regeneratedKey.GetPublicAddress());
 }
예제 #8
0
        public void ShouldSignEncodeTransactionAndRecoverPublicAddress()
        {
            var privateKey = "b5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7";
            var sendersAddress = "12890d2cce102216644c59daE5baed380d84830c";
            var publicKey =
                "87977ddf1e8e4c3f0a4619601fc08ac5c1dcf78ee64e826a63818394754cef52457a10a599cb88afb7c5a6473b7534b8b150d38d48a11c9b515dd01434cceb08";

            var key = new ECKey(privateKey.HexToByteArray(), true);
            var hash = "test".ToHexUTF8().HexToByteArray();
            var signature = key.Sign(hash);
            Assert.True(key.Verify(hash, signature));
            Assert.Equal(key.GetPubKeyNoPrefix().ToHex(), publicKey);
            Assert.Equal(sendersAddress.ToLower(), key.GetPublicAddress());
        }
예제 #9
0
파일: Key.cs 프로젝트: nikropht/NBitcoin
 private void SetBytes(byte[] data, int count, bool fCompressedIn)
 {
     vch = new byte[32];
     Array.Copy(data, 0, vch, 0, count);
     IsCompressed = fCompressedIn;
     _ECKey = new ECKey(vch, true);
 }
예제 #10
0
 public void Sign(ECKey key)
 {
     signature = key.SignAndCalculateV(RawHash);
     rlpEncoded = null;
 }
예제 #11
0
파일: ECKey.cs 프로젝트: pkahle/NBitcoin
        public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 message, bool compressed)
        {
            if (recId < 0)
            {
                throw new ArgumentException("recId should be positive");
            }
            if (sig.R.SignValue < 0)
            {
                throw new ArgumentException("r should be positive");
            }
            if (sig.S.SignValue < 0)
            {
                throw new ArgumentException("s should be positive");
            }
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }


            var curve = ECKey.CreateCurve();

            // 1.0 For j from 0 to h   (h == recId here and the loop is outside this function)
            //   1.1 Let x = r + jn

            var n = curve.N;
            var i = Org.BouncyCastle.Math.BigInteger.ValueOf((long)recId / 2);
            var x = sig.R.Add(i.Multiply(n));

            //   1.2. Convert the integer x to an octet string X of length mlen using the conversion routine
            //        specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉.
            //   1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
            //        conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then
            //        do another iteration of Step 1.
            //
            // More concisely, what these points mean is to use X as a compressed public key.
            var prime = ((FpCurve)curve.Curve).Q;

            if (x.CompareTo(prime) >= 0)
            {
                return(null);
            }

            // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
            // So it's encoded in the recId.
            ECPoint R = DecompressKey(x, (recId & 1) == 1);

            //   1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).

            if (!R.Multiply(n).IsInfinity)
            {
                return(null);
            }

            //   1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
            var e = new Org.BouncyCastle.Math.BigInteger(1, message.ToBytes());
            //   1.6. For k from 1 to 2 do the following.   (loop is outside this function via iterating recId)
            //   1.6.1. Compute a candidate public key as:
            //               Q = mi(r) * (sR - eG)
            //
            // Where mi(x) is the modular multiplicative inverse. We transform this into the following:
            //               Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
            // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). In the above equation
            // ** is point multiplication and + is point addition (the EC group operator).
            //
            // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
            // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.

            var eInv     = Org.BouncyCastle.Math.BigInteger.Zero.Subtract(e).Mod(n);
            var rInv     = sig.R.ModInverse(n);
            var srInv    = rInv.Multiply(sig.S).Mod(n);
            var eInvrInv = rInv.Multiply(eInv).Mod(n);
            var q        = (FpPoint)ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv);

            if (compressed)
            {
                q = new FpPoint(curve.Curve, q.X, q.Y, true);
            }
            return(new ECKey(q.GetEncoded(), false));
        }