public virtual void Sign(EthereumEcdsa localPrivateKey, EthereumEcdsa ephemeralPrivateKey, EthereumEcdsa receiverPublicKey, uint?chainID = null) { // Generate the shared secret using ECDH between our local private key and this remote public key byte[] ecdhKey = localPrivateKey.ComputeECDHKey(receiverPublicKey); // If our nonce is null, generate a new one Nonce = Nonce ?? RLPxSession.GenerateNonce(); // Verify the nonce is the correct length. if (Nonce.Length != RLPxSession.NONCE_SIZE) { // Throw an exception if an invalid nonce was provided. throw new ArgumentException($"Invalid size nonce provided for RLPx session when signing auth message. Should be {RLPxSession.NONCE_SIZE} bytes but was {Nonce?.Length}."); } // Obtain our transformed nonce data. byte[] transformedNonceData = GetTransformedNonce(ecdhKey); // Sign the transformed data. var signature = ephemeralPrivateKey.SignData(transformedNonceData); // We want our signature in r,s,v format. R = BigIntegerConverter.GetBytes(signature.r, 32); S = BigIntegerConverter.GetBytes(signature.s, 32); V = EthereumEcdsa.GetVFromRecoveryID(chainID, signature.RecoveryID); // Set our local public key and the public key hash. PublicKey = localPrivateKey.ToPublicKeyArray(false, true); }
public static (BigInteger R, BigInteger S, byte V) Sign(EthereumEcdsa privateKey, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, Address?to, BigInteger value, byte[] data, uint?chainID) { // Obtain our transaction hash to sign. byte[] hash = GetUnsignedHash(nonce, gasPrice, gasLimit, to, value, data, chainID); // Sign our data (byte RecoveryID, BigInteger r, BigInteger s)signature = privateKey.SignData(hash); // Set our r and s components. var r = signature.r; var s = signature.s; // Obtain our v parameter from recovery ID and set it var v = EthereumEcdsa.GetVFromRecoveryID(chainID, signature.RecoveryID); return(r, s, v); }