rfc6979.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. const createHmac = require('create-hmac')
  2. const ONE1 = Buffer.alloc(1, 1)
  3. const ZERO1 = Buffer.alloc(1, 0)
  4. // https://tools.ietf.org/html/rfc6979#section-3.2
  5. function deterministicGenerateK (hash, x, checkSig, isPrivate, extraEntropy) {
  6. // Step A, ignored as hash already provided
  7. // Step B
  8. // Step C
  9. let k = Buffer.alloc(32, 0)
  10. let v = Buffer.alloc(32, 1)
  11. // Step D
  12. k = createHmac('sha256', k)
  13. .update(v)
  14. .update(ZERO1)
  15. .update(x)
  16. .update(hash)
  17. .update(extraEntropy || '')
  18. .digest()
  19. // Step E
  20. v = createHmac('sha256', k).update(v).digest()
  21. // Step F
  22. k = createHmac('sha256', k)
  23. .update(v)
  24. .update(ONE1)
  25. .update(x)
  26. .update(hash)
  27. .update(extraEntropy || '')
  28. .digest()
  29. // Step G
  30. v = createHmac('sha256', k).update(v).digest()
  31. // Step H1/H2a, ignored as tlen === qlen (256 bit)
  32. // Step H2b
  33. v = createHmac('sha256', k).update(v).digest()
  34. let T = v
  35. // Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA
  36. while (!isPrivate(T) || !checkSig(T)) {
  37. k = createHmac('sha256', k)
  38. .update(v)
  39. .update(ZERO1)
  40. .digest()
  41. v = createHmac('sha256', k).update(v).digest()
  42. // Step H1/H2a, again, ignored as tlen === qlen (256 bit)
  43. // Step H2b again
  44. v = createHmac('sha256', k).update(v).digest()
  45. T = v
  46. }
  47. return T
  48. }
  49. module.exports = deterministicGenerateK