Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

88 linhas
2.0 KiB

  1. package cln16sidh
  2. // Represents an element of the extension field F_{p^2}.
  3. type FieldElement struct {
  4. A Fp751Element
  5. B Fp751Element
  6. }
  7. func (dest *FieldElement) Mul(lhs, rhs *FieldElement) {
  8. // Let (a,b,c,d) = (lhs.A,lhs.B,rhs.A,rhs.B).
  9. a := &lhs.A
  10. b := &lhs.B
  11. c := &rhs.A
  12. d := &rhs.B
  13. // We want to compute
  14. //
  15. // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i
  16. //
  17. // Use Karatsuba's trick: note that
  18. //
  19. // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d
  20. //
  21. // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d.
  22. var ac, bd Fp751X2
  23. Fp751Mul(&ac, a, c)
  24. Fp751Mul(&bd, b, d)
  25. var b_minus_a, c_minus_d Fp751Element
  26. Fp751SubReduced(&b_minus_a, b, a)
  27. Fp751SubReduced(&c_minus_d, c, d)
  28. var ad_plus_bc Fp751X2
  29. Fp751Mul(&ad_plus_bc, &b_minus_a, &c_minus_d)
  30. Fp751X2AddLazy(&ad_plus_bc, &ad_plus_bc, &ac)
  31. Fp751X2AddLazy(&ad_plus_bc, &ad_plus_bc, &bd)
  32. Fp751Reduce(&dest.B, &ad_plus_bc)
  33. Fp751X2AddLazy(&ac, &ac, &bd)
  34. Fp751Reduce(&dest.A, &ac)
  35. }
  36. func (dest *FieldElement) Add(lhs, rhs *FieldElement) {
  37. Fp751AddReduced(&dest.A, &lhs.A, &rhs.A)
  38. Fp751AddReduced(&dest.B, &lhs.B, &rhs.B)
  39. }
  40. func (dest *FieldElement) Sub(lhs, rhs *FieldElement) {
  41. Fp751SubReduced(&dest.A, &lhs.A, &rhs.A)
  42. Fp751SubReduced(&dest.B, &lhs.B, &rhs.B)
  43. }
  44. const Fp751NumWords = 12
  45. // Represents an element of the base field F_p, in Montgomery form.
  46. type Fp751Element [Fp751NumWords]uint64
  47. // Represents an intermediate product of two elements of the base field F_p.
  48. type Fp751X2 [2 * Fp751NumWords]uint64
  49. // Compute z = x + y (mod p).
  50. //go:noescape
  51. func Fp751AddReduced(z, x, y *Fp751Element)
  52. // Compute z = x - y (mod p).
  53. //go:noescape
  54. func Fp751SubReduced(z, x, y *Fp751Element)
  55. // Compute z = x + y, without reducing mod p.
  56. //go:noescape
  57. func Fp751AddLazy(z, x, y *Fp751Element)
  58. // Compute z = x + y, without reducing mod p.
  59. //go:noescape
  60. func Fp751X2AddLazy(z, x, y *Fp751X2)
  61. // Compute z = x * y.
  62. //go:noescape
  63. func Fp751Mul(z *Fp751X2, x, y *Fp751Element)
  64. // Reduce an X2 to a field element: set z = x (mod p).
  65. // Destroys the input value.
  66. //go:noescape
  67. func Fp751Reduce(z *Fp751Element, x *Fp751X2)