Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signatures will randomly return as invalid. #87

Closed
cmdruid opened this issue Dec 18, 2022 · 1 comment
Closed

Signatures will randomly return as invalid. #87

cmdruid opened this issue Dec 18, 2022 · 1 comment

Comments

@cmdruid
Copy link

cmdruid commented Dec 18, 2022

Hello. I believe that I have found a bug with how signatures (and possibly keys) are validated.

I have devised a test where the signature validation will fail 50% on average. I have also confirmed this behavior in two other projects, which caused me to write this test case to figure out what was going on.

Here is the code I am using to reproduce the bug:

import * as Noble from '@noble/secp256k1'
import { webcrypto as crypto } from 'crypto'

let rounds = 10, passed = 0

for (let i = 0; i < rounds; i++) {

  const randomBytes = getRandBytes(32)
  const randomData  = getRandBytes(32)

  const isValidPrivateKey = Noble.utils.isValidPrivateKey(randomBytes)
  const pubKey = Noble.getPublicKey(randomBytes)

  const signature = await Noble.schnorr.sign(randomData, randomBytes)
  const isValid = await Noble.schnorr.verify(signature, randomData, pubKey)

  if (!(isValidPrivateKey && isValid)) {
    console.log('Failed validation!')
    console.log('  message:', Noble.utils.bytesToHex(randomData))
    console.log('  Valid Key:', isValidPrivateKey, Noble.utils.bytesToHex(randomBytes))
    console.log('  Valid Sig:', isValid, Noble.utils.bytesToHex(signature))
    console.log('')
  } else { passed++ }
}

console.log(`Passed: ${passed}\nFailed: ${rounds - passed}\nTotal: ${rounds}`)

function getRandBytes(size = 32) {
  return crypto.getRandomValues(new Uint8Array(size))
}

For the above code, there are no dependencies besides the built-in webcrypto module and (version 1.7.0) the @noble/secp256k1 library.

I haven't run into this issue until recently, and I suspect it may have something to do with the random data being used for signing, but honestly I'm not sure. The random data will pass the isValidPrivateKey check 100% of the time, but the signature will fail 50% of the time on average.

@paulmillr
Copy link
Owner

const pubKey = Noble.getPublicKey(randomBytes)
=>
const pubKey = Noble.schnorr.getPublicKey(randomBytes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants