Last active
May 18, 2022 07:31
-
-
Save ankushKun/b3bb0e6a174ec9da1c14aef239a81061 to your computer and use it in GitHub Desktop.
Sign DeSo transaction hex in C# using Bouncy Castle cryptography library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Text; | |
using Desonity; | |
using Org.BouncyCastle.Asn1; | |
using Org.BouncyCastle.Asn1.Sec; | |
using Org.BouncyCastle.Crypto.Digests; | |
using Org.BouncyCastle.Crypto.Parameters; | |
using Org.BouncyCastle.Crypto.Signers; | |
using Org.BouncyCastle.Math; | |
using UnityEngine; | |
public class SignTransactionExample : MonoBehaviour | |
{ | |
// Start is called before the first frame update | |
void Start() | |
{ | |
string seed = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; | |
string txnHex = "01efa5060f5fdae5ed9d90e5f076b2c328a64e347d0c87e8e3317daec5a44fe7c8000102bd53e48625f49e60ff6b7a934e3871b54cc2a93a8737352e8320549e42e2322bab0405270000167b22426f6479223a2248656c6c6f20576f726c64227de807d461f4df9efad8a0f3f716002102bd53e48625f49e60ff6b7a934e3871b54cc2a93a8737352e8320549e42e2322b0000"; | |
Debug.Log("Signed Transaction " + SignTransaction(seed, txnHex)); | |
} | |
public string SignTransaction(string privateKey, string txnHex) | |
{ | |
var curve = SecNamedCurves.GetByName("secp256k1"); | |
var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H); | |
var keyParameters = new ECPrivateKeyParameters(new BigInteger(privateKey, 16), domain); | |
var signer = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest())); | |
signer.Init(true, keyParameters); | |
var txnBytes = Convert(txnHex); | |
var hash = GetHash(GetHash(txnBytes)); | |
var signature = signer.GenerateSignature(hash); | |
var r = signature[0]; | |
var s = signature[1]; | |
var otherS = curve.Curve.Order.Subtract(s); | |
if (s.CompareTo(otherS) == 1) | |
{ | |
s = otherS; | |
} | |
var derSignature = new DerSequence | |
( | |
new DerInteger(new BigInteger(1, r.ToByteArray())), | |
new DerInteger(new BigInteger(1, s.ToByteArray())) | |
) | |
.GetDerEncoded(); | |
var signatureStr = Convert(derSignature); | |
string signedTxn = txnHex.Substring(0, txnHex.Length - 2) + (signatureStr.Length / 2).ToString("x") + signatureStr; | |
return signedTxn; | |
} | |
private static byte[] GetHash(byte[] data) | |
{ | |
var digest = new Sha256Digest(); | |
var hash = new byte[digest.GetDigestSize()]; | |
digest.BlockUpdate(data, 0, data.Length); | |
digest.DoFinal(hash, 0); | |
return hash; | |
} | |
public string Convert(byte[] input) | |
{ | |
return string.Concat(input.Select(x => x.ToString("x2"))); | |
} | |
public byte[] Convert(string input) | |
{ | |
if (input.StartsWith("0x")) input = input.Remove(0, 2); | |
return Enumerable.Range(0, input.Length / 2).Select(x => System.Convert.ToByte(input.Substring(x * 2, 2), 16)).ToArray(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment