paulmillr / noble-curves

Audited & minimal JS implementation of elliptic curve cryptography.
https://paulmillr.com/noble
MIT License
621 stars 56 forks source link

Same private keys generate different signatures #115

Closed Egge21M closed 4 months ago

Egge21M commented 4 months ago

Hi everyone,

today I encountered some very weird behavior when working with @noble/curves. I generate a random key, convert it to HEX and then back to an Uint8 Array. The two keys are equal. But when I use the original and the converted key to create a signature on the same data, the signatures differ.

Here is a minimal reproducible example:

function isEqualBytes(bytes1: Uint8Array, bytes2: Uint8Array): boolean {
  if (bytes1.length !== bytes2.length) {
    return false;
  }
  for (let i = 0; i < bytes1.length; i++) {
    if (bytes1[i] !== bytes2[i]) {
      return false;
    }
  }
  return true;
}

const privkeyBytes = schnorr.utils.randomPrivateKey();
const privkeyHex = bytesToHex(privkeyBytes);
const privkeyBytes2 = hexToBytes(privkeyHex);

console.log(
  'Keys in Bytes are equal: ',
  indexedDB.cmp(privkeyBytes, privkeyBytes2) === 0
);
console.log(
  'Keys in Bytes are equal: ',
  isEqualBytes(privkeyBytes2, privkeyBytes)
);

const secretHashBytes = sha256('hallo');

const nobleSig2 = schnorr.sign(secretHashBytes, privkeyBytes2);
const nobleSig = schnorr.sign(secretHashBytes, privkeyBytes);

console.log('Signatures are equal: ', isEqualBytes(nobleSig2, nobleSig));
console.log(bytesToHex(nobleSig2));
console.log(bytesToHex(nobleSig));

and here is this example on StackBlitz

paulmillr commented 4 months ago

auxRand is default third argument, which injects some randomness into signatures. if you want same sigs, set it to something static.