Skip to content

Instantly share code, notes, and snippets.

@ankushKun
Last active May 18, 2022 07:31
Show Gist options
  • Save ankushKun/b3bb0e6a174ec9da1c14aef239a81061 to your computer and use it in GitHub Desktop.
Save ankushKun/b3bb0e6a174ec9da1c14aef239a81061 to your computer and use it in GitHub Desktop.
Sign DeSo transaction hex in C# using Bouncy Castle cryptography library
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