public PubKey(byte[] vch) { if(!IsValidSize(vch.Length)) { throw new FormatException("Invalid public key size"); } this.vch = vch.ToArray(); _Key = new ECKey(vch, false); }
/// <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); } } }
public void Sign(ECKey key) { simpleRlpSigner.Sign(key); }
private void SetBytes(byte[] data, int count, bool fCompressedIn) { vch = data.SafeSubarray(0, count); IsCompressed = fCompressedIn; _ECKey = new ECKey(vch, true); }
public void ReadWrite(BitcoinStream stream) { stream.ReadWrite(ref vch); if(!stream.Serializing) { _ECKey = new ECKey(vch, true); } }
public static string GetPublicAddress(string privateKey) { var key = new ECKey(privateKey.HexToByteArray(), true); return key.GetPublicAddress(); }
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()); }
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()); }
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); }
public void Sign(ECKey key) { signature = key.SignAndCalculateV(RawHash); rlpEncoded = null; }
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)); }