p256.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package p256
  2. import (
  3. "crypto/elliptic"
  4. "errors"
  5. "math/big"
  6. "filippo.io/bigmod"
  7. "golang.org/x/crypto/cryptobyte"
  8. "golang.org/x/crypto/cryptobyte/asn1"
  9. )
  10. var halfN = new(big.Int).Rsh(elliptic.P256().Params().N, 1)
  11. var nMod *bigmod.Modulus
  12. func init() {
  13. n, err := bigmod.NewModulus(elliptic.P256().Params().N.Bytes())
  14. if err != nil {
  15. panic(err)
  16. }
  17. nMod = n
  18. }
  19. func IsNormalized(sig []byte) (bool, error) {
  20. r, s, err := parseSignature(sig)
  21. if err != nil {
  22. return false, err
  23. }
  24. return checkLowS(r, s), nil
  25. }
  26. func checkLowS(_, s []byte) bool {
  27. bigS := new(big.Int).SetBytes(s)
  28. // Check if S <= (N/2), because we want to include the midpoint in the set of low-s
  29. return bigS.Cmp(halfN) <= 0
  30. }
  31. func swap(r, s []byte) ([]byte, []byte, error) {
  32. var err error
  33. bigS, err := bigmod.NewNat().SetBytes(s, nMod)
  34. if err != nil {
  35. return nil, nil, err
  36. }
  37. sNormalized := nMod.Nat().Sub(bigS, nMod)
  38. result := sNormalized.Bytes(nMod)
  39. for len(result) > 1 && result[0] == 0 {
  40. result = result[1:]
  41. }
  42. return r, result, nil
  43. }
  44. func Normalize(sig []byte) ([]byte, error) {
  45. r, s, err := parseSignature(sig)
  46. if err != nil {
  47. return nil, err
  48. }
  49. if checkLowS(r, s) {
  50. return sig, nil
  51. }
  52. newR, newS, err := swap(r, s)
  53. if err != nil {
  54. return nil, err
  55. }
  56. return encodeSignature(newR, newS)
  57. }
  58. // Swap will change sig between its current form to the opposite high or low form.
  59. func Swap(sig []byte) ([]byte, error) {
  60. r, s, err := parseSignature(sig)
  61. if err != nil {
  62. return nil, err
  63. }
  64. newR, newS, err := swap(r, s)
  65. if err != nil {
  66. return nil, err
  67. }
  68. return encodeSignature(newR, newS)
  69. }
  70. // parseSignature taken exactly from crypto/ecdsa/ecdsa.go
  71. func parseSignature(sig []byte) (r, s []byte, err error) {
  72. var inner cryptobyte.String
  73. input := cryptobyte.String(sig)
  74. if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
  75. !input.Empty() ||
  76. !inner.ReadASN1Integer(&r) ||
  77. !inner.ReadASN1Integer(&s) ||
  78. !inner.Empty() {
  79. return nil, nil, errors.New("invalid ASN.1")
  80. }
  81. return r, s, nil
  82. }
  83. func encodeSignature(r, s []byte) ([]byte, error) {
  84. var b cryptobyte.Builder
  85. b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
  86. addASN1IntBytes(b, r)
  87. addASN1IntBytes(b, s)
  88. })
  89. return b.Bytes()
  90. }
  91. // addASN1IntBytes encodes in ASN.1 a positive integer represented as
  92. // a big-endian byte slice with zero or more leading zeroes.
  93. func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
  94. for len(bytes) > 0 && bytes[0] == 0 {
  95. bytes = bytes[1:]
  96. }
  97. if len(bytes) == 0 {
  98. b.SetError(errors.New("invalid integer"))
  99. return
  100. }
  101. b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
  102. if bytes[0]&0x80 != 0 {
  103. c.AddUint8(0)
  104. }
  105. c.AddBytes(bytes)
  106. })
  107. }