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 🙂