Пример #1
0
 public SimpleRLPSigner(byte[][] data, byte[] r, byte[] s, byte v)
 {
     this.numberOfElements = data.Length;
     this.data = data;
     this.signature = EthECDSASignatureFactory.FromComponents(r, s, v);
     decoded = true;
 }
Пример #2
0
 public TransactionSignature(ECDSASignature signature, SigHash sigHash)
 {
     if(sigHash == SigHash.Undefined)
         throw new ArgumentException("sigHash should not be Undefined");
     _SigHash = sigHash;
     _Signature = signature.MakeCanonical();
 }
Пример #3
0
        public static int CalculateRecId(this ECKey key, ECDSASignature signature, byte[] hash)
        {
            var recId = -1;
            var thisKey = key.GetPubKey(false); // compressed

            for (var i = 0; i < 4; i++)
            {
                var k = ECKey.RecoverFromSignature(i, signature, hash, false).GetPubKey(false);
                if ((k != null) && k.SequenceEqual(thisKey))
                {
                    recId = i;
                    break;
                }
            }
            if (recId == -1)
                throw new Exception("Could not construct a recoverable key. This should never happen.");
            return recId;
        }
Пример #4
0
        public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, byte[] 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 = Secp256k1;

            // 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 = 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 = ((SecP256K1Curve) curve.Curve).QQ;
            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.
            var 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 BigInteger(1, message);
            //   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 = 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 = ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv);
            q = q.Normalize();
            if (compressed)
                q = new SecP256K1Point(curve.Curve, q.XCoord, q.YCoord, true);
            return new ECKey(q.GetEncoded(), false);
        }
Пример #5
0
 public bool Verify(byte[] hash, ECDSASignature sig)
 {
     var signer = new ECDsaSigner();
     signer.Init(false, GetPublicKeyParameters());
     return signer.VerifySignature(hash, sig.R, sig.S);
 }
Пример #6
0
 internal bool Verify(uint256 hash, ECDSASignature sig)
 {
     var signer = new ECDsaSigner();
     signer.Init(false, GetPublicKeyParameters());
     return signer.VerifySignature(hash.ToBytes(), sig.R, sig.S);
 }
Пример #7
0
		private static ECDSASignature DecodeSig(byte[] signatureEncoded)
		{
			BigInteger r = new BigInteger(1, signatureEncoded.SafeSubarray(1, 32));
			BigInteger s = new BigInteger(1, signatureEncoded.SafeSubarray(33, 32));
			var sig = new ECDSASignature(r, s);
			return sig;
		}
Пример #8
0
		public Script GenerateScriptSig(ECDSASignature[] signatures, Script redeemScript)
		{
			return GenerateScriptSig(signatures.Select(s => new TransactionSignature(s, SigHash.All)).ToArray(), redeemScript);
		}
Пример #9
0
 public TransactionSignature(byte[] sigSigHash)
 {
     _Signature = ECDSASignature.FromDER(sigSigHash.Take(sigSigHash.Length - 1).ToArray()).MakeCanonical();
     _SigHash = (SigHash)sigSigHash[sigSigHash.Length - 1];
 }
Пример #10
0
 public TransactionSignature(ECDSASignature signature)
     : this(signature, SigHash.All)
 {
 }
Пример #11
0
 public ECDSASignature Sign(uint256 hash)
 {
     AssertPrivateKey();
     ECDsaSigner signer = new ECDsaSigner();
     signer.Init(true, PrivateKey);
     BigInteger[] components = signer.GenerateSignature(hash.ToBytes());
     ECDSASignature signature = new ECDSASignature(components[0], components[1]);
     signature = signature.MakeCanonical();
     return signature;
 }
Пример #12
0
        public static PubKey RecoverCompact(uint256 hash, byte[] signatureEncoded)
        {
            if(signatureEncoded.Length < 65)
                throw new ArgumentException("Signature truncated, expected 65 bytes and got " + signatureEncoded.Length);

            int header = signatureEncoded[0];

            // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
            //                  0x1D = second key with even y, 0x1E = second key with odd y

            if(header < 27 || header > 34)
                throw new ArgumentException("Header byte out of range: " + header);

            BigInteger r = new BigInteger(1, signatureEncoded.Skip(1).Take(32).ToArray());
            BigInteger s = new BigInteger(1, signatureEncoded.Skip(33).Take(32).ToArray());
            var sig = new ECDSASignature(r, s);
            bool compressed = false;

            if(header >= 31)
            {
                compressed = true;
                header -= 4;
            }
            int recId = header - 27;

            ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed);
            return key.GetPubKey(compressed);
        }
Пример #13
0
 public bool Verify(uint256 hash, ECDSASignature sig)
 {
     return _Key.Verify(hash, sig);
 }
Пример #14
0
		private ECDSASignature ToPositive(ECDSASignature sig)
		{
			return new ECDSASignature(new BouncyCastle.Math.BigInteger(1, sig.R.ToByteArray()), new BouncyCastle.Math.BigInteger(1, sig.S.ToByteArray()));
		}
Пример #15
0
 public TransactionSignature(byte[] sig, SigHash sigHash)
 {
     _Signature = ECDSASignature.FromDER(sig).MakeCanonical();
     _SigHash = sigHash;
 }
Пример #16
0
 public static bool VerifyAllowingOnlyLowS(this ECKey key, byte[] hash, ECDSASignature sig)
 {
     if (!sig.IsLowS) return false;
     return key.Verify(hash, sig);
 }
Пример #17
0
        public void RlpDecode()
        {
            var decodedList = RLP.Decode(GetRLPEncoded());
            var decodedData = new List<byte[]>();
            var decodedElements = (RLPCollection)decodedList[0];
            for (var i = 0; i < numberOfElements; i++)
            {
                decodedData.Add(decodedElements[i].RLPData);    
            }
            // only parse signature in case is signed
            if (decodedElements[numberOfElements].RLPData != null)
            {
                var v = decodedElements[numberOfElements].RLPData[0];
                var r = decodedElements[numberOfElements + 1].RLPData;
                var s = decodedElements[numberOfElements + 2].RLPData;

                signature = EthECDSASignatureFactory.FromComponents(r, s, v);
            }
            data = decodedData.ToArray();
            decoded = true;
        }
Пример #18
0
 public static ECKey RecoverFromSignature(ECDSASignature signature, byte[] hash)
 {
     return ECKey.RecoverFromSignature(GetRecIdFromV(signature.V), signature, hash, false);
 }
Пример #19
0
 public void Sign(ECKey key)
 {
     signature = key.SignAndCalculateV(RawHash);
     rlpEncoded = null;
 }
Пример #20
0
		public Script GenerateScriptSig(ECDSASignature signature)
		{
			return GenerateScriptSig(new TransactionSignature(signature, SigHash.All));
		}
Пример #21
0
        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));
        }