x448.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // The MIT License (MIT)
  2. //
  3. // Copyright (c) 2011 Stanford University.
  4. // Copyright (c) 2014-2015 Cryptography Research, Inc.
  5. // Copyright (c) 2015 Yawning Angel.
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. // Package x448 provides an implementation of scalar multiplication on the
  25. // elliptic curve known as curve448.
  26. //
  27. // See https://tools.ietf.org/html/draft-irtf-cfrg-curves-11
  28. package x448 // import "git.schwanenlied.me/yawning/x448.git"
  29. const (
  30. x448Bytes = 56
  31. edwardsD = -39081
  32. )
  33. var basePoint = [56]byte{
  34. 5, 0, 0, 0, 0, 0,
  35. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  36. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  37. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  38. }
  39. func ScalarMult(out, scalar, base *[56]byte) int {
  40. var x1, x2, z2, x3, z3, t1, t2 gf
  41. x1.deser(base)
  42. x2.cpy(&one)
  43. z2.cpy(&zero)
  44. x3.cpy(&x1)
  45. z3.cpy(&one)
  46. var swap limbUint
  47. for t := int(448 - 1); t >= 0; t-- {
  48. sb := scalar[t/8]
  49. // Scalar conditioning.
  50. if t/8 == 0 {
  51. sb &= 0xFC
  52. } else if t/8 == x448Bytes-1 {
  53. sb |= 0x80
  54. }
  55. kT := (limbUint)((sb >> ((uint)(t) % 8)) & 1)
  56. kT = -kT // Set to all 0s or all 1s
  57. swap ^= kT
  58. x2.condSwap(&x3, swap)
  59. z2.condSwap(&z3, swap)
  60. swap = kT
  61. t1.add(&x2, &z2) // A = x2 + z2
  62. t2.sub(&x2, &z2) // B = x2 - z2
  63. z2.sub(&x3, &z3) // D = x3 - z3
  64. x2.mul(&t1, &z2) // DA
  65. z2.add(&z3, &x3) // C = x3 + z3
  66. x3.mul(&t2, &z2) // CB
  67. z3.sub(&x2, &x3) // DA-CB
  68. z2.sqr(&z3) // (DA-CB)^2
  69. z3.mul(&x1, &z2) // z3 = x1(DA-CB)^2
  70. z2.add(&x2, &x3) // (DA+CB)
  71. x3.sqr(&z2) // x3 = (DA+CB)^2
  72. z2.sqr(&t1) // AA = A^2
  73. t1.sqr(&t2) // BB = B^2
  74. x2.mul(&z2, &t1) // x2 = AA*BB
  75. t2.sub(&z2, &t1) // E = AA-BB
  76. t1.mlw(&t2, -edwardsD) // E*-d = a24*E
  77. t1.add(&t1, &z2) // AA + a24*E
  78. z2.mul(&t2, &t1) // z2 = E(AA+a24*E)
  79. }
  80. // Finish
  81. x2.condSwap(&x3, swap)
  82. z2.condSwap(&x3, swap)
  83. z2.inv(&z2)
  84. x1.mul(&x2, &z2)
  85. x1.ser(out)
  86. // As with X25519, both sides MUST check, without leaking extra
  87. // information about the value of K, whether the resulting shared K is
  88. // the all-zero value and abort if so.
  89. var nz limbSint
  90. for _, v := range out {
  91. nz |= (limbSint)(v)
  92. }
  93. nz = (nz - 1) >> 8 // 0 = succ, -1 = fail
  94. // return value: 0 = succ, -1 = fail
  95. return (int)(nz)
  96. }
  97. func ScalarBaseMult(out, scalar *[56]byte) int {
  98. return ScalarMult(out, scalar, &basePoint)
  99. }