gfp.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package bn256
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. type gfP [4]uint64
  7. func newGFp(x int64) (out *gfP) {
  8. if x >= 0 {
  9. out = &gfP{uint64(x)}
  10. } else {
  11. out = &gfP{uint64(-x)}
  12. gfpNeg(out, out)
  13. }
  14. montEncode(out, out)
  15. return out
  16. }
  17. func (e *gfP) String() string {
  18. return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0])
  19. }
  20. func (e *gfP) Set(f *gfP) {
  21. e[0] = f[0]
  22. e[1] = f[1]
  23. e[2] = f[2]
  24. e[3] = f[3]
  25. }
  26. func (e *gfP) Invert(f *gfP) {
  27. bits := [4]uint64{0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029}
  28. sum, power := &gfP{}, &gfP{}
  29. sum.Set(rN1)
  30. power.Set(f)
  31. for word := 0; word < 4; word++ {
  32. for bit := uint(0); bit < 64; bit++ {
  33. if (bits[word]>>bit)&1 == 1 {
  34. gfpMul(sum, sum, power)
  35. }
  36. gfpMul(power, power, power)
  37. }
  38. }
  39. gfpMul(sum, sum, r3)
  40. e.Set(sum)
  41. }
  42. func (e *gfP) Marshal(out []byte) {
  43. for w := uint(0); w < 4; w++ {
  44. for b := uint(0); b < 8; b++ {
  45. out[8*w+b] = byte(e[3-w] >> (56 - 8*b))
  46. }
  47. }
  48. }
  49. func (e *gfP) Unmarshal(in []byte) error {
  50. // Unmarshal the bytes into little endian form
  51. for w := uint(0); w < 4; w++ {
  52. for b := uint(0); b < 8; b++ {
  53. e[3-w] += uint64(in[8*w+b]) << (56 - 8*b)
  54. }
  55. }
  56. // Ensure the point respects the curve modulus
  57. for i := 3; i >= 0; i-- {
  58. if e[i] < p2[i] {
  59. return nil
  60. }
  61. if e[i] > p2[i] {
  62. return errors.New("bn256: coordinate exceeds modulus")
  63. }
  64. }
  65. return errors.New("bn256: coordinate equals modulus")
  66. }
  67. func montEncode(c, a *gfP) { gfpMul(c, a, r2) }
  68. func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) }