Convert working C# code for signing data using Ed25519 to JavaScript code

I have a working C# code, which is used to sign data using the Ed25519 algorithm. In the C# code I use the BouncyCastle library. Here is the C# version of the code:

bool SignFunction(byte[] inData, byte[] outData)
{
    if ((inData.Length != 32) || (outData.Length != 64))
    {
        return false;
    }
    byte[] SecretBytes =
    {
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
    };

    Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(SecretBytes, 0);
    Ed25519phSigner signer = new Ed25519phSigner(Array.Empty<byte>());
    signer.Init(true, privateKey);
    signer.BlockUpdate(inData, 0, inData.Length);
    byte[] signature = signer.GenerateSignature();
    Array.ConstrainedCopy(signature, 0, outData, 0, signature.Length);
    return true;
}

I call the function like this:

byte[] InData = 
{
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
byte[] OutData = new byte[0x40];

SignFunction(InData, OutData);

And the result which is stored in OutData is:

OutData: 98 CA B8 60 77 C2 C7 F3 9A E1 81 5D 2F B6 3E 4D EC 24 84 C6 61 12 20 8F 4D 78 01 32 25 3F 95 60 51 71 0A 4C F4 A8 C2 5D F2 69 EA 49 72 5A D0 99 95 F0 EC 89 53 F7 8D 79 CC 62 EF DA 94 8A 41 06


I want to use the same algorithm in JavaScript. I use “https://cdn.jsdelivr.net/npm/[email protected]/nacl.min.js” for the Ed25519 signing algorithm. Here is my JavaScript code:

const nacl = window.nacl;
    
function onClick() 
{
  updateLabel();
}

function toByteArray(x) 
{
    var hexString = x.toString(16);
    if(hexString.length % 2 > 0) hexString = "0" + hexString;
    var byteArray = [];
    for(var i = 0; i < hexString.length; i += 2) 
    {
        byteArray.push(parseInt(hexString.slice(i, i + 2), 16));
    }
    return byteArray;
}

function toPaddedHexString(num, len) 
{
    str = num.toString(16);
    return "0".repeat(len - str.length) + str;
}

function calculateSHA512(byteArray) 
{
    var hashArrayStr = sha512.hex(byteArray);
    const hashArray = toByteArray(hashArrayStr);

    return hashArray;
}

function SignFunction(inData, outData)
{
    if (inData.length !== 32 || outData.length !== 64) {
        return; // Return early if sizes are incorrect
    }
    
    const SecretBytes = new Uint8Array([
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
]);
var InBytes = new Uint8Array(32).fill(1);
for(var i=0; i<32; i++)
    InBytes[i] = inData[i];

// Generate the key pair from the 32-byte seed (private and public keys)
    const keyPair = nacl.sign.keyPair.fromSeed(SecretBytes);

    // Sign the Hash512Bytes using the private key (keyPair.secretKey)
    const signature = nacl.sign.detached(InBytes, keyPair.secretKey);

    // Copy the signature into outData (64 bytes)
    for (let i = 0; i < signature.length; i++) {
        outData[i] = signature[i];
    }
}

function updateLabel() 
{
  var InData = new Uint8Array(32);
  var OutData = new Uint8Array(64);
  
  InData = toByteArray("0101010101010101010101010101010101010101010101010101010101010101");
  SignFunction(InData, OutData);
  
  var InStr =  "";
  for(var i = 0; i < 32; i += 1) 
    {
        InStr = InStr + toPaddedHexString(InData[i], 2) + ' ';
    }
  
  var OutStr =  "";
  for(var i = 0; i < 64; i += 1) 
    {
        OutStr = OutStr + toPaddedHexString(OutData[i], 2) + ' ';
    }
    label.textContent = 'InData: ' + InStr.toUpperCase() + '   -> OutData: ' + OutStr.toUpperCase();
}

var label = document.querySelector('p');
var button = document.querySelector('button');
button.addEventListener('click', onClick);

The result I get is totally different. Can anyone please advise what library I should use in order to make the JavaScript code generate the same result as the C# code?

I tried to use ChatGpt, because I have almost zero experience with JavaScript, but it didn’t help 🙂