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); } var sig = DecodeSig(signatureEncoded); 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)); }
public byte[] SignCompact(uint256 hash) { var sig = _ECKey.Sign(hash); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; for (int i = 0; i < 4; i++) { ECKey k = ECKey.RecoverFromSignature(i, sig, hash, IsCompressed); if (k != null && k.GetPubKey(IsCompressed).ToHex() == PubKey.ToHex()) { recId = i; break; } } if (recId == -1) { throw new InvalidOperationException("Could not construct a recoverable key. This should never happen."); } int headerByte = recId + 27 + (IsCompressed ? 4 : 0); byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S sigData[0] = (byte)headerByte; Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 1, 32); Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 33, 32); return(sigData); }
public void RecoverySignature() { ECKey key = ECKey.FromPrivateKey(this.privatekey); ECDSASignature signature = key.Sign(signature_message); signature.Should().NotBeNull(); key.Verify(signature_message, signature).Should().BeTrue(); ECKey.RecoverFromSignature(signature, signature_message, false).PublicKey.SequenceEqual(key.PublicKey).Should().BeTrue(); }
public static long CheckWeight(Permission permission, List <ByteString> signature, byte[] hash, List <ByteString> approve_list) { long result = 0; if (signature.Count > permission.Keys.Count) { throw new PermissionException( "Signature count is" + signature.Count + "more than key counts of permission" + permission.Keys.Count); } Dictionary <ByteString, long> signature_weight = new Dictionary <ByteString, long>(); foreach (ByteString sign in signature) { if (sign.Length < 65) { throw new SignatureFormatException("Signature size is" + sign.Length); } ECKey ec_key = ECKey.RecoverFromSignature(ECDSASignature.ExtractECDSASignature(sign.ToByteArray()), hash, false); byte[] publickey = ec_key.PublicKey; byte[] address = Wallet.PublickKeyToAddress(ec_key.PublicKey); long weight = GetWeight(permission, address); if (weight == 0) { throw new PermissionException( sign.ToByteArray().ToHexString() + "is signed by" + Wallet.AddressToBase58(address) + "but it is not contained of permission."); } if (signature_weight.ContainsKey(sign)) { throw new PermissionException(Wallet.AddressToBase58(address) + " has signed twice"); } signature_weight.Add(sign, weight); if (approve_list != null) { approve_list.Add(ByteString.CopyFrom(publickey)); } result += weight; } return(result); }
public static PubKey RecoverCompact(uint256 hash, byte[] signatureEncoded) { #if HAS_SPAN if (signatureEncoded.Length != 65) { throw new ArgumentException(paramName: nameof(signatureEncoded), message: "Signature truncated, expected 65"); } Span <byte> msg = stackalloc byte[32]; hash.ToBytes(msg); var s = signatureEncoded.AsSpan(); int recid = (s[0] - 27) & 3; bool fComp = ((s[0] - 27) & 4) != 0; Secp256k1.ECPubKey pubkey; Secp256k1.SecpRecoverableECDSASignature sig; if (Secp256k1.SecpRecoverableECDSASignature.TryCreateFromCompact(s.Slice(1), recid, out sig) && sig is Secp256k1.SecpRecoverableECDSASignature && Secp256k1.ECPubKey.TryRecover(NBitcoinContext.Instance, sig, msg, out pubkey) && pubkey is Secp256k1.ECPubKey) { return(new PubKey(pubkey, fComp)); } throw new InvalidOperationException("Impossible to recover the public key"); #else 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); } var sig = DecodeSig(signatureEncoded); 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)); #endif }
public byte[] SignCompact(uint256 hash, bool forceLowR) { if (hash is null) { throw new ArgumentNullException(nameof(hash)); } AssertNotDisposed(); #if HAS_SPAN Span <byte> vchSig = stackalloc byte[65]; int rec = -1; var sig = new Secp256k1.SecpRecoverableECDSASignature(_ECKey.Sign(hash, forceLowR, out rec), rec); sig.WriteToSpanCompact(vchSig.Slice(1), out int recid); vchSig[0] = (byte)(27 + rec + (IsCompressed ? 4 : 0)); return(vchSig.ToArray()); #else var sig = _ECKey.Sign(hash, forceLowR); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; for (int i = 0; i < 4; i++) { ECKey k = ECKey.RecoverFromSignature(i, sig, hash, IsCompressed); if (k != null && k.GetPubKey(IsCompressed).ToHex() == PubKey.ToHex()) { recId = i; break; } } if (recId == -1) { throw new InvalidOperationException("Could not construct a recoverable key. This should never happen."); } int headerByte = recId + 27 + (IsCompressed ? 4 : 0); byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S sigData[0] = (byte)headerByte; #pragma warning disable 618 Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 1, 32); Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 33, 32); #pragma warning restore 618 return(sigData); #endif }
public CompactSignature SignCompact(uint256 hash, bool forceLowR) { if (hash is null) { throw new ArgumentNullException(nameof(hash)); } if (!IsCompressed) { throw new InvalidOperationException("This operation is only supported on compressed pubkey"); } AssertNotDisposed(); #if HAS_SPAN byte[] sigBytes = new byte[64]; var sig = new Secp256k1.SecpRecoverableECDSASignature(_ECKey.Sign(hash, forceLowR, out var rec), rec); sig.WriteToSpanCompact(sigBytes, out _); return(new CompactSignature(rec, sigBytes)); #else var sig = _ECKey.Sign(hash, forceLowR); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; for (int i = 0; i < 4; i++) { ECKey k = ECKey.RecoverFromSignature(i, sig, hash); if (k != null && k.GetPubKey(true).ToHex() == PubKey.ToHex()) { recId = i; break; } } if (recId == -1) { throw new InvalidOperationException("Could not construct a recoverable key. This should never happen."); } #pragma warning disable 618 byte[] sigData = new byte[64]; // 1 header + 32 bytes for R + 32 bytes for S Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 0, 32); Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 32, 32); #pragma warning restore 618 return(new CompactSignature(recId, sigData)); #endif }
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 && Enumerable.SequenceEqual(k, thisKey)) { recId = i; break; } } if (recId == -1) { throw new Exception("Could not construct a recoverable key. This should never happen."); } return(recId); }
//Note: Y coordinates can only be forced, so it is assumed 0 and 1 will be the recId (even if implementation allows for 2 and 3) internal int CalculateRecId(ECDSASignature signature, byte[] hash) { var recId = -1; var thisKey = _ecKey.GetPubKey(false); // compressed for (var i = 0; i \ { var rec = ECKey.RecoverFromSignature(i, signature, hash, false); if (rec != null) { var k = rec.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; }
private static int CalculateRecId(ECDSASignature signature, byte[] hash, byte[] uncompressedPublicKey) { var recId = -1; for (var i = 0; i < 4; i++) { var rec = ECKey.RecoverFromSignature(i, signature, hash, false); var k = rec?.GetPubKey(false); if (k != null && k.SequenceEqual(uncompressedPublicKey)) { recId = i; break; } } if (recId == -1) { throw new ArgumentException("Could not construct a recoverable key. This should never happen."); } return(recId); }
public static NasECKey RecoverFromSignature(NasECDSASignature signature, int recId, byte[] hash) { return(new NasECKey(ECKey.RecoverFromSignature(recId, signature.ECDSASignature, hash, false))); }
//public static int GetRecIdFromVChain(byte[] vChain, BigInteger chainId) //{ // return GetRecIdFromVChain(vChain.ToBigIntegerFromRLPDecoded(), chainId); //} public static NasECKey RecoverFromSignature(NasECDSASignature signature, byte[] hash) { return(new NasECKey(ECKey.RecoverFromSignature(GetRecIdFromV(signature.V), signature.ECDSASignature, hash, false))); }
public static EthECKey RecoverFromSignature(EthECDSASignature signature, byte[] hash, BigInteger chainId) { return(new EthECKey(ECKey.RecoverFromSignature(GetRecIdFromVChain(signature.V, chainId), signature.ECDSASignature, hash, false))); }
public static EthECKey RecoverFromSignature(EthECDSASignature signature, int recId, byte[] hash) { return new EthECKey(ECKey.RecoverFromSignature(recId, signature.ECDSASignature, hash, false)); }
public static EthECKey RecoverFromParityYSignature(EthECDSASignature signature, byte[] hash) { return(new EthECKey(ECKey.RecoverFromSignature(signature.V.ToIntFromRLPDecoded(), signature.ECDSASignature, hash, false))); }
public static PubKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 hash, bool compressed) { ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed); return(key?.GetPubKey(compressed)); }