scalar.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // Copyright (c) 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package edwards25519
  5. import (
  6. "encoding/binary"
  7. "errors"
  8. )
  9. // A Scalar is an integer modulo
  10. //
  11. // l = 2^252 + 27742317777372353535851937790883648493
  12. //
  13. // which is the prime order of the edwards25519 group.
  14. //
  15. // This type works similarly to math/big.Int, and all arguments and
  16. // receivers are allowed to alias.
  17. //
  18. // The zero value is a valid zero element.
  19. type Scalar struct {
  20. // s is the scalar in the Montgomery domain, in the format of the
  21. // fiat-crypto implementation.
  22. s fiatScalarMontgomeryDomainFieldElement
  23. }
  24. // The field implementation in scalar_fiat.go is generated by the fiat-crypto
  25. // project (https://github.com/mit-plv/fiat-crypto) at version v0.0.9 (23d2dbc)
  26. // from a formally verified model.
  27. //
  28. // fiat-crypto code comes under the following license.
  29. //
  30. // Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved.
  31. //
  32. // Redistribution and use in source and binary forms, with or without
  33. // modification, are permitted provided that the following conditions are
  34. // met:
  35. //
  36. // 1. Redistributions of source code must retain the above copyright
  37. // notice, this list of conditions and the following disclaimer.
  38. //
  39. // THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
  40. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  41. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
  43. // Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  44. // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  45. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  46. // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  47. // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  48. // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50. //
  51. // NewScalar returns a new zero Scalar.
  52. func NewScalar() *Scalar {
  53. return &Scalar{}
  54. }
  55. // MultiplyAdd sets s = x * y + z mod l, and returns s. It is equivalent to
  56. // using Multiply and then Add.
  57. func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar {
  58. // Make a copy of z in case it aliases s.
  59. zCopy := new(Scalar).Set(z)
  60. return s.Multiply(x, y).Add(s, zCopy)
  61. }
  62. // Add sets s = x + y mod l, and returns s.
  63. func (s *Scalar) Add(x, y *Scalar) *Scalar {
  64. // s = 1 * x + y mod l
  65. fiatScalarAdd(&s.s, &x.s, &y.s)
  66. return s
  67. }
  68. // Subtract sets s = x - y mod l, and returns s.
  69. func (s *Scalar) Subtract(x, y *Scalar) *Scalar {
  70. // s = -1 * y + x mod l
  71. fiatScalarSub(&s.s, &x.s, &y.s)
  72. return s
  73. }
  74. // Negate sets s = -x mod l, and returns s.
  75. func (s *Scalar) Negate(x *Scalar) *Scalar {
  76. // s = -1 * x + 0 mod l
  77. fiatScalarOpp(&s.s, &x.s)
  78. return s
  79. }
  80. // Multiply sets s = x * y mod l, and returns s.
  81. func (s *Scalar) Multiply(x, y *Scalar) *Scalar {
  82. // s = x * y + 0 mod l
  83. fiatScalarMul(&s.s, &x.s, &y.s)
  84. return s
  85. }
  86. // Set sets s = x, and returns s.
  87. func (s *Scalar) Set(x *Scalar) *Scalar {
  88. *s = *x
  89. return s
  90. }
  91. // SetUniformBytes sets s = x mod l, where x is a 64-byte little-endian integer.
  92. // If x is not of the right length, SetUniformBytes returns nil and an error,
  93. // and the receiver is unchanged.
  94. //
  95. // SetUniformBytes can be used to set s to a uniformly distributed value given
  96. // 64 uniformly distributed random bytes.
  97. func (s *Scalar) SetUniformBytes(x []byte) (*Scalar, error) {
  98. if len(x) != 64 {
  99. return nil, errors.New("edwards25519: invalid SetUniformBytes input length")
  100. }
  101. // We have a value x of 512 bits, but our fiatScalarFromBytes function
  102. // expects an input lower than l, which is a little over 252 bits.
  103. //
  104. // Instead of writing a reduction function that operates on wider inputs, we
  105. // can interpret x as the sum of three shorter values a, b, and c.
  106. //
  107. // x = a + b * 2^168 + c * 2^336 mod l
  108. //
  109. // We then precompute 2^168 and 2^336 modulo l, and perform the reduction
  110. // with two multiplications and two additions.
  111. s.setShortBytes(x[:21])
  112. t := new(Scalar).setShortBytes(x[21:42])
  113. s.Add(s, t.Multiply(t, scalarTwo168))
  114. t.setShortBytes(x[42:])
  115. s.Add(s, t.Multiply(t, scalarTwo336))
  116. return s, nil
  117. }
  118. // scalarTwo168 and scalarTwo336 are 2^168 and 2^336 modulo l, encoded as a
  119. // fiatScalarMontgomeryDomainFieldElement, which is a little-endian 4-limb value
  120. // in the 2^256 Montgomery domain.
  121. var scalarTwo168 = &Scalar{s: [4]uint64{0x5b8ab432eac74798, 0x38afddd6de59d5d7,
  122. 0xa2c131b399411b7c, 0x6329a7ed9ce5a30}}
  123. var scalarTwo336 = &Scalar{s: [4]uint64{0xbd3d108e2b35ecc5, 0x5c3a3718bdf9c90b,
  124. 0x63aa97a331b4f2ee, 0x3d217f5be65cb5c}}
  125. // setShortBytes sets s = x mod l, where x is a little-endian integer shorter
  126. // than 32 bytes.
  127. func (s *Scalar) setShortBytes(x []byte) *Scalar {
  128. if len(x) >= 32 {
  129. panic("edwards25519: internal error: setShortBytes called with a long string")
  130. }
  131. var buf [32]byte
  132. copy(buf[:], x)
  133. fiatScalarFromBytes((*[4]uint64)(&s.s), &buf)
  134. fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
  135. return s
  136. }
  137. // SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of
  138. // s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes
  139. // returns nil and an error, and the receiver is unchanged.
  140. func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) {
  141. if len(x) != 32 {
  142. return nil, errors.New("invalid scalar length")
  143. }
  144. if !isReduced(x) {
  145. return nil, errors.New("invalid scalar encoding")
  146. }
  147. fiatScalarFromBytes((*[4]uint64)(&s.s), (*[32]byte)(x))
  148. fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
  149. return s, nil
  150. }
  151. // scalarMinusOneBytes is l - 1 in little endian.
  152. var scalarMinusOneBytes = [32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}
  153. // isReduced returns whether the given scalar in 32-byte little endian encoded
  154. // form is reduced modulo l.
  155. func isReduced(s []byte) bool {
  156. if len(s) != 32 {
  157. return false
  158. }
  159. for i := len(s) - 1; i >= 0; i-- {
  160. switch {
  161. case s[i] > scalarMinusOneBytes[i]:
  162. return false
  163. case s[i] < scalarMinusOneBytes[i]:
  164. return true
  165. }
  166. }
  167. return true
  168. }
  169. // SetBytesWithClamping applies the buffer pruning described in RFC 8032,
  170. // Section 5.1.5 (also known as clamping) and sets s to the result. The input
  171. // must be 32 bytes, and it is not modified. If x is not of the right length,
  172. // SetBytesWithClamping returns nil and an error, and the receiver is unchanged.
  173. //
  174. // Note that since Scalar values are always reduced modulo the prime order of
  175. // the curve, the resulting value will not preserve any of the cofactor-clearing
  176. // properties that clamping is meant to provide. It will however work as
  177. // expected as long as it is applied to points on the prime order subgroup, like
  178. // in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
  179. // irrelevant RFC 7748 clamping, but it is now required for compatibility.
  180. func (s *Scalar) SetBytesWithClamping(x []byte) (*Scalar, error) {
  181. // The description above omits the purpose of the high bits of the clamping
  182. // for brevity, but those are also lost to reductions, and are also
  183. // irrelevant to edwards25519 as they protect against a specific
  184. // implementation bug that was once observed in a generic Montgomery ladder.
  185. if len(x) != 32 {
  186. return nil, errors.New("edwards25519: invalid SetBytesWithClamping input length")
  187. }
  188. // We need to use the wide reduction from SetUniformBytes, since clamping
  189. // sets the 2^254 bit, making the value higher than the order.
  190. var wideBytes [64]byte
  191. copy(wideBytes[:], x[:])
  192. wideBytes[0] &= 248
  193. wideBytes[31] &= 63
  194. wideBytes[31] |= 64
  195. return s.SetUniformBytes(wideBytes[:])
  196. }
  197. // Bytes returns the canonical 32-byte little-endian encoding of s.
  198. func (s *Scalar) Bytes() []byte {
  199. // This function is outlined to make the allocations inline in the caller
  200. // rather than happen on the heap.
  201. var encoded [32]byte
  202. return s.bytes(&encoded)
  203. }
  204. func (s *Scalar) bytes(out *[32]byte) []byte {
  205. var ss fiatScalarNonMontgomeryDomainFieldElement
  206. fiatScalarFromMontgomery(&ss, &s.s)
  207. fiatScalarToBytes(out, (*[4]uint64)(&ss))
  208. return out[:]
  209. }
  210. // Equal returns 1 if s and t are equal, and 0 otherwise.
  211. func (s *Scalar) Equal(t *Scalar) int {
  212. var diff fiatScalarMontgomeryDomainFieldElement
  213. fiatScalarSub(&diff, &s.s, &t.s)
  214. var nonzero uint64
  215. fiatScalarNonzero(&nonzero, (*[4]uint64)(&diff))
  216. nonzero |= nonzero >> 32
  217. nonzero |= nonzero >> 16
  218. nonzero |= nonzero >> 8
  219. nonzero |= nonzero >> 4
  220. nonzero |= nonzero >> 2
  221. nonzero |= nonzero >> 1
  222. return int(^nonzero) & 1
  223. }
  224. // nonAdjacentForm computes a width-w non-adjacent form for this scalar.
  225. //
  226. // w must be between 2 and 8, or nonAdjacentForm will panic.
  227. func (s *Scalar) nonAdjacentForm(w uint) [256]int8 {
  228. // This implementation is adapted from the one
  229. // in curve25519-dalek and is documented there:
  230. // https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
  231. b := s.Bytes()
  232. if b[31] > 127 {
  233. panic("scalar has high bit set illegally")
  234. }
  235. if w < 2 {
  236. panic("w must be at least 2 by the definition of NAF")
  237. } else if w > 8 {
  238. panic("NAF digits must fit in int8")
  239. }
  240. var naf [256]int8
  241. var digits [5]uint64
  242. for i := 0; i < 4; i++ {
  243. digits[i] = binary.LittleEndian.Uint64(b[i*8:])
  244. }
  245. width := uint64(1 << w)
  246. windowMask := uint64(width - 1)
  247. pos := uint(0)
  248. carry := uint64(0)
  249. for pos < 256 {
  250. indexU64 := pos / 64
  251. indexBit := pos % 64
  252. var bitBuf uint64
  253. if indexBit < 64-w {
  254. // This window's bits are contained in a single u64
  255. bitBuf = digits[indexU64] >> indexBit
  256. } else {
  257. // Combine the current 64 bits with bits from the next 64
  258. bitBuf = (digits[indexU64] >> indexBit) | (digits[1+indexU64] << (64 - indexBit))
  259. }
  260. // Add carry into the current window
  261. window := carry + (bitBuf & windowMask)
  262. if window&1 == 0 {
  263. // If the window value is even, preserve the carry and continue.
  264. // Why is the carry preserved?
  265. // If carry == 0 and window & 1 == 0,
  266. // then the next carry should be 0
  267. // If carry == 1 and window & 1 == 0,
  268. // then bit_buf & 1 == 1 so the next carry should be 1
  269. pos += 1
  270. continue
  271. }
  272. if window < width/2 {
  273. carry = 0
  274. naf[pos] = int8(window)
  275. } else {
  276. carry = 1
  277. naf[pos] = int8(window) - int8(width)
  278. }
  279. pos += w
  280. }
  281. return naf
  282. }
  283. func (s *Scalar) signedRadix16() [64]int8 {
  284. b := s.Bytes()
  285. if b[31] > 127 {
  286. panic("scalar has high bit set illegally")
  287. }
  288. var digits [64]int8
  289. // Compute unsigned radix-16 digits:
  290. for i := 0; i < 32; i++ {
  291. digits[2*i] = int8(b[i] & 15)
  292. digits[2*i+1] = int8((b[i] >> 4) & 15)
  293. }
  294. // Recenter coefficients:
  295. for i := 0; i < 63; i++ {
  296. carry := (digits[i] + 8) >> 4
  297. digits[i] -= carry << 4
  298. digits[i+1] += carry
  299. }
  300. return digits
  301. }