You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3053 lines
72 KiB

  1. // Copyright 2013 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-BSD file.
  4. // Most of this is from the golang x/crypto package
  5. // Package edwards25519 implements operations in GF(2**255-19) and on an
  6. // Edwards curve that is isomorphic to curve25519. See
  7. // http://ed25519.cr.yp.to/.
  8. // move this file out of this package and use x/crypto
  9. package ringct
  10. // This code is a port of the public domain, "ref10" implementation of ed25519
  11. // from SUPERCOP.
  12. // FieldElement represents an element of the field GF(2^255 - 19). An element
  13. // t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
  14. // t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
  15. // context.
  16. type FieldElement [10]int32
  17. var FeMa = FieldElement{-486662, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* -A */
  18. var FeMa2 = FieldElement{-12721188, -3529, 0, 0, 0, 0, 0, 0, 0, 0} /* -A^2 */
  19. var FeFffb1 = FieldElement{-31702527, -2466483, -26106795, -12203692, -12169197, -321052, 14850977, -10296299, -16929438, -407568} /* sqrt(-2 * A * (A + 2)) */
  20. var FeFffb2 = FieldElement{8166131, -6741800, -17040804, 3154616, 21461005, 1466302, -30876704, -6368709, 10503587, -13363080} /* sqrt(2 * A * (A + 2)) */
  21. var FeFffb3 = FieldElement{-13620103, 14639558, 4532995, 7679154, 16815101, -15883539, -22863840, -14813421, 13716513, -6477756} /* sqrt(-sqrt(-1) * A * (A + 2)) */
  22. var FeFffb4 = FieldElement{-21786234, -12173074, 21573800, 4524538, -4645904, 16204591, 8012863, -8444712, 3212926, 6885324} /* sqrt(sqrt(-1) * A * (A + 2)) */
  23. var FeSqrtM1 = FieldElement{-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482} /* sqrt(-1) */
  24. var zero FieldElement
  25. var one FieldElement
  26. func init() {
  27. one[0] = 1
  28. }
  29. func (f *FieldElement) Zero() {
  30. copy(f[:], zero[:])
  31. }
  32. func (f *FieldElement) One() {
  33. copy(f[:], one[:])
  34. }
  35. func FeAdd(dst, a, b *FieldElement) {
  36. dst[0] = a[0] + b[0]
  37. dst[1] = a[1] + b[1]
  38. dst[2] = a[2] + b[2]
  39. dst[3] = a[3] + b[3]
  40. dst[4] = a[4] + b[4]
  41. dst[5] = a[5] + b[5]
  42. dst[6] = a[6] + b[6]
  43. dst[7] = a[7] + b[7]
  44. dst[8] = a[8] + b[8]
  45. dst[9] = a[9] + b[9]
  46. }
  47. func FeSub(dst, a, b *FieldElement) {
  48. dst[0] = a[0] - b[0]
  49. dst[1] = a[1] - b[1]
  50. dst[2] = a[2] - b[2]
  51. dst[3] = a[3] - b[3]
  52. dst[4] = a[4] - b[4]
  53. dst[5] = a[5] - b[5]
  54. dst[6] = a[6] - b[6]
  55. dst[7] = a[7] - b[7]
  56. dst[8] = a[8] - b[8]
  57. dst[9] = a[9] - b[9]
  58. }
  59. func FeCopy(dst, src *FieldElement) {
  60. copy(dst[:], src[:])
  61. }
  62. // Replace (f,g) with (g,g) if b == 1;
  63. // replace (f,g) with (f,g) if b == 0.
  64. //
  65. // Preconditions: b in {0,1}.
  66. func FeCMove(f, g *FieldElement, b int32) {
  67. b = -b
  68. f[0] ^= b & (f[0] ^ g[0])
  69. f[1] ^= b & (f[1] ^ g[1])
  70. f[2] ^= b & (f[2] ^ g[2])
  71. f[3] ^= b & (f[3] ^ g[3])
  72. f[4] ^= b & (f[4] ^ g[4])
  73. f[5] ^= b & (f[5] ^ g[5])
  74. f[6] ^= b & (f[6] ^ g[6])
  75. f[7] ^= b & (f[7] ^ g[7])
  76. f[8] ^= b & (f[8] ^ g[8])
  77. f[9] ^= b & (f[9] ^ g[9])
  78. }
  79. func load3(in []byte) (result int64) {
  80. result = int64(in[0]) | (int64(in[1]) << 8) | (int64(in[2]) << 16)
  81. return
  82. }
  83. func load4(in []byte) (result int64) {
  84. result = int64(in[0]) | (int64(in[1]) << 8) | (int64(in[2]) << 16) | (int64(in[3]) << 24)
  85. return
  86. }
  87. func FeFromBytes(dst *FieldElement, src *Key) {
  88. h0 := load4(src[:])
  89. h1 := load3(src[4:]) << 6
  90. h2 := load3(src[7:]) << 5
  91. h3 := load3(src[10:]) << 3
  92. h4 := load3(src[13:]) << 2
  93. h5 := load4(src[16:])
  94. h6 := load3(src[20:]) << 7
  95. h7 := load3(src[23:]) << 5
  96. h8 := load3(src[26:]) << 4
  97. h9 := (load3(src[29:]) & 8388607) << 2
  98. FeCombine(dst, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
  99. }
  100. // FeToBytes marshals h to s.
  101. // Preconditions:
  102. // |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
  103. //
  104. // Write p=2^255-19; q=floor(h/p).
  105. // Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
  106. //
  107. // Proof:
  108. // Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
  109. // Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
  110. //
  111. // Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
  112. // Then 0<y<1.
  113. //
  114. // Write r=h-pq.
  115. // Have 0<=r<=p-1=2^255-20.
  116. // Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
  117. //
  118. // Write x=r+19(2^-255)r+y.
  119. // Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
  120. //
  121. // Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
  122. // so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
  123. func FeToBytes(s *Key, h *FieldElement) {
  124. var carry [10]int32
  125. q := (19*h[9] + (1 << 24)) >> 25
  126. q = (h[0] + q) >> 26
  127. q = (h[1] + q) >> 25
  128. q = (h[2] + q) >> 26
  129. q = (h[3] + q) >> 25
  130. q = (h[4] + q) >> 26
  131. q = (h[5] + q) >> 25
  132. q = (h[6] + q) >> 26
  133. q = (h[7] + q) >> 25
  134. q = (h[8] + q) >> 26
  135. q = (h[9] + q) >> 25
  136. // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
  137. h[0] += 19 * q
  138. // Goal: Output h-2^255 q, which is between 0 and 2^255-20.
  139. carry[0] = h[0] >> 26
  140. h[1] += carry[0]
  141. h[0] -= carry[0] << 26
  142. carry[1] = h[1] >> 25
  143. h[2] += carry[1]
  144. h[1] -= carry[1] << 25
  145. carry[2] = h[2] >> 26
  146. h[3] += carry[2]
  147. h[2] -= carry[2] << 26
  148. carry[3] = h[3] >> 25
  149. h[4] += carry[3]
  150. h[3] -= carry[3] << 25
  151. carry[4] = h[4] >> 26
  152. h[5] += carry[4]
  153. h[4] -= carry[4] << 26
  154. carry[5] = h[5] >> 25
  155. h[6] += carry[5]
  156. h[5] -= carry[5] << 25
  157. carry[6] = h[6] >> 26
  158. h[7] += carry[6]
  159. h[6] -= carry[6] << 26
  160. carry[7] = h[7] >> 25
  161. h[8] += carry[7]
  162. h[7] -= carry[7] << 25
  163. carry[8] = h[8] >> 26
  164. h[9] += carry[8]
  165. h[8] -= carry[8] << 26
  166. carry[9] = h[9] >> 25
  167. h[9] -= carry[9] << 25
  168. // h10 = carry9
  169. // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
  170. // Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
  171. // evidently 2^255 h10-2^255 q = 0.
  172. // Goal: Output h[0]+...+2^230 h[9].
  173. s[0] = byte(h[0] >> 0)
  174. s[1] = byte(h[0] >> 8)
  175. s[2] = byte(h[0] >> 16)
  176. s[3] = byte((h[0] >> 24) | (h[1] << 2))
  177. s[4] = byte(h[1] >> 6)
  178. s[5] = byte(h[1] >> 14)
  179. s[6] = byte((h[1] >> 22) | (h[2] << 3))
  180. s[7] = byte(h[2] >> 5)
  181. s[8] = byte(h[2] >> 13)
  182. s[9] = byte((h[2] >> 21) | (h[3] << 5))
  183. s[10] = byte(h[3] >> 3)
  184. s[11] = byte(h[3] >> 11)
  185. s[12] = byte((h[3] >> 19) | (h[4] << 6))
  186. s[13] = byte(h[4] >> 2)
  187. s[14] = byte(h[4] >> 10)
  188. s[15] = byte(h[4] >> 18)
  189. s[16] = byte(h[5] >> 0)
  190. s[17] = byte(h[5] >> 8)
  191. s[18] = byte(h[5] >> 16)
  192. s[19] = byte((h[5] >> 24) | (h[6] << 1))
  193. s[20] = byte(h[6] >> 7)
  194. s[21] = byte(h[6] >> 15)
  195. s[22] = byte((h[6] >> 23) | (h[7] << 3))
  196. s[23] = byte(h[7] >> 5)
  197. s[24] = byte(h[7] >> 13)
  198. s[25] = byte((h[7] >> 21) | (h[8] << 4))
  199. s[26] = byte(h[8] >> 4)
  200. s[27] = byte(h[8] >> 12)
  201. s[28] = byte((h[8] >> 20) | (h[9] << 6))
  202. s[29] = byte(h[9] >> 2)
  203. s[30] = byte(h[9] >> 10)
  204. s[31] = byte(h[9] >> 18)
  205. }
  206. func (f *FieldElement) IsNegative() byte {
  207. var s Key
  208. FeToBytes(&s, f)
  209. return s[0] & 1
  210. }
  211. func (f *FieldElement) IsNonZero() int32 {
  212. var s Key
  213. FeToBytes(&s, f)
  214. var x uint8
  215. for _, b := range s {
  216. x |= b
  217. }
  218. x |= x >> 4
  219. x |= x >> 2
  220. x |= x >> 1
  221. return int32(x & 1)
  222. }
  223. // FeNeg sets h = -f
  224. //
  225. // Preconditions:
  226. // |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
  227. //
  228. // Postconditions:
  229. // |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
  230. func FeNeg(h, f *FieldElement) {
  231. h[0] = -f[0]
  232. h[1] = -f[1]
  233. h[2] = -f[2]
  234. h[3] = -f[3]
  235. h[4] = -f[4]
  236. h[5] = -f[5]
  237. h[6] = -f[6]
  238. h[7] = -f[7]
  239. h[8] = -f[8]
  240. h[9] = -f[9]
  241. }
  242. func FeCombine(h *FieldElement, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) {
  243. var c0, c1, c2, c3, c4, c5, c6, c7, c8, c9 int64
  244. /*
  245. |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
  246. i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
  247. |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
  248. i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
  249. */
  250. c0 = (h0 + (1 << 25)) >> 26
  251. h1 += c0
  252. h0 -= c0 << 26
  253. c4 = (h4 + (1 << 25)) >> 26
  254. h5 += c4
  255. h4 -= c4 << 26
  256. /* |h0| <= 2^25 */
  257. /* |h4| <= 2^25 */
  258. /* |h1| <= 1.51*2^58 */
  259. /* |h5| <= 1.51*2^58 */
  260. c1 = (h1 + (1 << 24)) >> 25
  261. h2 += c1
  262. h1 -= c1 << 25
  263. c5 = (h5 + (1 << 24)) >> 25
  264. h6 += c5
  265. h5 -= c5 << 25
  266. /* |h1| <= 2^24; from now on fits into int32 */
  267. /* |h5| <= 2^24; from now on fits into int32 */
  268. /* |h2| <= 1.21*2^59 */
  269. /* |h6| <= 1.21*2^59 */
  270. c2 = (h2 + (1 << 25)) >> 26
  271. h3 += c2
  272. h2 -= c2 << 26
  273. c6 = (h6 + (1 << 25)) >> 26
  274. h7 += c6
  275. h6 -= c6 << 26
  276. /* |h2| <= 2^25; from now on fits into int32 unchanged */
  277. /* |h6| <= 2^25; from now on fits into int32 unchanged */
  278. /* |h3| <= 1.51*2^58 */
  279. /* |h7| <= 1.51*2^58 */
  280. c3 = (h3 + (1 << 24)) >> 25
  281. h4 += c3
  282. h3 -= c3 << 25
  283. c7 = (h7 + (1 << 24)) >> 25
  284. h8 += c7
  285. h7 -= c7 << 25
  286. /* |h3| <= 2^24; from now on fits into int32 unchanged */
  287. /* |h7| <= 2^24; from now on fits into int32 unchanged */
  288. /* |h4| <= 1.52*2^33 */
  289. /* |h8| <= 1.52*2^33 */
  290. c4 = (h4 + (1 << 25)) >> 26
  291. h5 += c4
  292. h4 -= c4 << 26
  293. c8 = (h8 + (1 << 25)) >> 26
  294. h9 += c8
  295. h8 -= c8 << 26
  296. /* |h4| <= 2^25; from now on fits into int32 unchanged */
  297. /* |h8| <= 2^25; from now on fits into int32 unchanged */
  298. /* |h5| <= 1.01*2^24 */
  299. /* |h9| <= 1.51*2^58 */
  300. c9 = (h9 + (1 << 24)) >> 25
  301. h0 += c9 * 19
  302. h9 -= c9 << 25
  303. /* |h9| <= 2^24; from now on fits into int32 unchanged */
  304. /* |h0| <= 1.8*2^37 */
  305. c0 = (h0 + (1 << 25)) >> 26
  306. h1 += c0
  307. h0 -= c0 << 26
  308. /* |h0| <= 2^25; from now on fits into int32 unchanged */
  309. /* |h1| <= 1.01*2^24 */
  310. h[0] = int32(h0)
  311. h[1] = int32(h1)
  312. h[2] = int32(h2)
  313. h[3] = int32(h3)
  314. h[4] = int32(h4)
  315. h[5] = int32(h5)
  316. h[6] = int32(h6)
  317. h[7] = int32(h7)
  318. h[8] = int32(h8)
  319. h[9] = int32(h9)
  320. }
  321. // FeMul calculates h = f * g
  322. // Can overlap h with f or g.
  323. //
  324. // Preconditions:
  325. // |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
  326. // |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
  327. //
  328. // Postconditions:
  329. // |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
  330. //
  331. // Notes on implementation strategy:
  332. //
  333. // Using schoolbook multiplication.
  334. // Karatsuba would save a little in some cost models.
  335. //
  336. // Most multiplications by 2 and 19 are 32-bit precomputations;
  337. // cheaper than 64-bit postcomputations.
  338. //
  339. // There is one remaining multiplication by 19 in the carry chain;
  340. // one *19 precomputation can be merged into this,
  341. // but the resulting data flow is considerably less clean.
  342. //
  343. // There are 12 carries below.
  344. // 10 of them are 2-way parallelizable and vectorizable.
  345. // Can get away with 11 carries, but then data flow is much deeper.
  346. //
  347. // With tighter constraints on inputs can squeeze carries into int32.
  348. func FeMul(h, f, g *FieldElement) {
  349. f0 := int64(f[0])
  350. f1 := int64(f[1])
  351. f2 := int64(f[2])
  352. f3 := int64(f[3])
  353. f4 := int64(f[4])
  354. f5 := int64(f[5])
  355. f6 := int64(f[6])
  356. f7 := int64(f[7])
  357. f8 := int64(f[8])
  358. f9 := int64(f[9])
  359. f1_2 := int64(2 * f[1])
  360. f3_2 := int64(2 * f[3])
  361. f5_2 := int64(2 * f[5])
  362. f7_2 := int64(2 * f[7])
  363. f9_2 := int64(2 * f[9])
  364. g0 := int64(g[0])
  365. g1 := int64(g[1])
  366. g2 := int64(g[2])
  367. g3 := int64(g[3])
  368. g4 := int64(g[4])
  369. g5 := int64(g[5])
  370. g6 := int64(g[6])
  371. g7 := int64(g[7])
  372. g8 := int64(g[8])
  373. g9 := int64(g[9])
  374. g1_19 := int64(19 * g[1]) /* 1.4*2^29 */
  375. g2_19 := int64(19 * g[2]) /* 1.4*2^30; still ok */
  376. g3_19 := int64(19 * g[3])
  377. g4_19 := int64(19 * g[4])
  378. g5_19 := int64(19 * g[5])
  379. g6_19 := int64(19 * g[6])
  380. g7_19 := int64(19 * g[7])
  381. g8_19 := int64(19 * g[8])
  382. g9_19 := int64(19 * g[9])
  383. h0 := f0*g0 + f1_2*g9_19 + f2*g8_19 + f3_2*g7_19 + f4*g6_19 + f5_2*g5_19 + f6*g4_19 + f7_2*g3_19 + f8*g2_19 + f9_2*g1_19
  384. h1 := f0*g1 + f1*g0 + f2*g9_19 + f3*g8_19 + f4*g7_19 + f5*g6_19 + f6*g5_19 + f7*g4_19 + f8*g3_19 + f9*g2_19
  385. h2 := f0*g2 + f1_2*g1 + f2*g0 + f3_2*g9_19 + f4*g8_19 + f5_2*g7_19 + f6*g6_19 + f7_2*g5_19 + f8*g4_19 + f9_2*g3_19
  386. h3 := f0*g3 + f1*g2 + f2*g1 + f3*g0 + f4*g9_19 + f5*g8_19 + f6*g7_19 + f7*g6_19 + f8*g5_19 + f9*g4_19
  387. h4 := f0*g4 + f1_2*g3 + f2*g2 + f3_2*g1 + f4*g0 + f5_2*g9_19 + f6*g8_19 + f7_2*g7_19 + f8*g6_19 + f9_2*g5_19
  388. h5 := f0*g5 + f1*g4 + f2*g3 + f3*g2 + f4*g1 + f5*g0 + f6*g9_19 + f7*g8_19 + f8*g7_19 + f9*g6_19
  389. h6 := f0*g6 + f1_2*g5 + f2*g4 + f3_2*g3 + f4*g2 + f5_2*g1 + f6*g0 + f7_2*g9_19 + f8*g8_19 + f9_2*g7_19
  390. h7 := f0*g7 + f1*g6 + f2*g5 + f3*g4 + f4*g3 + f5*g2 + f6*g1 + f7*g0 + f8*g9_19 + f9*g8_19
  391. h8 := f0*g8 + f1_2*g7 + f2*g6 + f3_2*g5 + f4*g4 + f5_2*g3 + f6*g2 + f7_2*g1 + f8*g0 + f9_2*g9_19
  392. h9 := f0*g9 + f1*g8 + f2*g7 + f3*g6 + f4*g5 + f5*g4 + f6*g3 + f7*g2 + f8*g1 + f9*g0
  393. FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
  394. }
  395. func feSquare(f *FieldElement) (h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) {
  396. f0 := int64(f[0])
  397. f1 := int64(f[1])
  398. f2 := int64(f[2])
  399. f3 := int64(f[3])
  400. f4 := int64(f[4])
  401. f5 := int64(f[5])
  402. f6 := int64(f[6])
  403. f7 := int64(f[7])
  404. f8 := int64(f[8])
  405. f9 := int64(f[9])
  406. f0_2 := int64(2 * f[0])
  407. f1_2 := int64(2 * f[1])
  408. f2_2 := int64(2 * f[2])
  409. f3_2 := int64(2 * f[3])
  410. f4_2 := int64(2 * f[4])
  411. f5_2 := int64(2 * f[5])
  412. f6_2 := int64(2 * f[6])
  413. f7_2 := int64(2 * f[7])
  414. f5_38 := 38 * f5 // 1.31*2^30
  415. f6_19 := 19 * f6 // 1.31*2^30
  416. f7_38 := 38 * f7 // 1.31*2^30
  417. f8_19 := 19 * f8 // 1.31*2^30
  418. f9_38 := 38 * f9 // 1.31*2^30
  419. h0 = f0*f0 + f1_2*f9_38 + f2_2*f8_19 + f3_2*f7_38 + f4_2*f6_19 + f5*f5_38
  420. h1 = f0_2*f1 + f2*f9_38 + f3_2*f8_19 + f4*f7_38 + f5_2*f6_19
  421. h2 = f0_2*f2 + f1_2*f1 + f3_2*f9_38 + f4_2*f8_19 + f5_2*f7_38 + f6*f6_19
  422. h3 = f0_2*f3 + f1_2*f2 + f4*f9_38 + f5_2*f8_19 + f6*f7_38
  423. h4 = f0_2*f4 + f1_2*f3_2 + f2*f2 + f5_2*f9_38 + f6_2*f8_19 + f7*f7_38
  424. h5 = f0_2*f5 + f1_2*f4 + f2_2*f3 + f6*f9_38 + f7_2*f8_19
  425. h6 = f0_2*f6 + f1_2*f5_2 + f2_2*f4 + f3_2*f3 + f7_2*f9_38 + f8*f8_19
  426. h7 = f0_2*f7 + f1_2*f6 + f2_2*f5 + f3_2*f4 + f8*f9_38
  427. h8 = f0_2*f8 + f1_2*f7_2 + f2_2*f6 + f3_2*f5_2 + f4*f4 + f9*f9_38
  428. h9 = f0_2*f9 + f1_2*f8 + f2_2*f7 + f3_2*f6 + f4_2*f5
  429. return
  430. }
  431. // FeSquare calculates h = f*f. Can overlap h with f.
  432. //
  433. // Preconditions:
  434. // |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
  435. //
  436. // Postconditions:
  437. // |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
  438. func FeSquare(h, f *FieldElement) {
  439. h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f)
  440. FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
  441. }
  442. // FeSquare2 sets h = 2 * f * f
  443. //
  444. // Can overlap h with f.
  445. //
  446. // Preconditions:
  447. // |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
  448. //
  449. // Postconditions:
  450. // |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
  451. // See fe_mul.c for discussion of implementation strategy.
  452. func FeSquare2(h, f *FieldElement) {
  453. h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f)
  454. h0 += h0
  455. h1 += h1
  456. h2 += h2
  457. h3 += h3
  458. h4 += h4
  459. h5 += h5
  460. h6 += h6
  461. h7 += h7
  462. h8 += h8
  463. h9 += h9
  464. FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
  465. }
  466. func FeInvert(out, z *FieldElement) {
  467. var t0, t1, t2, t3 FieldElement
  468. var i int
  469. FeSquare(&t0, z) // 2^1
  470. FeSquare(&t1, &t0) // 2^2
  471. for i = 1; i < 2; i++ { // 2^3
  472. FeSquare(&t1, &t1)
  473. }
  474. FeMul(&t1, z, &t1) // 2^3 + 2^0
  475. FeMul(&t0, &t0, &t1) // 2^3 + 2^1 + 2^0
  476. FeSquare(&t2, &t0) // 2^4 + 2^2 + 2^1
  477. FeMul(&t1, &t1, &t2) // 2^4 + 2^3 + 2^2 + 2^1 + 2^0
  478. FeSquare(&t2, &t1) // 5,4,3,2,1
  479. for i = 1; i < 5; i++ { // 9,8,7,6,5
  480. FeSquare(&t2, &t2)
  481. }
  482. FeMul(&t1, &t2, &t1) // 9,8,7,6,5,4,3,2,1,0
  483. FeSquare(&t2, &t1) // 10..1
  484. for i = 1; i < 10; i++ { // 19..10
  485. FeSquare(&t2, &t2)
  486. }
  487. FeMul(&t2, &t2, &t1) // 19..0
  488. FeSquare(&t3, &t2) // 20..1
  489. for i = 1; i < 20; i++ { // 39..20
  490. FeSquare(&t3, &t3)
  491. }
  492. FeMul(&t2, &t3, &t2) // 39..0
  493. FeSquare(&t2, &t2) // 40..1
  494. for i = 1; i < 10; i++ { // 49..10
  495. FeSquare(&t2, &t2)
  496. }
  497. FeMul(&t1, &t2, &t1) // 49..0
  498. FeSquare(&t2, &t1) // 50..1
  499. for i = 1; i < 50; i++ { // 99..50
  500. FeSquare(&t2, &t2)
  501. }
  502. FeMul(&t2, &t2, &t1) // 99..0
  503. FeSquare(&t3, &t2) // 100..1
  504. for i = 1; i < 100; i++ { // 199..100
  505. FeSquare(&t3, &t3)
  506. }
  507. FeMul(&t2, &t3, &t2) // 199..0
  508. FeSquare(&t2, &t2) // 200..1
  509. for i = 1; i < 50; i++ { // 249..50
  510. FeSquare(&t2, &t2)
  511. }
  512. FeMul(&t1, &t2, &t1) // 249..0
  513. FeSquare(&t1, &t1) // 250..1
  514. for i = 1; i < 5; i++ { // 254..5
  515. FeSquare(&t1, &t1)
  516. }
  517. FeMul(out, &t1, &t0) // 254..5,3,1,0
  518. }
  519. func fePow22523(out, z *FieldElement) {
  520. var t0, t1, t2 FieldElement
  521. var i int
  522. FeSquare(&t0, z)
  523. for i = 1; i < 1; i++ {
  524. FeSquare(&t0, &t0)
  525. }
  526. FeSquare(&t1, &t0)
  527. for i = 1; i < 2; i++ {
  528. FeSquare(&t1, &t1)
  529. }
  530. FeMul(&t1, z, &t1)
  531. FeMul(&t0, &t0, &t1)
  532. FeSquare(&t0, &t0)
  533. for i = 1; i < 1; i++ {
  534. FeSquare(&t0, &t0)
  535. }
  536. FeMul(&t0, &t1, &t0)
  537. FeSquare(&t1, &t0)
  538. for i = 1; i < 5; i++ {
  539. FeSquare(&t1, &t1)
  540. }
  541. FeMul(&t0, &t1, &t0)
  542. FeSquare(&t1, &t0)
  543. for i = 1; i < 10; i++ {
  544. FeSquare(&t1, &t1)
  545. }
  546. FeMul(&t1, &t1, &t0)
  547. FeSquare(&t2, &t1)
  548. for i = 1; i < 20; i++ {
  549. FeSquare(&t2, &t2)
  550. }
  551. FeMul(&t1, &t2, &t1)
  552. FeSquare(&t1, &t1)
  553. for i = 1; i < 10; i++ {
  554. FeSquare(&t1, &t1)
  555. }
  556. FeMul(&t0, &t1, &t0)
  557. FeSquare(&t1, &t0)
  558. for i = 1; i < 50; i++ {
  559. FeSquare(&t1, &t1)
  560. }
  561. FeMul(&t1, &t1, &t0)
  562. FeSquare(&t2, &t1)
  563. for i = 1; i < 100; i++ {
  564. FeSquare(&t2, &t2)
  565. }
  566. FeMul(&t1, &t2, &t1)
  567. FeSquare(&t1, &t1)
  568. for i = 1; i < 50; i++ {
  569. FeSquare(&t1, &t1)
  570. }
  571. FeMul(&t0, &t1, &t0)
  572. FeSquare(&t0, &t0)
  573. for i = 1; i < 2; i++ {
  574. FeSquare(&t0, &t0)
  575. }
  576. FeMul(out, &t0, z)
  577. }
  578. func FeDivPowM1(out, u, v *FieldElement) {
  579. var v3, uv7, t0 FieldElement
  580. FeSquare(&v3, v)
  581. FeMul(&v3, &v3, v) /* v3 = v^3 */
  582. FeSquare(&uv7, &v3)
  583. FeMul(&uv7, &uv7, v)
  584. FeMul(&uv7, &uv7, u) /* uv7 = uv^7 */
  585. fePow22523(&t0, &uv7)
  586. /* t0 = (uv^7)^((q-5)/8) */
  587. FeMul(&t0, &t0, &v3)
  588. FeMul(out, &t0, u) /* u^(m+1)v^(-(m+1)) */
  589. }
  590. // Group elements are members of the elliptic curve -x^2 + y^2 = 1 + d * x^2 *
  591. // y^2 where d = -121665/121666.
  592. //
  593. // Several representations are used:
  594. // ProjectiveGroupElement: (X:Y:Z) satisfying x=X/Z, y=Y/Z
  595. // ExtendedGroupElement: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
  596. // CompletedGroupElement: ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
  597. // PreComputedGroupElement: (y+x,y-x,2dxy)
  598. type ProjectiveGroupElement struct {
  599. X, Y, Z FieldElement
  600. }
  601. type ExtendedGroupElement struct {
  602. X, Y, Z, T FieldElement
  603. }
  604. type CompletedGroupElement struct {
  605. X, Y, Z, T FieldElement
  606. }
  607. type PreComputedGroupElement struct {
  608. yPlusX, yMinusX, xy2d FieldElement
  609. }
  610. type CachedGroupElement struct {
  611. yPlusX, yMinusX, Z, T2d FieldElement
  612. }
  613. func (p *ProjectiveGroupElement) Zero() {
  614. p.X.Zero()
  615. p.Y.One()
  616. p.Z.One()
  617. }
  618. func (p *ProjectiveGroupElement) Double(r *CompletedGroupElement) {
  619. var t0 FieldElement
  620. FeSquare(&r.X, &p.X)
  621. FeSquare(&r.Z, &p.Y)
  622. FeSquare2(&r.T, &p.Z)
  623. FeAdd(&r.Y, &p.X, &p.Y)
  624. FeSquare(&t0, &r.Y)
  625. FeAdd(&r.Y, &r.Z, &r.X)
  626. FeSub(&r.Z, &r.Z, &r.X)
  627. FeSub(&r.X, &t0, &r.Y)
  628. FeSub(&r.T, &r.T, &r.Z)
  629. }
  630. func (p *ProjectiveGroupElement) ToBytes(s *Key) {
  631. var recip, x, y FieldElement
  632. FeInvert(&recip, &p.Z)
  633. FeMul(&x, &p.X, &recip)
  634. FeMul(&y, &p.Y, &recip)
  635. FeToBytes(s, &y)
  636. s[31] ^= x.IsNegative() << 7
  637. }
  638. func (p *ProjectiveGroupElement) FromBytes(s *Key) {
  639. h0 := load4(s[:])
  640. h1 := load3(s[4:]) << 6
  641. h2 := load3(s[7:]) << 5
  642. h3 := load3(s[10:]) << 3
  643. h4 := load3(s[13:]) << 2
  644. h5 := load4(s[16:])
  645. h6 := load3(s[20:]) << 7
  646. h7 := load3(s[23:]) << 5
  647. h8 := load3(s[26:]) << 4
  648. h9 := load3(s[29:]) << 2
  649. var carry [10]int64
  650. carry[9] = (h9 + int64(1<<24)) >> 25
  651. h0 += carry[9] * 19
  652. h9 -= carry[9] << 25
  653. carry[1] = (h1 + int64(1<<24)) >> 25
  654. h2 += carry[1]
  655. h1 -= carry[1] << 25
  656. carry[3] = (h3 + int64(1<<24)) >> 25
  657. h4 += carry[3]
  658. h3 -= carry[3] << 25
  659. carry[5] = (h5 + int64(1<<24)) >> 25
  660. h6 += carry[5]
  661. h5 -= carry[5] << 25
  662. carry[7] = (h7 + int64(1<<24)) >> 25
  663. h8 += carry[7]
  664. h7 -= carry[7] << 25
  665. carry[0] = (h0 + int64(1<<25)) >> 26
  666. h1 += carry[0]
  667. h0 -= carry[0] << 26
  668. carry[2] = (h2 + int64(1<<25)) >> 26
  669. h3 += carry[2]
  670. h2 -= carry[2] << 26
  671. carry[4] = (h4 + int64(1<<25)) >> 26
  672. h5 += carry[4]
  673. h4 -= carry[4] << 26
  674. carry[6] = (h6 + int64(1<<25)) >> 26
  675. h7 += carry[6]
  676. h6 -= carry[6] << 26
  677. carry[8] = (h8 + int64(1<<25)) >> 26
  678. h9 += carry[8]
  679. h8 -= carry[8] << 26
  680. var u, v, w, x, y, z FieldElement
  681. u[0] = int32(h0)
  682. u[1] = int32(h1)
  683. u[2] = int32(h2)
  684. u[3] = int32(h3)
  685. u[4] = int32(h4)
  686. u[5] = int32(h5)
  687. u[6] = int32(h6)
  688. u[7] = int32(h7)
  689. u[8] = int32(h8)
  690. u[9] = int32(h9)
  691. FeSquare2(&v, &u) /* 2 * u^2 */
  692. w.One()
  693. FeAdd(&w, &v, &w) /* w = 2 * u^2 + 1 */
  694. FeSquare(&x, &w) /* w^2 */
  695. FeMul(&y, &FeMa2, &v) /* -2 * A^2 * u^2 */
  696. FeAdd(&x, &x, &y) /* x = w^2 - 2 * A^2 * u^2 */
  697. FeDivPowM1(&p.X, &w, &x) /* (w / x)^(m + 1) */
  698. FeSquare(&y, &p.X)
  699. FeMul(&x, &y, &x)
  700. FeSub(&y, &w, &x)
  701. FeCopy(&z, &FeMa)
  702. isNegative := false
  703. var sign byte
  704. if y.IsNonZero() != 0 {
  705. FeAdd(&y, &w, &x)
  706. if y.IsNonZero() != 0 {
  707. isNegative = true
  708. } else {
  709. FeMul(&p.X, &p.X, &FeFffb1)
  710. }
  711. } else {
  712. FeMul(&p.X, &p.X, &FeFffb2)
  713. }
  714. if isNegative {
  715. FeMul(&x, &x, &FeSqrtM1)
  716. FeSub(&y, &w, &x)
  717. if y.IsNonZero() != 0 {
  718. FeAdd(&y, &w, &x)
  719. FeMul(&p.X, &p.X, &FeFffb3)
  720. } else {
  721. FeMul(&p.X, &p.X, &FeFffb4)
  722. }
  723. /* p.X = sqrt(A * (A + 2) * w / x) */
  724. /* z = -A */
  725. sign = 1
  726. } else {
  727. FeMul(&p.X, &p.X, &u) /* u * sqrt(2 * A * (A + 2) * w / x) */
  728. FeMul(&z, &z, &v) /* -2 * A * u^2 */
  729. sign = 0
  730. }
  731. if p.X.IsNegative() != sign {
  732. FeNeg(&p.X, &p.X)
  733. }
  734. FeAdd(&p.Z, &z, &w)
  735. FeSub(&p.Y, &z, &w)
  736. FeMul(&p.X, &p.X, &p.Z)
  737. }
  738. func (p *ExtendedGroupElement) Zero() {
  739. p.X.Zero()
  740. p.Y.One()
  741. p.Z.One()
  742. p.T.Zero()
  743. }
  744. func (p *ExtendedGroupElement) Double(r *CompletedGroupElement) {
  745. var q ProjectiveGroupElement
  746. p.ToProjective(&q)
  747. q.Double(r)
  748. }
  749. func (p *ExtendedGroupElement) ToCached(r *CachedGroupElement) {
  750. FeAdd(&r.yPlusX, &p.Y, &p.X)
  751. FeSub(&r.yMinusX, &p.Y, &p.X)
  752. FeCopy(&r.Z, &p.Z)
  753. FeMul(&r.T2d, &p.T, &d2)
  754. }
  755. func (p *ExtendedGroupElement) ToProjective(r *ProjectiveGroupElement) {
  756. FeCopy(&r.X, &p.X)
  757. FeCopy(&r.Y, &p.Y)
  758. FeCopy(&r.Z, &p.Z)
  759. }
  760. func (p *ExtendedGroupElement) ToBytes(s *Key) {
  761. var recip, x, y FieldElement
  762. FeInvert(&recip, &p.Z)
  763. FeMul(&x, &p.X, &recip)
  764. FeMul(&y, &p.Y, &recip)
  765. FeToBytes(s, &y)
  766. s[31] ^= x.IsNegative() << 7
  767. }
  768. func (p *ExtendedGroupElement) FromBytes(s *Key) bool {
  769. var u, v, v3, vxx, check FieldElement
  770. FeFromBytes(&p.Y, s)
  771. p.Z.One()
  772. FeSquare(&u, &p.Y)
  773. FeMul(&v, &u, &d)
  774. FeSub(&u, &u, &p.Z) // y = y^2-1
  775. FeAdd(&v, &v, &p.Z) // v = dy^2+1
  776. FeSquare(&v3, &v)
  777. FeMul(&v3, &v3, &v) // v3 = v^3
  778. FeSquare(&p.X, &v3)
  779. FeMul(&p.X, &p.X, &v)
  780. FeMul(&p.X, &p.X, &u) // x = uv^7
  781. fePow22523(&p.X, &p.X) // x = (uv^7)^((q-5)/8)
  782. FeMul(&p.X, &p.X, &v3)
  783. FeMul(&p.X, &p.X, &u) // x = uv^3(uv^7)^((q-5)/8)
  784. var tmpX, tmp2 Key
  785. FeSquare(&vxx, &p.X)
  786. FeMul(&vxx, &vxx, &v)
  787. FeSub(&check, &vxx, &u) // vx^2-u
  788. if check.IsNonZero() == 1 {
  789. FeAdd(&check, &vxx, &u) // vx^2+u
  790. if check.IsNonZero() == 1 {
  791. return false
  792. }
  793. FeMul(&p.X, &p.X, &SqrtM1)
  794. FeToBytes(&tmpX, &p.X)
  795. for i, v := range tmpX {
  796. tmp2[31-i] = v
  797. }
  798. }
  799. if p.X.IsNegative() != (s[31] >> 7) {
  800. FeNeg(&p.X, &p.X)
  801. }
  802. FeMul(&p.T, &p.X, &p.Y)
  803. return true
  804. }
  805. func (p *CompletedGroupElement) ToProjective(r *ProjectiveGroupElement) {
  806. FeMul(&r.X, &p.X, &p.T)
  807. FeMul(&r.Y, &p.Y, &p.Z)
  808. FeMul(&r.Z, &p.Z, &p.T)
  809. }
  810. func (p *CompletedGroupElement) ToExtended(r *ExtendedGroupElement) {
  811. FeMul(&r.X, &p.X, &p.T)
  812. FeMul(&r.Y, &p.Y, &p.Z)
  813. FeMul(&r.Z, &p.Z, &p.T)
  814. FeMul(&r.T, &p.X, &p.Y)
  815. }
  816. func (p *PreComputedGroupElement) Zero() {
  817. p.yPlusX.One()
  818. p.yMinusX.One()
  819. p.xy2d.Zero()
  820. }
  821. func (c *CachedGroupElement) Zero() {
  822. c.yPlusX.One()
  823. c.yMinusX.One()
  824. c.Z.One()
  825. c.T2d.Zero()
  826. }
  827. func geAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) {
  828. var t0 FieldElement
  829. FeAdd(&r.X, &p.Y, &p.X)
  830. FeSub(&r.Y, &p.Y, &p.X)
  831. FeMul(&r.Z, &r.X, &q.yPlusX)
  832. FeMul(&r.Y, &r.Y, &q.yMinusX)
  833. FeMul(&r.T, &q.T2d, &p.T)
  834. FeMul(&r.X, &p.Z, &q.Z)
  835. FeAdd(&t0, &r.X, &r.X)
  836. FeSub(&r.X, &r.Z, &r.Y)
  837. FeAdd(&r.Y, &r.Z, &r.Y)
  838. FeAdd(&r.Z, &t0, &r.T)
  839. FeSub(&r.T, &t0, &r.T)
  840. }
  841. func geSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) {
  842. var t0 FieldElement
  843. FeAdd(&r.X, &p.Y, &p.X)
  844. FeSub(&r.Y, &p.Y, &p.X)
  845. FeMul(&r.Z, &r.X, &q.yMinusX)
  846. FeMul(&r.Y, &r.Y, &q.yPlusX)
  847. FeMul(&r.T, &q.T2d, &p.T)
  848. FeMul(&r.X, &p.Z, &q.Z)
  849. FeAdd(&t0, &r.X, &r.X)
  850. FeSub(&r.X, &r.Z, &r.Y)
  851. FeAdd(&r.Y, &r.Z, &r.Y)
  852. FeSub(&r.Z, &t0, &r.T)
  853. FeAdd(&r.T, &t0, &r.T)
  854. }
  855. func geMixedAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) {
  856. var t0 FieldElement
  857. FeAdd(&r.X, &p.Y, &p.X)
  858. FeSub(&r.Y, &p.Y, &p.X)
  859. FeMul(&r.Z, &r.X, &q.yPlusX)
  860. FeMul(&r.Y, &r.Y, &q.yMinusX)
  861. FeMul(&r.T, &q.xy2d, &p.T)
  862. FeAdd(&t0, &p.Z, &p.Z)
  863. FeSub(&r.X, &r.Z, &r.Y)
  864. FeAdd(&r.Y, &r.Z, &r.Y)
  865. FeAdd(&r.Z, &t0, &r.T)
  866. FeSub(&r.T, &t0, &r.T)
  867. }
  868. func geMixedSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) {
  869. var t0 FieldElement
  870. FeAdd(&r.X, &p.Y, &p.X)
  871. FeSub(&r.Y, &p.Y, &p.X)
  872. FeMul(&r.Z, &r.X, &q.yMinusX)
  873. FeMul(&r.Y, &r.Y, &q.yPlusX)
  874. FeMul(&r.T, &q.xy2d, &p.T)
  875. FeAdd(&t0, &p.Z, &p.Z)
  876. FeSub(&r.X, &r.Z, &r.Y)
  877. FeAdd(&r.Y, &r.Z, &r.Y)
  878. FeSub(&r.Z, &t0, &r.T)
  879. FeAdd(&r.T, &t0, &r.T)
  880. }
  881. // r = 8 * t
  882. func GeMul8(r *CompletedGroupElement, t *ProjectiveGroupElement) {
  883. var u ProjectiveGroupElement
  884. t.Double(r)
  885. r.ToProjective(&u)
  886. u.Double(r)
  887. r.ToProjective(&u)
  888. u.Double(r)
  889. }
  890. // caches s into an array of CachedGroupElements for scalar multiplication later
  891. func GePrecompute(r *[8]CachedGroupElement, s *ExtendedGroupElement) {
  892. var t CompletedGroupElement
  893. var s2, u ExtendedGroupElement
  894. s.ToCached(&r[0])
  895. s.Double(&t)
  896. t.ToExtended(&s2)
  897. for i := 0; i < 7; i++ {
  898. geAdd(&t, &s2, &r[i])
  899. t.ToExtended(&u)
  900. u.ToCached(&r[i+1])
  901. }
  902. }
  903. func slide(r *[256]int8, a *Key) {
  904. for i := range r {
  905. r[i] = int8(1 & (a[i>>3] >> uint(i&7)))
  906. }
  907. for i := range r {
  908. if r[i] != 0 {
  909. for b := 1; b <= 6 && i+b < 256; b++ {
  910. if r[i+b] != 0 {
  911. if r[i]+(r[i+b]<<uint(b)) <= 15 {
  912. r[i] += r[i+b] << uint(b)
  913. r[i+b] = 0
  914. } else if r[i]-(r[i+b]<<uint(b)) >= -15 {
  915. r[i] -= r[i+b] << uint(b)
  916. for k := i + b; k < 256; k++ {
  917. if r[k] == 0 {
  918. r[k] = 1
  919. break
  920. }
  921. r[k] = 0
  922. }
  923. } else {
  924. break
  925. }
  926. }
  927. }
  928. }
  929. }
  930. }
  931. // GeDoubleScalarMultVartime sets r = a*A + b*B
  932. // where a = a[0]+256*a[1]+...+256^31 a[31].
  933. // and b = b[0]+256*b[1]+...+256^31 b[31].
  934. // B is the Ed25519 base point (x,4/5) with x positive.
  935. func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *Key, A *ExtendedGroupElement, b *Key) {
  936. var aSlide, bSlide [256]int8
  937. var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A
  938. var t CompletedGroupElement
  939. var u ExtendedGroupElement
  940. var i int
  941. slide(&aSlide, a)
  942. slide(&bSlide, b)
  943. GePrecompute(&Ai, A)
  944. r.Zero()
  945. for i = 255; i >= 0; i-- {
  946. if aSlide[i] != 0 || bSlide[i] != 0 {
  947. break
  948. }
  949. }
  950. for ; i >= 0; i-- {
  951. r.Double(&t)
  952. if aSlide[i] > 0 {
  953. t.ToExtended(&u)
  954. geAdd(&t, &u, &Ai[aSlide[i]/2])
  955. } else if aSlide[i] < 0 {
  956. t.ToExtended(&u)
  957. geSub(&t, &u, &Ai[(-aSlide[i])/2])
  958. }
  959. if bSlide[i] > 0 {
  960. t.ToExtended(&u)
  961. geMixedAdd(&t, &u, &bi[bSlide[i]/2])
  962. } else if bSlide[i] < 0 {
  963. t.ToExtended(&u)
  964. geMixedSub(&t, &u, &bi[(-bSlide[i])/2])
  965. }
  966. t.ToProjective(r)
  967. }
  968. }
  969. // sets r = a*A + b*B
  970. // where Bi is the [8]CachedGroupElement consisting of
  971. // B,3B,5B,7B,9B,11B,13B,15B
  972. func GeDoubleScalarMultPrecompVartime(r *ProjectiveGroupElement, a *Key, A *ExtendedGroupElement, b *Key, Bi *[8]CachedGroupElement) {
  973. var aSlide, bSlide [256]int8
  974. var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A
  975. var t CompletedGroupElement
  976. var u ExtendedGroupElement
  977. var i int
  978. slide(&aSlide, a)
  979. slide(&bSlide, b)
  980. GePrecompute(&Ai, A)
  981. r.Zero()
  982. for i = 255; i >= 0; i-- {
  983. if aSlide[i] != 0 || bSlide[i] != 0 {
  984. break
  985. }
  986. }
  987. for ; i >= 0; i-- {
  988. r.Double(&t)
  989. if aSlide[i] > 0 {
  990. t.ToExtended(&u)
  991. geAdd(&t, &u, &Ai[aSlide[i]/2])
  992. } else if aSlide[i] < 0 {
  993. t.ToExtended(&u)
  994. geSub(&t, &u, &Ai[(-aSlide[i])/2])
  995. }
  996. if bSlide[i] > 0 {
  997. t.ToExtended(&u)
  998. geAdd(&t, &u, &Bi[bSlide[i]/2])
  999. } else if bSlide[i] < 0 {
  1000. t.ToExtended(&u)
  1001. geSub(&t, &u, &Bi[(-bSlide[i])/2])
  1002. }
  1003. t.ToProjective(r)
  1004. }
  1005. return
  1006. }
  1007. // equal returns 1 if b == c and 0 otherwise.
  1008. func equal(b, c int32) int32 {
  1009. x := uint32(b ^ c)
  1010. x--
  1011. return int32(x >> 31)
  1012. }
  1013. // negative returns 1 if b < 0 and 0 otherwise.
  1014. func negative(b int32) int32 {
  1015. return (b >> 31) & 1
  1016. }
  1017. func CachedGroupElementCMove(t, u *CachedGroupElement, b int32) {
  1018. FeCMove(&t.yPlusX, &u.yPlusX, b)
  1019. FeCMove(&t.yMinusX, &u.yMinusX, b)
  1020. FeCMove(&t.Z, &u.Z, b)
  1021. FeCMove(&t.T2d, &u.T2d, b)
  1022. }
  1023. func PreComputedGroupElementCMove(t, u *PreComputedGroupElement, b int32) {
  1024. FeCMove(&t.yPlusX, &u.yPlusX, b)
  1025. FeCMove(&t.yMinusX, &u.yMinusX, b)
  1026. FeCMove(&t.xy2d, &u.xy2d, b)
  1027. }
  1028. func selectPoint(t *PreComputedGroupElement, pos int32, b int32) {
  1029. var minusT PreComputedGroupElement
  1030. bNegative := negative(b)
  1031. bAbs := b - (((-bNegative) & b) << 1)
  1032. t.Zero()
  1033. for i := int32(0); i < 8; i++ {
  1034. PreComputedGroupElementCMove(t, &base[pos][i], equal(bAbs, i+1))
  1035. }
  1036. FeCopy(&minusT.yPlusX, &t.yMinusX)
  1037. FeCopy(&minusT.yMinusX, &t.yPlusX)
  1038. FeNeg(&minusT.xy2d, &t.xy2d)
  1039. PreComputedGroupElementCMove(t, &minusT, bNegative)
  1040. }
  1041. // GeScalarMult computes h = a*A, where
  1042. // a = a[0]+256*a[1]+...+256^31 a[31]
  1043. // A is a point on the curve
  1044. //
  1045. // Preconditions:
  1046. // a[31] <= 127
  1047. func GeScalarMult(r *ProjectiveGroupElement, a *Key, A *ExtendedGroupElement) {
  1048. var e [64]int32
  1049. var carry, carry2 int32
  1050. for i := 0; i < 31; i++ {
  1051. carry += int32(a[i]) /* 0..256 */
  1052. carry2 = (carry + 8) >> 4 /* 0..16 */
  1053. e[2*i] = carry - (carry2 << 4) /* -8..7 */
  1054. carry = (carry2 + 8) >> 4 /* 0..1 */
  1055. e[2*i+1] = carry2 - (carry << 4) /* -8..7 */
  1056. }
  1057. carry += int32(a[31]) /* 0..128 */
  1058. carry2 = (carry + 8) >> 4 /* 0..8 */
  1059. e[62] = carry - (carry2 << 4) /* -8..7 */
  1060. e[63] = carry2 /* 0..8 */
  1061. var Ai [8]CachedGroupElement // A,2A,3A,4A,5A,6A,7A,8A
  1062. t := new(CompletedGroupElement)
  1063. u := new(ExtendedGroupElement)
  1064. A.ToCached(&Ai[0])
  1065. for i := 0; i < 7; i++ {
  1066. geAdd(t, A, &Ai[i])
  1067. t.ToExtended(u)
  1068. u.ToCached(&Ai[i+1])
  1069. }
  1070. r.Zero()
  1071. cur := new(CachedGroupElement)
  1072. minusCur := new(CachedGroupElement)
  1073. for i := 63; i >= 0; i-- {
  1074. b := e[i]
  1075. bNegative := negative(b)
  1076. bAbs := b - (((-bNegative) & b) << 1)
  1077. r.Double(t)
  1078. t.ToProjective(r)
  1079. r.Double(t)
  1080. t.ToProjective(r)
  1081. r.Double(t)
  1082. t.ToProjective(r)
  1083. r.Double(t)
  1084. t.ToExtended(u)
  1085. cur.Zero()
  1086. for j := int32(0); j < 8; j++ {
  1087. CachedGroupElementCMove(cur, &Ai[j], equal(bAbs, j+1))
  1088. }
  1089. FeCopy(&minusCur.yPlusX, &cur.yMinusX)
  1090. FeCopy(&minusCur.yMinusX, &cur.yPlusX)
  1091. FeCopy(&minusCur.Z, &cur.Z)
  1092. FeNeg(&minusCur.T2d, &cur.T2d)
  1093. CachedGroupElementCMove(cur, minusCur, bNegative)
  1094. geAdd(t, u, cur)
  1095. t.ToProjective(r)
  1096. }
  1097. }
  1098. // GeScalarMultBase computes h = a*B, where
  1099. // a = a[0]+256*a[1]+...+256^31 a[31]
  1100. // B is the Ed25519 base point (x,4/5) with x positive.
  1101. //
  1102. // Preconditions:
  1103. // a[31] <= 127
  1104. func GeScalarMultBase(h *ExtendedGroupElement, a *Key) {
  1105. var e [64]int8
  1106. for i, v := range a {
  1107. e[2*i] = int8(v & 15)
  1108. e[2*i+1] = int8((v >> 4) & 15)
  1109. }
  1110. // each e[i] is between 0 and 15 and e[63] is between 0 and 7.
  1111. carry := int8(0)
  1112. for i := 0; i < 63; i++ {
  1113. e[i] += carry
  1114. carry = (e[i] + 8) >> 4
  1115. e[i] -= carry << 4
  1116. }
  1117. e[63] += carry
  1118. // each e[i] is between -8 and 8.
  1119. h.Zero()
  1120. var t PreComputedGroupElement
  1121. var r CompletedGroupElement
  1122. for i := int32(1); i < 64; i += 2 {
  1123. selectPoint(&t, i/2, int32(e[i]))
  1124. geMixedAdd(&r, h, &t)
  1125. r.ToExtended(h)
  1126. }
  1127. var s ProjectiveGroupElement
  1128. h.Double(&r)
  1129. r.ToProjective(&s)
  1130. s.Double(&r)
  1131. r.ToProjective(&s)
  1132. s.Double(&r)
  1133. r.ToProjective(&s)
  1134. s.Double(&r)
  1135. r.ToExtended(h)
  1136. for i := int32(0); i < 64; i += 2 {
  1137. selectPoint(&t, i/2, int32(e[i]))
  1138. geMixedAdd(&r, h, &t)
  1139. r.ToExtended(h)
  1140. }
  1141. }
  1142. func ScAdd(s, a, b *Key) {
  1143. a0 := 2097151 & load3(a[:])
  1144. a1 := 2097151 & (load4(a[2:]) >> 5)
  1145. a2 := 2097151 & (load3(a[5:]) >> 2)
  1146. a3 := 2097151 & (load4(a[7:]) >> 7)
  1147. a4 := 2097151 & (load4(a[10:]) >> 4)
  1148. a5 := 2097151 & (load3(a[13:]) >> 1)
  1149. a6 := 2097151 & (load4(a[15:]) >> 6)
  1150. a7 := 2097151 & (load3(a[18:]) >> 3)
  1151. a8 := 2097151 & load3(a[21:])
  1152. a9 := 2097151 & (load4(a[23:]) >> 5)
  1153. a10 := 2097151 & (load3(a[26:]) >> 2)
  1154. a11 := (load4(a[28:]) >> 7)
  1155. b0 := 2097151 & load3(b[:])
  1156. b1 := 2097151 & (load4(b[2:]) >> 5)
  1157. b2 := 2097151 & (load3(b[5:]) >> 2)
  1158. b3 := 2097151 & (load4(b[7:]) >> 7)
  1159. b4 := 2097151 & (load4(b[10:]) >> 4)
  1160. b5 := 2097151 & (load3(b[13:]) >> 1)
  1161. b6 := 2097151 & (load4(b[15:]) >> 6)
  1162. b7 := 2097151 & (load3(b[18:]) >> 3)
  1163. b8 := 2097151 & load3(b[21:])
  1164. b9 := 2097151 & (load4(b[23:]) >> 5)
  1165. b10 := 2097151 & (load3(b[26:]) >> 2)
  1166. b11 := (load4(b[28:]) >> 7)
  1167. s0 := a0 + b0
  1168. s1 := a1 + b1
  1169. s2 := a2 + b2
  1170. s3 := a3 + b3
  1171. s4 := a4 + b4
  1172. s5 := a5 + b5
  1173. s6 := a6 + b6
  1174. s7 := a7 + b7
  1175. s8 := a8 + b8
  1176. s9 := a9 + b9
  1177. s10 := a10 + b10
  1178. s11 := a11 + b11
  1179. s12 := int64(0)
  1180. var carry [12]int64
  1181. carry[0] = (s0 + (1 << 20)) >> 21
  1182. s1 += carry[0]
  1183. s0 -= carry[0] << 21
  1184. carry[2] = (s2 + (1 << 20)) >> 21
  1185. s3 += carry[2]
  1186. s2 -= carry[2] << 21
  1187. carry[4] = (s4 + (1 << 20)) >> 21
  1188. s5 += carry[4]
  1189. s4 -= carry[4] << 21
  1190. carry[6] = (s6 + (1 << 20)) >> 21
  1191. s7 += carry[6]
  1192. s6 -= carry[6] << 21
  1193. carry[8] = (s8 + (1 << 20)) >> 21
  1194. s9 += carry[8]
  1195. s8 -= carry[8] << 21
  1196. carry[10] = (s10 + (1 << 20)) >> 21
  1197. s11 += carry[10]
  1198. s10 -= carry[10] << 21
  1199. carry[1] = (s1 + (1 << 20)) >> 21
  1200. s2 += carry[1]
  1201. s1 -= carry[1] << 21
  1202. carry[3] = (s3 + (1 << 20)) >> 21
  1203. s4 += carry[3]
  1204. s3 -= carry[3] << 21
  1205. carry[5] = (s5 + (1 << 20)) >> 21
  1206. s6 += carry[5]
  1207. s5 -= carry[5] << 21
  1208. carry[7] = (s7 + (1 << 20)) >> 21
  1209. s8 += carry[7]
  1210. s7 -= carry[7] << 21
  1211. carry[9] = (s9 + (1 << 20)) >> 21
  1212. s10 += carry[9]
  1213. s9 -= carry[9] << 21
  1214. carry[11] = (s11 + (1 << 20)) >> 21
  1215. s12 += carry[11]
  1216. s11 -= carry[11] << 21
  1217. s0 += s12 * 666643
  1218. s1 += s12 * 470296
  1219. s2 += s12 * 654183
  1220. s3 -= s12 * 997805
  1221. s4 += s12 * 136657
  1222. s5 -= s12 * 683901
  1223. s12 = 0
  1224. carry[0] = s0 >> 21
  1225. s1 += carry[0]
  1226. s0 -= carry[0] << 21
  1227. carry[1] = s1 >> 21
  1228. s2 += carry[1]
  1229. s1 -= carry[1] << 21
  1230. carry[2] = s2 >> 21
  1231. s3 += carry[2]
  1232. s2 -= carry[2] << 21
  1233. carry[3] = s3 >> 21
  1234. s4 += carry[3]
  1235. s3 -= carry[3] << 21
  1236. carry[4] = s4 >> 21
  1237. s5 += carry[4]
  1238. s4 -= carry[4] << 21
  1239. carry[5] = s5 >> 21
  1240. s6 += carry[5]
  1241. s5 -= carry[5] << 21
  1242. carry[6] = s6 >> 21
  1243. s7 += carry[6]
  1244. s6 -= carry[6] << 21
  1245. carry[7] = s7 >> 21
  1246. s8 += carry[7]
  1247. s7 -= carry[7] << 21
  1248. carry[8] = s8 >> 21
  1249. s9 += carry[8]
  1250. s8 -= carry[8] << 21
  1251. carry[9] = s9 >> 21
  1252. s10 += carry[9]
  1253. s9 -= carry[9] << 21
  1254. carry[10] = s10 >> 21
  1255. s11 += carry[10]
  1256. s10 -= carry[10] << 21
  1257. carry[11] = s11 >> 21
  1258. s12 += carry[11]
  1259. s11 -= carry[11] << 21
  1260. s0 += s12 * 666643
  1261. s1 += s12 * 470296
  1262. s2 += s12 * 654183
  1263. s3 -= s12 * 997805
  1264. s4 += s12 * 136657
  1265. s5 -= s12 * 683901
  1266. carry[0] = s0 >> 21
  1267. s1 += carry[0]
  1268. s0 -= carry[0] << 21
  1269. carry[1] = s1 >> 21
  1270. s2 += carry[1]
  1271. s1 -= carry[1] << 21
  1272. carry[2] = s2 >> 21
  1273. s3 += carry[2]
  1274. s2 -= carry[2] << 21
  1275. carry[3] = s3 >> 21
  1276. s4 += carry[3]
  1277. s3 -= carry[3] << 21
  1278. carry[4] = s4 >> 21
  1279. s5 += carry[4]
  1280. s4 -= carry[4] << 21
  1281. carry[5] = s5 >> 21
  1282. s6 += carry[5]
  1283. s5 -= carry[5] << 21
  1284. carry[6] = s6 >> 21
  1285. s7 += carry[6]
  1286. s6 -= carry[6] << 21
  1287. carry[7] = s7 >> 21
  1288. s8 += carry[7]
  1289. s7 -= carry[7] << 21
  1290. carry[8] = s8 >> 21
  1291. s9 += carry[8]
  1292. s8 -= carry[8] << 21
  1293. carry[9] = s9 >> 21
  1294. s10 += carry[9]
  1295. s9 -= carry[9] << 21
  1296. carry[10] = s10 >> 21
  1297. s11 += carry[10]
  1298. s10 -= carry[10] << 21
  1299. s[0] = byte(s0 >> 0)
  1300. s[1] = byte(s0 >> 8)
  1301. s[2] = byte((s0 >> 16) | (s1 << 5))
  1302. s[3] = byte(s1 >> 3)
  1303. s[4] = byte(s1 >> 11)
  1304. s[5] = byte((s1 >> 19) | (s2 << 2))
  1305. s[6] = byte(s2 >> 6)
  1306. s[7] = byte((s2 >> 14) | (s3 << 7))
  1307. s[8] = byte(s3 >> 1)
  1308. s[9] = byte(s3 >> 9)
  1309. s[10] = byte((s3 >> 17) | (s4 << 4))
  1310. s[11] = byte(s4 >> 4)
  1311. s[12] = byte(s4 >> 12)
  1312. s[13] = byte((s4 >> 20) | (s5 << 1))
  1313. s[14] = byte(s5 >> 7)
  1314. s[15] = byte((s5 >> 15) | (s6 << 6))
  1315. s[16] = byte(s6 >> 2)
  1316. s[17] = byte(s6 >> 10)
  1317. s[18] = byte((s6 >> 18) | (s7 << 3))
  1318. s[19] = byte(s7 >> 5)
  1319. s[20] = byte(s7 >> 13)
  1320. s[21] = byte(s8 >> 0)
  1321. s[22] = byte(s8 >> 8)
  1322. s[23] = byte((s8 >> 16) | (s9 << 5))
  1323. s[24] = byte(s9 >> 3)
  1324. s[25] = byte(s9 >> 11)
  1325. s[26] = byte((s9 >> 19) | (s10 << 2))
  1326. s[27] = byte(s10 >> 6)
  1327. s[28] = byte((s10 >> 14) | (s11 << 7))
  1328. s[29] = byte(s11 >> 1)
  1329. s[30] = byte(s11 >> 9)
  1330. s[31] = byte(s11 >> 17)
  1331. }
  1332. func ScSub(s, a, b *Key) {
  1333. a0 := 2097151 & load3(a[:])
  1334. a1 := 2097151 & (load4(a[2:]) >> 5)
  1335. a2 := 2097151 & (load3(a[5:]) >> 2)
  1336. a3 := 2097151 & (load4(a[7:]) >> 7)
  1337. a4 := 2097151 & (load4(a[10:]) >> 4)
  1338. a5 := 2097151 & (load3(a[13:]) >> 1)
  1339. a6 := 2097151 & (load4(a[15:]) >> 6)
  1340. a7 := 2097151 & (load3(a[18:]) >> 3)
  1341. a8 := 2097151 & load3(a[21:])
  1342. a9 := 2097151 & (load4(a[23:]) >> 5)
  1343. a10 := 2097151 & (load3(a[26:]) >> 2)
  1344. a11 := (load4(a[28:]) >> 7)
  1345. b0 := 2097151 & load3(b[:])
  1346. b1 := 2097151 & (load4(b[2:]) >> 5)
  1347. b2 := 2097151 & (load3(b[5:]) >> 2)
  1348. b3 := 2097151 & (load4(b[7:]) >> 7)
  1349. b4 := 2097151 & (load4(b[10:]) >> 4)
  1350. b5 := 2097151 & (load3(b[13:]) >> 1)
  1351. b6 := 2097151 & (load4(b[15:]) >> 6)
  1352. b7 := 2097151 & (load3(b[18:]) >> 3)
  1353. b8 := 2097151 & load3(b[21:])
  1354. b9 := 2097151 & (load4(b[23:]) >> 5)
  1355. b10 := 2097151 & (load3(b[26:]) >> 2)
  1356. b11 := (load4(b[28:]) >> 7)
  1357. s0 := a0 - b0
  1358. s1 := a1 - b1
  1359. s2 := a2 - b2
  1360. s3 := a3 - b3
  1361. s4 := a4 - b4
  1362. s5 := a5 - b5
  1363. s6 := a6 - b6
  1364. s7 := a7 - b7
  1365. s8 := a8 - b8
  1366. s9 := a9 - b9
  1367. s10 := a10 - b10
  1368. s11 := a11 - b11
  1369. s12 := int64(0)
  1370. var carry [12]int64
  1371. carry[0] = (s0 + (1 << 20)) >> 21
  1372. s1 += carry[0]
  1373. s0 -= carry[0] << 21
  1374. carry[2] = (s2 + (1 << 20)) >> 21
  1375. s3 += carry[2]
  1376. s2 -= carry[2] << 21
  1377. carry[4] = (s4 + (1 << 20)) >> 21
  1378. s5 += carry[4]
  1379. s4 -= carry[4] << 21
  1380. carry[6] = (s6 + (1 << 20)) >> 21
  1381. s7 += carry[6]
  1382. s6 -= carry[6] << 21
  1383. carry[8] = (s8 + (1 << 20)) >> 21
  1384. s9 += carry[8]
  1385. s8 -= carry[8] << 21
  1386. carry[10] = (s10 + (1 << 20)) >> 21
  1387. s11 += carry[10]
  1388. s10 -= carry[10] << 21
  1389. carry[1] = (s1 + (1 << 20)) >> 21
  1390. s2 += carry[1]
  1391. s1 -= carry[1] << 21
  1392. carry[3] = (s3 + (1 << 20)) >> 21
  1393. s4 += carry[3]
  1394. s3 -= carry[3] << 21
  1395. carry[5] = (s5 + (1 << 20)) >> 21
  1396. s6 += carry[5]
  1397. s5 -= carry[5] << 21
  1398. carry[7] = (s7 + (1 << 20)) >> 21
  1399. s8 += carry[7]
  1400. s7 -= carry[7] << 21
  1401. carry[9] = (s9 + (1 << 20)) >> 21
  1402. s10 += carry[9]
  1403. s9 -= carry[9] << 21
  1404. carry[11] = (s11 + (1 << 20)) >> 21
  1405. s12 += carry[11]
  1406. s11 -= carry[11] << 21
  1407. s0 += s12 * 666643
  1408. s1 += s12 * 470296
  1409. s2 += s12 * 654183
  1410. s3 -= s12 * 997805
  1411. s4 += s12 * 136657
  1412. s5 -= s12 * 683901
  1413. s12 = 0
  1414. carry[0] = s0 >> 21
  1415. s1 += carry[0]
  1416. s0 -= carry[0] << 21
  1417. carry[1] = s1 >> 21
  1418. s2 += carry[1]
  1419. s1 -= carry[1] << 21
  1420. carry[2] = s2 >> 21
  1421. s3 += carry[2]
  1422. s2 -= carry[2] << 21
  1423. carry[3] = s3 >> 21
  1424. s4 += carry[3]
  1425. s3 -= carry[3] << 21
  1426. carry[4] = s4 >> 21
  1427. s5 += carry[4]
  1428. s4 -= carry[4] << 21
  1429. carry[5] = s5 >> 21
  1430. s6 += carry[5]
  1431. s5 -= carry[5] << 21
  1432. carry[6] = s6 >> 21
  1433. s7 += carry[6]
  1434. s6 -= carry[6] << 21
  1435. carry[7] = s7 >> 21
  1436. s8 += carry[7]
  1437. s7 -= carry[7] << 21
  1438. carry[8] = s8 >> 21
  1439. s9 += carry[8]
  1440. s8 -= carry[8] << 21
  1441. carry[9] = s9 >> 21
  1442. s10 += carry[9]
  1443. s9 -= carry[9] << 21
  1444. carry[10] = s10 >> 21
  1445. s11 += carry[10]
  1446. s10 -= carry[10] << 21
  1447. carry[11] = s11 >> 21
  1448. s12 += carry[11]
  1449. s11 -= carry[11] << 21
  1450. s0 += s12 * 666643
  1451. s1 += s12 * 470296
  1452. s2 += s12 * 654183
  1453. s3 -= s12 * 997805
  1454. s4 += s12 * 136657
  1455. s5 -= s12 * 683901
  1456. carry[0] = s0 >> 21
  1457. s1 += carry[0]
  1458. s0 -= carry[0] << 21
  1459. carry[1] = s1 >> 21
  1460. s2 += carry[1]
  1461. s1 -= carry[1] << 21
  1462. carry[2] = s2 >> 21
  1463. s3 += carry[2]
  1464. s2 -= carry[2] << 21
  1465. carry[3] = s3 >> 21
  1466. s4 += carry[3]
  1467. s3 -= carry[3] << 21
  1468. carry[4] = s4 >> 21
  1469. s5 += carry[4]
  1470. s4 -= carry[4] << 21
  1471. carry[5] = s5 >> 21
  1472. s6 += carry[5]
  1473. s5 -= carry[5] << 21
  1474. carry[6] = s6 >> 21
  1475. s7 += carry[6]
  1476. s6 -= carry[6] << 21
  1477. carry[7] = s7 >> 21
  1478. s8 += carry[7]
  1479. s7 -= carry[7] << 21
  1480. carry[8] = s8 >> 21
  1481. s9 += carry[8]
  1482. s8 -= carry[8] << 21
  1483. carry[9] = s9 >> 21
  1484. s10 += carry[9]
  1485. s9 -= carry[9] << 21
  1486. carry[10] = s10 >> 21
  1487. s11 += carry[10]
  1488. s10 -= carry[10] << 21
  1489. s[0] = byte(s0 >> 0)
  1490. s[1] = byte(s0 >> 8)
  1491. s[2] = byte((s0 >> 16) | (s1 << 5))
  1492. s[3] = byte(s1 >> 3)
  1493. s[4] = byte(s1 >> 11)
  1494. s[5] = byte((s1 >> 19) | (s2 << 2))
  1495. s[6] = byte(s2 >> 6)
  1496. s[7] = byte((s2 >> 14) | (s3 << 7))
  1497. s[8] = byte(s3 >> 1)
  1498. s[9] = byte(s3 >> 9)
  1499. s[10] = byte((s3 >> 17) | (s4 << 4))
  1500. s[11] = byte(s4 >> 4)
  1501. s[12] = byte(s4 >> 12)
  1502. s[13] = byte((s4 >> 20) | (s5 << 1))
  1503. s[14] = byte(s5 >> 7)
  1504. s[15] = byte((s5 >> 15) | (s6 << 6))
  1505. s[16] = byte(s6 >> 2)
  1506. s[17] = byte(s6 >> 10)
  1507. s[18] = byte((s6 >> 18) | (s7 << 3))
  1508. s[19] = byte(s7 >> 5)
  1509. s[20] = byte(s7 >> 13)
  1510. s[21] = byte(s8 >> 0)
  1511. s[22] = byte(s8 >> 8)
  1512. s[23] = byte((s8 >> 16) | (s9 << 5))
  1513. s[24] = byte(s9 >> 3)
  1514. s[25] = byte(s9 >> 11)
  1515. s[26] = byte((s9 >> 19) | (s10 << 2))
  1516. s[27] = byte(s10 >> 6)
  1517. s[28] = byte((s10 >> 14) | (s11 << 7))
  1518. s[29] = byte(s11 >> 1)
  1519. s[30] = byte(s11 >> 9)
  1520. s[31] = byte(s11 >> 17)
  1521. }
  1522. func signum(a int64) int64 {
  1523. return a>>63 - ((-a) >> 63)
  1524. }
  1525. func ScValid(s *Key) bool {
  1526. s0 := load4(s[:])
  1527. s1 := load4(s[4:])
  1528. s2 := load4(s[8:])
  1529. s3 := load4(s[12:])
  1530. s4 := load4(s[16:])
  1531. s5 := load4(s[20:])
  1532. s6 := load4(s[24:])
  1533. s7 := load4(s[28:])
  1534. return (signum(1559614444-s0)+(signum(1477600026-s1)<<1)+(signum(2734136534-s2)<<2)+(signum(350157278-s3)<<3)+(signum(-s4)<<4)+(signum(-s5)<<5)+(signum(-s6)<<6)+(signum(268435456-s7)<<7))>>8 == 0
  1535. }
  1536. func ScIsZero(s *Key) bool {
  1537. return ((int(s[0]|s[1]|s[2]|s[3]|s[4]|s[5]|s[6]|s[7]|s[8]|
  1538. s[9]|s[10]|s[11]|s[12]|s[13]|s[14]|s[15]|s[16]|s[17]|
  1539. s[18]|s[19]|s[20]|s[21]|s[22]|s[23]|s[24]|s[25]|s[26]|
  1540. s[27]|s[28]|s[29]|s[30]|s[31])-1)>>8)+1 == 0
  1541. }
  1542. // The scalars are GF(2^252 + 27742317777372353535851937790883648493).
  1543. // Input:
  1544. // a[0]+256*a[1]+...+256^31*a[31] = a
  1545. // b[0]+256*b[1]+...+256^31*b[31] = b
  1546. // c[0]+256*c[1]+...+256^31*c[31] = c
  1547. //
  1548. // Output:
  1549. // s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
  1550. // where l = 2^252 + 27742317777372353535851937790883648493.
  1551. func ScMulAdd(s, a, b, c *Key) {
  1552. a0 := 2097151 & load3(a[:])
  1553. a1 := 2097151 & (load4(a[2:]) >> 5)
  1554. a2 := 2097151 & (load3(a[5:]) >> 2)
  1555. a3 := 2097151 & (load4(a[7:]) >> 7)
  1556. a4 := 2097151 & (load4(a[10:]) >> 4)
  1557. a5 := 2097151 & (load3(a[13:]) >> 1)
  1558. a6 := 2097151 & (load4(a[15:]) >> 6)
  1559. a7 := 2097151 & (load3(a[18:]) >> 3)
  1560. a8 := 2097151 & load3(a[21:])
  1561. a9 := 2097151 & (load4(a[23:]) >> 5)
  1562. a10 := 2097151 & (load3(a[26:]) >> 2)
  1563. a11 := (load4(a[28:]) >> 7)
  1564. b0 := 2097151 & load3(b[:])
  1565. b1 := 2097151 & (load4(b[2:]) >> 5)
  1566. b2 := 2097151 & (load3(b[5:]) >> 2)
  1567. b3 := 2097151 & (load4(b[7:]) >> 7)
  1568. b4 := 2097151 & (load4(b[10:]) >> 4)
  1569. b5 := 2097151 & (load3(b[13:]) >> 1)
  1570. b6 := 2097151 & (load4(b[15:]) >> 6)
  1571. b7 := 2097151 & (load3(b[18:]) >> 3)
  1572. b8 := 2097151 & load3(b[21:])
  1573. b9 := 2097151 & (load4(b[23:]) >> 5)
  1574. b10 := 2097151 & (load3(b[26:]) >> 2)
  1575. b11 := (load4(b[28:]) >> 7)
  1576. c0 := 2097151 & load3(c[:])
  1577. c1 := 2097151 & (load4(c[2:]) >> 5)
  1578. c2 := 2097151 & (load3(c[5:]) >> 2)
  1579. c3 := 2097151 & (load4(c[7:]) >> 7)
  1580. c4 := 2097151 & (load4(c[10:]) >> 4)
  1581. c5 := 2097151 & (load3(c[13:]) >> 1)
  1582. c6 := 2097151 & (load4(c[15:]) >> 6)
  1583. c7 := 2097151 & (load3(c[18:]) >> 3)
  1584. c8 := 2097151 & load3(c[21:])
  1585. c9 := 2097151 & (load4(c[23:]) >> 5)
  1586. c10 := 2097151 & (load3(c[26:]) >> 2)
  1587. c11 := (load4(c[28:]) >> 7)
  1588. var carry [23]int64
  1589. s0 := c0 + a0*b0
  1590. s1 := c1 + a0*b1 + a1*b0
  1591. s2 := c2 + a0*b2 + a1*b1 + a2*b0
  1592. s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0
  1593. s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0
  1594. s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0
  1595. s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0
  1596. s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0
  1597. s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0
  1598. s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0
  1599. s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0
  1600. s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0
  1601. s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1
  1602. s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2
  1603. s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3
  1604. s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4
  1605. s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5
  1606. s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6
  1607. s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7
  1608. s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8
  1609. s20 := a9*b11 + a10*b10 + a11*b9
  1610. s21 := a10*b11 + a11*b10
  1611. s22 := a11 * b11
  1612. s23 := int64(0)
  1613. carry[0] = (s0 + (1 << 20)) >> 21
  1614. s1 += carry[0]
  1615. s0 -= carry[0] << 21
  1616. carry[2] = (s2 + (1 << 20)) >> 21
  1617. s3 += carry[2]
  1618. s2 -= carry[2] << 21
  1619. carry[4] = (s4 + (1 << 20)) >> 21
  1620. s5 += carry[4]
  1621. s4 -= carry[4] << 21
  1622. carry[6] = (s6 + (1 << 20)) >> 21
  1623. s7 += carry[6]
  1624. s6 -= carry[6] << 21
  1625. carry[8] = (s8 + (1 << 20)) >> 21
  1626. s9 += carry[8]
  1627. s8 -= carry[8] << 21
  1628. carry[10] = (s10 + (1 << 20)) >> 21
  1629. s11 += carry[10]
  1630. s10 -= carry[10] << 21
  1631. carry[12] = (s12 + (1 << 20)) >> 21
  1632. s13 += carry[12]
  1633. s12 -= carry[12] << 21
  1634. carry[14] = (s14 + (1 << 20)) >> 21
  1635. s15 += carry[14]
  1636. s14 -= carry[14] << 21
  1637. carry[16] = (s16 + (1 << 20)) >> 21
  1638. s17 += carry[16]
  1639. s16 -= carry[16] << 21
  1640. carry[18] = (s18 + (1 << 20)) >> 21
  1641. s19 += carry[18]
  1642. s18 -= carry[18] << 21
  1643. carry[20] = (s20 + (1 << 20)) >> 21
  1644. s21 += carry[20]
  1645. s20 -= carry[20] << 21
  1646. carry[22] = (s22 + (1 << 20)) >> 21
  1647. s23 += carry[22]
  1648. s22 -= carry[22] << 21
  1649. carry[1] = (s1 + (1 << 20)) >> 21
  1650. s2 += carry[1]
  1651. s1 -= carry[1] << 21
  1652. carry[3] = (s3 + (1 << 20)) >> 21
  1653. s4 += carry[3]
  1654. s3 -= carry[3] << 21
  1655. carry[5] = (s5 + (1 << 20)) >> 21
  1656. s6 += carry[5]
  1657. s5 -= carry[5] << 21
  1658. carry[7] = (s7 + (1 << 20)) >> 21
  1659. s8 += carry[7]
  1660. s7 -= carry[7] << 21
  1661. carry[9] = (s9 + (1 << 20)) >> 21
  1662. s10 += carry[9]
  1663. s9 -= carry[9] << 21
  1664. carry[11] = (s11 + (1 << 20)) >> 21
  1665. s12 += carry[11]
  1666. s11 -= carry[11] << 21
  1667. carry[13] = (s13 + (1 << 20)) >> 21
  1668. s14 += carry[13]
  1669. s13 -= carry[13] << 21
  1670. carry[15] = (s15 + (1 << 20)) >> 21
  1671. s16 += carry[15]
  1672. s15 -= carry[15] << 21
  1673. carry[17] = (s17 + (1 << 20)) >> 21
  1674. s18 += carry[17]
  1675. s17 -= carry[17] << 21
  1676. carry[19] = (s19 + (1 << 20)) >> 21
  1677. s20 += carry[19]
  1678. s19 -= carry[19] << 21
  1679. carry[21] = (s21 + (1 << 20)) >> 21
  1680. s22 += carry[21]
  1681. s21 -= carry[21] << 21
  1682. s11 += s23 * 666643
  1683. s12 += s23 * 470296
  1684. s13 += s23 * 654183
  1685. s14 -= s23 * 997805
  1686. s15 += s23 * 136657
  1687. s16 -= s23 * 683901
  1688. s23 = 0
  1689. s10 += s22 * 666643
  1690. s11 += s22 * 470296
  1691. s12 += s22 * 654183
  1692. s13 -= s22 * 997805
  1693. s14 += s22 * 136657
  1694. s15 -= s22 * 683901
  1695. s22 = 0
  1696. s9 += s21 * 666643
  1697. s10 += s21 * 470296
  1698. s11 += s21 * 654183
  1699. s12 -= s21 * 997805
  1700. s13 += s21 * 136657
  1701. s14 -= s21 * 683901
  1702. s21 = 0
  1703. s8 += s20 * 666643
  1704. s9 += s20 * 470296
  1705. s10 += s20 * 654183
  1706. s11 -= s20 * 997805
  1707. s12 += s20 * 136657
  1708. s13 -= s20 * 683901
  1709. s20 = 0
  1710. s7 += s19 * 666643
  1711. s8 += s19 * 470296
  1712. s9 += s19 * 654183
  1713. s10 -= s19 * 997805
  1714. s11 += s19 * 136657
  1715. s12 -= s19 * 683901
  1716. s19 = 0
  1717. s6 += s18 * 666643
  1718. s7 += s18 * 470296
  1719. s8 += s18 * 654183
  1720. s9 -= s18 * 997805
  1721. s10 += s18 * 136657
  1722. s11 -= s18 * 683901
  1723. s18 = 0
  1724. carry[6] = (s6 + (1 << 20)) >> 21
  1725. s7 += carry[6]
  1726. s6 -= carry[6] << 21
  1727. carry[8] = (s8 + (1 << 20)) >> 21
  1728. s9 += carry[8]
  1729. s8 -= carry[8] << 21
  1730. carry[10] = (s10 + (1 << 20)) >> 21
  1731. s11 += carry[10]
  1732. s10 -= carry[10] << 21
  1733. carry[12] = (s12 + (1 << 20)) >> 21
  1734. s13 += carry[12]
  1735. s12 -= carry[12] << 21
  1736. carry[14] = (s14 + (1 << 20)) >> 21
  1737. s15 += carry[14]
  1738. s14 -= carry[14] << 21
  1739. carry[16] = (s16 + (1 << 20)) >> 21
  1740. s17 += carry[16]
  1741. s16 -= carry[16] << 21
  1742. carry[7] = (s7 + (1 << 20)) >> 21
  1743. s8 += carry[7]
  1744. s7 -= carry[7] << 21
  1745. carry[9] = (s9 + (1 << 20)) >> 21
  1746. s10 += carry[9]
  1747. s9 -= carry[9] << 21
  1748. carry[11] = (s11 + (1 << 20)) >> 21
  1749. s12 += carry[11]
  1750. s11 -= carry[11] << 21
  1751. carry[13] = (s13 + (1 << 20)) >> 21
  1752. s14 += carry[13]
  1753. s13 -= carry[13] << 21
  1754. carry[15] = (s15 + (1 << 20)) >> 21
  1755. s16 += carry[15]
  1756. s15 -= carry[15] << 21
  1757. s5 += s17 * 666643
  1758. s6 += s17 * 470296
  1759. s7 += s17 * 654183
  1760. s8 -= s17 * 997805
  1761. s9 += s17 * 136657
  1762. s10 -= s17 * 683901
  1763. s17 = 0
  1764. s4 += s16 * 666643
  1765. s5 += s16 * 470296
  1766. s6 += s16 * 654183
  1767. s7 -= s16 * 997805
  1768. s8 += s16 * 136657
  1769. s9 -= s16 * 683901
  1770. s16 = 0
  1771. s3 += s15 * 666643
  1772. s4 += s15 * 470296
  1773. s5 += s15 * 654183
  1774. s6 -= s15 * 997805
  1775. s7 += s15 * 136657
  1776. s8 -= s15 * 683901
  1777. s15 = 0
  1778. s2 += s14 * 666643
  1779. s3 += s14 * 470296
  1780. s4 += s14 * 654183
  1781. s5 -= s14 * 997805
  1782. s6 += s14 * 136657
  1783. s7 -= s14 * 683901
  1784. s14 = 0
  1785. s1 += s13 * 666643
  1786. s2 += s13 * 470296
  1787. s3 += s13 * 654183
  1788. s4 -= s13 * 997805
  1789. s5 += s13 * 136657
  1790. s6 -= s13 * 683901
  1791. s13 = 0
  1792. s0 += s12 * 666643
  1793. s1 += s12 * 470296
  1794. s2 += s12 * 654183
  1795. s3 -= s12 * 997805
  1796. s4 += s12 * 136657
  1797. s5 -= s12 * 683901
  1798. s12 = 0
  1799. carry[0] = (s0 + (1 << 20)) >> 21
  1800. s1 += carry[0]
  1801. s0 -= carry[0] << 21
  1802. carry[2] = (s2 + (1 << 20)) >> 21
  1803. s3 += carry[2]
  1804. s2 -= carry[2] << 21
  1805. carry[4] = (s4 + (1 << 20)) >> 21
  1806. s5 += carry[4]
  1807. s4 -= carry[4] << 21
  1808. carry[6] = (s6 + (1 << 20)) >> 21
  1809. s7 += carry[6]
  1810. s6 -= carry[6] << 21
  1811. carry[8] = (s8 + (1 << 20)) >> 21
  1812. s9 += carry[8]
  1813. s8 -= carry[8] << 21
  1814. carry[10] = (s10 + (1 << 20)) >> 21
  1815. s11 += carry[10]
  1816. s10 -= carry[10] << 21
  1817. carry[1] = (s1 + (1 << 20)) >> 21
  1818. s2 += carry[1]
  1819. s1 -= carry[1] << 21
  1820. carry[3] = (s3 + (1 << 20)) >> 21
  1821. s4 += carry[3]
  1822. s3 -= carry[3] << 21
  1823. carry[5] = (s5 + (1 << 20)) >> 21
  1824. s6 += carry[5]
  1825. s5 -= carry[5] << 21
  1826. carry[7] = (s7 + (1 << 20)) >> 21
  1827. s8 += carry[7]
  1828. s7 -= carry[7] << 21
  1829. carry[9] = (s9 + (1 << 20)) >> 21
  1830. s10 += carry[9]
  1831. s9 -= carry[9] << 21
  1832. carry[11] = (s11 + (1 << 20)) >> 21
  1833. s12 += carry[11]
  1834. s11 -= carry[11] << 21
  1835. s0 += s12 * 666643
  1836. s1 += s12 * 470296
  1837. s2 += s12 * 654183
  1838. s3 -= s12 * 997805
  1839. s4 += s12 * 136657
  1840. s5 -= s12 * 683901
  1841. s12 = 0
  1842. carry[0] = s0 >> 21
  1843. s1 += carry[0]
  1844. s0 -= carry[0] << 21
  1845. carry[1] = s1 >> 21
  1846. s2 += carry[1]
  1847. s1 -= carry[1] << 21
  1848. carry[2] = s2 >> 21
  1849. s3 += carry[2]
  1850. s2 -= carry[2] << 21
  1851. carry[3] = s3 >> 21
  1852. s4 += carry[3]
  1853. s3 -= carry[3] << 21
  1854. carry[4] = s4 >> 21
  1855. s5 += carry[4]
  1856. s4 -= carry[4] << 21
  1857. carry[5] = s5 >> 21
  1858. s6 += carry[5]
  1859. s5 -= carry[5] << 21
  1860. carry[6] = s6 >> 21
  1861. s7 += carry[6]
  1862. s6 -= carry[6] << 21
  1863. carry[7] = s7 >> 21
  1864. s8 += carry[7]
  1865. s7 -= carry[7] << 21
  1866. carry[8] = s8 >> 21
  1867. s9 += carry[8]
  1868. s8 -= carry[8] << 21
  1869. carry[9] = s9 >> 21
  1870. s10 += carry[9]
  1871. s9 -= carry[9] << 21
  1872. carry[10] = s10 >> 21
  1873. s11 += carry[10]
  1874. s10 -= carry[10] << 21
  1875. carry[11] = s11 >> 21
  1876. s12 += carry[11]
  1877. s11 -= carry[11] << 21
  1878. s0 += s12 * 666643
  1879. s1 += s12 * 470296
  1880. s2 += s12 * 654183
  1881. s3 -= s12 * 997805
  1882. s4 += s12 * 136657
  1883. s5 -= s12 * 683901
  1884. s12 = 0
  1885. carry[0] = s0 >> 21
  1886. s1 += carry[0]
  1887. s0 -= carry[0] << 21
  1888. carry[1] = s1 >> 21
  1889. s2 += carry[1]
  1890. s1 -= carry[1] << 21
  1891. carry[2] = s2 >> 21
  1892. s3 += carry[2]
  1893. s2 -= carry[2] << 21
  1894. carry[3] = s3 >> 21
  1895. s4 += carry[3]
  1896. s3 -= carry[3] << 21
  1897. carry[4] = s4 >> 21
  1898. s5 += carry[4]
  1899. s4 -= carry[4] << 21
  1900. carry[5] = s5 >> 21
  1901. s6 += carry[5]
  1902. s5 -= carry[5] << 21
  1903. carry[6] = s6 >> 21
  1904. s7 += carry[6]
  1905. s6 -= carry[6] << 21
  1906. carry[7] = s7 >> 21
  1907. s8 += carry[7]
  1908. s7 -= carry[7] << 21
  1909. carry[8] = s8 >> 21
  1910. s9 += carry[8]
  1911. s8 -= carry[8] << 21
  1912. carry[9] = s9 >> 21
  1913. s10 += carry[9]
  1914. s9 -= carry[9] << 21
  1915. carry[10] = s10 >> 21
  1916. s11 += carry[10]
  1917. s10 -= carry[10] << 21
  1918. s[0] = byte(s0 >> 0)
  1919. s[1] = byte(s0 >> 8)
  1920. s[2] = byte((s0 >> 16) | (s1 << 5))
  1921. s[3] = byte(s1 >> 3)
  1922. s[4] = byte(s1 >> 11)
  1923. s[5] = byte((s1 >> 19) | (s2 << 2))
  1924. s[6] = byte(s2 >> 6)
  1925. s[7] = byte((s2 >> 14) | (s3 << 7))
  1926. s[8] = byte(s3 >> 1)
  1927. s[9] = byte(s3 >> 9)
  1928. s[10] = byte((s3 >> 17) | (s4 << 4))
  1929. s[11] = byte(s4 >> 4)
  1930. s[12] = byte(s4 >> 12)
  1931. s[13] = byte((s4 >> 20) | (s5 << 1))
  1932. s[14] = byte(s5 >> 7)
  1933. s[15] = byte((s5 >> 15) | (s6 << 6))
  1934. s[16] = byte(s6 >> 2)
  1935. s[17] = byte(s6 >> 10)
  1936. s[18] = byte((s6 >> 18) | (s7 << 3))
  1937. s[19] = byte(s7 >> 5)
  1938. s[20] = byte(s7 >> 13)
  1939. s[21] = byte(s8 >> 0)
  1940. s[22] = byte(s8 >> 8)
  1941. s[23] = byte((s8 >> 16) | (s9 << 5))
  1942. s[24] = byte(s9 >> 3)
  1943. s[25] = byte(s9 >> 11)
  1944. s[26] = byte((s9 >> 19) | (s10 << 2))
  1945. s[27] = byte(s10 >> 6)
  1946. s[28] = byte((s10 >> 14) | (s11 << 7))
  1947. s[29] = byte(s11 >> 1)
  1948. s[30] = byte(s11 >> 9)
  1949. s[31] = byte(s11 >> 17)
  1950. }
  1951. // Input:
  1952. // a[0]+256*a[1]+...+256^31*a[31] = a
  1953. // b[0]+256*b[1]+...+256^31*b[31] = b
  1954. // c[0]+256*c[1]+...+256^31*c[31] = c
  1955. //
  1956. // Output:
  1957. // s[0]+256*s[1]+...+256^31*s[31] = (c-ab) mod l
  1958. // where l = 2^252 + 27742317777372353535851937790883648493.
  1959. func ScMulSub(s, a, b, c *Key) {
  1960. a0 := 2097151 & load3(a[:])
  1961. a1 := 2097151 & (load4(a[2:]) >> 5)
  1962. a2 := 2097151 & (load3(a[5:]) >> 2)
  1963. a3 := 2097151 & (load4(a[7:]) >> 7)
  1964. a4 := 2097151 & (load4(a[10:]) >> 4)
  1965. a5 := 2097151 & (load3(a[13:]) >> 1)
  1966. a6 := 2097151 & (load4(a[15:]) >> 6)
  1967. a7 := 2097151 & (load3(a[18:]) >> 3)
  1968. a8 := 2097151 & load3(a[21:])
  1969. a9 := 2097151 & (load4(a[23:]) >> 5)
  1970. a10 := 2097151 & (load3(a[26:]) >> 2)
  1971. a11 := (load4(a[28:]) >> 7)
  1972. b0 := 2097151 & load3(b[:])
  1973. b1 := 2097151 & (load4(b[2:]) >> 5)
  1974. b2 := 2097151 & (load3(b[5:]) >> 2)
  1975. b3 := 2097151 & (load4(b[7:]) >> 7)
  1976. b4 := 2097151 & (load4(b[10:]) >> 4)
  1977. b5 := 2097151 & (load3(b[13:]) >> 1)
  1978. b6 := 2097151 & (load4(b[15:]) >> 6)
  1979. b7 := 2097151 & (load3(b[18:]) >> 3)
  1980. b8 := 2097151 & load3(b[21:])
  1981. b9 := 2097151 & (load4(b[23:]) >> 5)
  1982. b10 := 2097151 & (load3(b[26:]) >> 2)
  1983. b11 := (load4(b[28:]) >> 7)
  1984. c0 := 2097151 & load3(c[:])
  1985. c1 := 2097151 & (load4(c[2:]) >> 5)
  1986. c2 := 2097151 & (load3(c[5:]) >> 2)
  1987. c3 := 2097151 & (load4(c[7:]) >> 7)
  1988. c4 := 2097151 & (load4(c[10:]) >> 4)
  1989. c5 := 2097151 & (load3(c[13:]) >> 1)
  1990. c6 := 2097151 & (load4(c[15:]) >> 6)
  1991. c7 := 2097151 & (load3(c[18:]) >> 3)
  1992. c8 := 2097151 & load3(c[21:])
  1993. c9 := 2097151 & (load4(c[23:]) >> 5)
  1994. c10 := 2097151 & (load3(c[26:]) >> 2)
  1995. c11 := (load4(c[28:]) >> 7)
  1996. var carry [23]int64
  1997. s0 := c0 - a0*b0
  1998. s1 := c1 - a0*b1 - a1*b0
  1999. s2 := c2 - a0*b2 - a1*b1 - a2*b0
  2000. s3 := c3 - a0*b3 - a1*b2 - a2*b1 - a3*b0
  2001. s4 := c4 - a0*b4 - a1*b3 - a2*b2 - a3*b1 - a4*b0
  2002. s5 := c5 - a0*b5 - a1*b4 - a2*b3 - a3*b2 - a4*b1 - a5*b0
  2003. s6 := c6 - a0*b6 - a1*b5 - a2*b4 - a3*b3 - a4*b2 - a5*b1 - a6*b0
  2004. s7 := c7 - a0*b7 - a1*b6 - a2*b5 - a3*b4 - a4*b3 - a5*b2 - a6*b1 - a7*b0
  2005. s8 := c8 - a0*b8 - a1*b7 - a2*b6 - a3*b5 - a4*b4 - a5*b3 - a6*b2 - a7*b1 - a8*b0
  2006. s9 := c9 - a0*b9 - a1*b8 - a2*b7 - a3*b6 - a4*b5 - a5*b4 - a6*b3 - a7*b2 - a8*b1 - a9*b0
  2007. s10 := c10 - a0*b10 - a1*b9 - a2*b8 - a3*b7 - a4*b6 - a5*b5 - a6*b4 - a7*b3 - a8*b2 - a9*b1 - a10*b0
  2008. s11 := c11 - a0*b11 - a1*b10 - a2*b9 - a3*b8 - a4*b7 - a5*b6 - a6*b5 - a7*b4 - a8*b3 - a9*b2 - a10*b1 - a11*b0
  2009. s12 := -a1*b11 - a2*b10 - a3*b9 - a4*b8 - a5*b7 - a6*b6 - a7*b5 - a8*b4 - a9*b3 - a10*b2 - a11*b1
  2010. s13 := -a2*b11 - a3*b10 - a4*b9 - a5*b8 - a6*b7 - a7*b6 - a8*b5 - a9*b4 - a10*b3 - a11*b2
  2011. s14 := -a3*b11 - a4*b10 - a5*b9 - a6*b8 - a7*b7 - a8*b6 - a9*b5 - a10*b4 - a11*b3
  2012. s15 := -a4*b11 - a5*b10 - a6*b9 - a7*b8 - a8*b7 - a9*b6 - a10*b5 - a11*b4
  2013. s16 := -a5*b11 - a6*b10 - a7*b9 - a8*b8 - a9*b7 - a10*b6 - a11*b5
  2014. s17 := -a6*b11 - a7*b10 - a8*b9 - a9*b8 - a10*b7 - a11*b6
  2015. s18 := -a7*b11 - a8*b10 - a9*b9 - a10*b8 - a11*b7
  2016. s19 := -a8*b11 - a9*b10 - a10*b9 - a11*b8
  2017. s20 := -a9*b11 - a10*b10 - a11*b9
  2018. s21 := -a10*b11 - a11*b10
  2019. s22 := -a11 * b11
  2020. s23 := int64(0)
  2021. carry[0] = (s0 + (1 << 20)) >> 21
  2022. s1 += carry[0]
  2023. s0 -= carry[0] << 21
  2024. carry[2] = (s2 + (1 << 20)) >> 21
  2025. s3 += carry[2]
  2026. s2 -= carry[2] << 21
  2027. carry[4] = (s4 + (1 << 20)) >> 21
  2028. s5 += carry[4]
  2029. s4 -= carry[4] << 21
  2030. carry[6] = (s6 + (1 << 20)) >> 21
  2031. s7 += carry[6]
  2032. s6 -= carry[6] << 21
  2033. carry[8] = (s8 + (1 << 20)) >> 21
  2034. s9 += carry[8]
  2035. s8 -= carry[8] << 21
  2036. carry[10] = (s10 + (1 << 20)) >> 21
  2037. s11 += carry[10]
  2038. s10 -= carry[10] << 21
  2039. carry[12] = (s12 + (1 << 20)) >> 21
  2040. s13 += carry[12]
  2041. s12 -= carry[12] << 21
  2042. carry[14] = (s14 + (1 << 20)) >> 21
  2043. s15 += carry[14]
  2044. s14 -= carry[14] << 21
  2045. carry[16] = (s16 + (1 << 20)) >> 21
  2046. s17 += carry[16]
  2047. s16 -= carry[16] << 21
  2048. carry[18] = (s18 + (1 << 20)) >> 21
  2049. s19 += carry[18]
  2050. s18 -= carry[18] << 21
  2051. carry[20] = (s20 + (1 << 20)) >> 21
  2052. s21 += carry[20]
  2053. s20 -= carry[20] << 21
  2054. carry[22] = (s22 + (1 << 20)) >> 21
  2055. s23 += carry[22]
  2056. s22 -= carry[22] << 21
  2057. carry[1] = (s1 + (1 << 20)) >> 21
  2058. s2 += carry[1]
  2059. s1 -= carry[1] << 21
  2060. carry[3] = (s3 + (1 << 20)) >> 21
  2061. s4 += carry[3]
  2062. s3 -= carry[3] << 21
  2063. carry[5] = (s5 + (1 << 20)) >> 21
  2064. s6 += carry[5]
  2065. s5 -= carry[5] << 21
  2066. carry[7] = (s7 + (1 << 20)) >> 21
  2067. s8 += carry[7]
  2068. s7 -= carry[7] << 21
  2069. carry[9] = (s9 + (1 << 20)) >> 21
  2070. s10 += carry[9]
  2071. s9 -= carry[9] << 21
  2072. carry[11] = (s11 + (1 << 20)) >> 21
  2073. s12 += carry[11]
  2074. s11 -= carry[11] << 21
  2075. carry[13] = (s13 + (1 << 20)) >> 21
  2076. s14 += carry[13]
  2077. s13 -= carry[13] << 21
  2078. carry[15] = (s15 + (1 << 20)) >> 21
  2079. s16 += carry[15]
  2080. s15 -= carry[15] << 21
  2081. carry[17] = (s17 + (1 << 20)) >> 21
  2082. s18 += carry[17]
  2083. s17 -= carry[17] << 21
  2084. carry[19] = (s19 + (1 << 20)) >> 21
  2085. s20 += carry[19]
  2086. s19 -= carry[19] << 21
  2087. carry[21] = (s21 + (1 << 20)) >> 21
  2088. s22 += carry[21]
  2089. s21 -= carry[21] << 21
  2090. s11 += s23 * 666643
  2091. s12 += s23 * 470296
  2092. s13 += s23 * 654183
  2093. s14 -= s23 * 997805
  2094. s15 += s23 * 136657
  2095. s16 -= s23 * 683901
  2096. s23 = 0
  2097. s10 += s22 * 666643
  2098. s11 += s22 * 470296
  2099. s12 += s22 * 654183
  2100. s13 -= s22 * 997805
  2101. s14 += s22 * 136657
  2102. s15 -= s22 * 683901
  2103. s22 = 0
  2104. s9 += s21 * 666643
  2105. s10 += s21 * 470296
  2106. s11 += s21 * 654183
  2107. s12 -= s21 * 997805
  2108. s13 += s21 * 136657
  2109. s14 -= s21 * 683901
  2110. s21 = 0
  2111. s8 += s20 * 666643
  2112. s9 += s20 * 470296
  2113. s10 += s20 * 654183
  2114. s11 -= s20 * 997805
  2115. s12 += s20 * 136657
  2116. s13 -= s20 * 683901
  2117. s20 = 0
  2118. s7 += s19 * 666643
  2119. s8 += s19 * 470296
  2120. s9 += s19 * 654183
  2121. s10 -= s19 * 997805
  2122. s11 += s19 * 136657
  2123. s12 -= s19 * 683901
  2124. s19 = 0
  2125. s6 += s18 * 666643
  2126. s7 += s18 * 470296
  2127. s8 += s18 * 654183
  2128. s9 -= s18 * 997805
  2129. s10 += s18 * 136657
  2130. s11 -= s18 * 683901
  2131. s18 = 0
  2132. carry[6] = (s6 + (1 << 20)) >> 21
  2133. s7 += carry[6]
  2134. s6 -= carry[6] << 21
  2135. carry[8] = (s8 + (1 << 20)) >> 21
  2136. s9 += carry[8]
  2137. s8 -= carry[8] << 21
  2138. carry[10] = (s10 + (1 << 20)) >> 21
  2139. s11 += carry[10]
  2140. s10 -= carry[10] << 21
  2141. carry[12] = (s12 + (1 << 20)) >> 21
  2142. s13 += carry[12]
  2143. s12 -= carry[12] << 21
  2144. carry[14] = (s14 + (1 << 20)) >> 21
  2145. s15 += carry[14]
  2146. s14 -= carry[14] << 21
  2147. carry[16] = (s16 + (1 << 20)) >> 21
  2148. s17 += carry[16]
  2149. s16 -= carry[16] << 21
  2150. carry[7] = (s7 + (1 << 20)) >> 21
  2151. s8 += carry[7]
  2152. s7 -= carry[7] << 21
  2153. carry[9] = (s9 + (1 << 20)) >> 21
  2154. s10 += carry[9]
  2155. s9 -= carry[9] << 21
  2156. carry[11] = (s11 + (1 << 20)) >> 21
  2157. s12 += carry[11]
  2158. s11 -= carry[11] << 21
  2159. carry[13] = (s13 + (1 << 20)) >> 21
  2160. s14 += carry[13]
  2161. s13 -= carry[13] << 21
  2162. carry[15] = (s15 + (1 << 20)) >> 21
  2163. s16 += carry[15]
  2164. s15 -= carry[15] << 21
  2165. s5 += s17 * 666643
  2166. s6 += s17 * 470296
  2167. s7 += s17 * 654183
  2168. s8 -= s17 * 997805
  2169. s9 += s17 * 136657
  2170. s10 -= s17 * 683901
  2171. s17 = 0
  2172. s4 += s16 * 666643
  2173. s5 += s16 * 470296
  2174. s6 += s16 * 654183
  2175. s7 -= s16 * 997805
  2176. s8 += s16 * 136657
  2177. s9 -= s16 * 683901
  2178. s16 = 0
  2179. s3 += s15 * 666643
  2180. s4 += s15 * 470296
  2181. s5 += s15 * 654183
  2182. s6 -= s15 * 997805
  2183. s7 += s15 * 136657
  2184. s8 -= s15 * 683901
  2185. s15 = 0
  2186. s2 += s14 * 666643
  2187. s3 += s14 * 470296
  2188. s4 += s14 * 654183
  2189. s5 -= s14 * 997805
  2190. s6 += s14 * 136657
  2191. s7 -= s14 * 683901
  2192. s14 = 0
  2193. s1 += s13 * 666643
  2194. s2 += s13 * 470296
  2195. s3 += s13 * 654183
  2196. s4 -= s13 * 997805
  2197. s5 += s13 * 136657
  2198. s6 -= s13 * 683901
  2199. s13 = 0
  2200. s0 += s12 * 666643
  2201. s1 += s12 * 470296
  2202. s2 += s12 * 654183
  2203. s3 -= s12 * 997805
  2204. s4 += s12 * 136657
  2205. s5 -= s12 * 683901
  2206. s12 = 0
  2207. carry[0] = (s0 + (1 << 20)) >> 21
  2208. s1 += carry[0]
  2209. s0 -= carry[0] << 21
  2210. carry[2] = (s2 + (1 << 20)) >> 21
  2211. s3 += carry[2]
  2212. s2 -= carry[2] << 21
  2213. carry[4] = (s4 + (1 << 20)) >> 21
  2214. s5 += carry[4]
  2215. s4 -= carry[4] << 21
  2216. carry[6] = (s6 + (1 << 20)) >> 21
  2217. s7 += carry[6]
  2218. s6 -= carry[6] << 21
  2219. carry[8] = (s8 + (1 << 20)) >> 21
  2220. s9 += carry[8]
  2221. s8 -= carry[8] << 21
  2222. carry[10] = (s10 + (1 << 20)) >> 21
  2223. s11 += carry[10]
  2224. s10 -= carry[10] << 21
  2225. carry[1] = (s1 + (1 << 20)) >> 21
  2226. s2 += carry[1]
  2227. s1 -= carry[1] << 21
  2228. carry[3] = (s3 + (1 << 20)) >> 21
  2229. s4 += carry[3]
  2230. s3 -= carry[3] << 21
  2231. carry[5] = (s5 + (1 << 20)) >> 21
  2232. s6 += carry[5]
  2233. s5 -= carry[5] << 21
  2234. carry[7] = (s7 + (1 << 20)) >> 21
  2235. s8 += carry[7]
  2236. s7 -= carry[7] << 21
  2237. carry[9] = (s9 + (1 << 20)) >> 21
  2238. s10 += carry[9]
  2239. s9 -= carry[9] << 21
  2240. carry[11] = (s11 + (1 << 20)) >> 21
  2241. s12 += carry[11]
  2242. s11 -= carry[11] << 21
  2243. s0 += s12 * 666643
  2244. s1 += s12 * 470296
  2245. s2 += s12 * 654183
  2246. s3 -= s12 * 997805
  2247. s4 += s12 * 136657
  2248. s5 -= s12 * 683901
  2249. s12 = 0
  2250. carry[0] = s0 >> 21
  2251. s1 += carry[0]
  2252. s0 -= carry[0] << 21
  2253. carry[1] = s1 >> 21
  2254. s2 += carry[1]
  2255. s1 -= carry[1] << 21
  2256. carry[2] = s2 >> 21
  2257. s3 += carry[2]
  2258. s2 -= carry[2] << 21
  2259. carry[3] = s3 >> 21
  2260. s4 += carry[3]
  2261. s3 -= carry[3] << 21
  2262. carry[4] = s4 >> 21
  2263. s5 += carry[4]
  2264. s4 -= carry[4] << 21
  2265. carry[5] = s5 >> 21
  2266. s6 += carry[5]
  2267. s5 -= carry[5] << 21
  2268. carry[6] = s6 >> 21
  2269. s7 += carry[6]
  2270. s6 -= carry[6] << 21
  2271. carry[7] = s7 >> 21
  2272. s8 += carry[7]
  2273. s7 -= carry[7] << 21
  2274. carry[8] = s8 >> 21
  2275. s9 += carry[8]
  2276. s8 -= carry[8] << 21
  2277. carry[9] = s9 >> 21
  2278. s10 += carry[9]
  2279. s9 -= carry[9] << 21
  2280. carry[10] = s10 >> 21
  2281. s11 += carry[10]
  2282. s10 -= carry[10] << 21
  2283. carry[11] = s11 >> 21
  2284. s12 += carry[11]
  2285. s11 -= carry[11] << 21
  2286. s0 += s12 * 666643
  2287. s1 += s12 * 470296
  2288. s2 += s12 * 654183
  2289. s3 -= s12 * 997805
  2290. s4 += s12 * 136657
  2291. s5 -= s12 * 683901
  2292. s12 = 0
  2293. carry[0] = s0 >> 21
  2294. s1 += carry[0]
  2295. s0 -= carry[0] << 21
  2296. carry[1] = s1 >> 21
  2297. s2 += carry[1]
  2298. s1 -= carry[1] << 21
  2299. carry[2] = s2 >> 21
  2300. s3 += carry[2]
  2301. s2 -= carry[2] << 21
  2302. carry[3] = s3 >> 21
  2303. s4 += carry[3]
  2304. s3 -= carry[3] << 21
  2305. carry[4] = s4 >> 21
  2306. s5 += carry[4]
  2307. s4 -= carry[4] << 21
  2308. carry[5] = s5 >> 21
  2309. s6 += carry[5]
  2310. s5 -= carry[5] << 21
  2311. carry[6] = s6 >> 21
  2312. s7 += carry[6]
  2313. s6 -= carry[6] << 21
  2314. carry[7] = s7 >> 21
  2315. s8 += carry[7]
  2316. s7 -= carry[7] << 21
  2317. carry[8] = s8 >> 21
  2318. s9 += carry[8]
  2319. s8 -= carry[8] << 21
  2320. carry[9] = s9 >> 21
  2321. s10 += carry[9]
  2322. s9 -= carry[9] << 21
  2323. carry[10] = s10 >> 21
  2324. s11 += carry[10]
  2325. s10 -= carry[10] << 21
  2326. s[0] = byte(s0 >> 0)
  2327. s[1] = byte(s0 >> 8)
  2328. s[2] = byte((s0 >> 16) | (s1 << 5))
  2329. s[3] = byte(s1 >> 3)
  2330. s[4] = byte(s1 >> 11)
  2331. s[5] = byte((s1 >> 19) | (s2 << 2))
  2332. s[6] = byte(s2 >> 6)
  2333. s[7] = byte((s2 >> 14) | (s3 << 7))
  2334. s[8] = byte(s3 >> 1)
  2335. s[9] = byte(s3 >> 9)
  2336. s[10] = byte((s3 >> 17) | (s4 << 4))
  2337. s[11] = byte(s4 >> 4)
  2338. s[12] = byte(s4 >> 12)
  2339. s[13] = byte((s4 >> 20) | (s5 << 1))
  2340. s[14] = byte(s5 >> 7)
  2341. s[15] = byte((s5 >> 15) | (s6 << 6))
  2342. s[16] = byte(s6 >> 2)
  2343. s[17] = byte(s6 >> 10)
  2344. s[18] = byte((s6 >> 18) | (s7 << 3))
  2345. s[19] = byte(s7 >> 5)
  2346. s[20] = byte(s7 >> 13)
  2347. s[21] = byte(s8 >> 0)
  2348. s[22] = byte(s8 >> 8)
  2349. s[23] = byte((s8 >> 16) | (s9 << 5))
  2350. s[24] = byte(s9 >> 3)
  2351. s[25] = byte(s9 >> 11)
  2352. s[26] = byte((s9 >> 19) | (s10 << 2))
  2353. s[27] = byte(s10 >> 6)
  2354. s[28] = byte((s10 >> 14) | (s11 << 7))
  2355. s[29] = byte(s11 >> 1)
  2356. s[30] = byte(s11 >> 9)
  2357. s[31] = byte(s11 >> 17)
  2358. }
  2359. // Input:
  2360. // s[0]+256*s[1]+...+256^63*s[63] = s
  2361. //
  2362. // Output:
  2363. // s[0]+256*s[1]+...+256^31*s[31] = s mod l
  2364. // where l = 2^252 + 27742317777372353535851937790883648493.
  2365. func ScReduce(out *Key, s *[64]byte) {
  2366. s0 := 2097151 & load3(s[:])
  2367. s1 := 2097151 & (load4(s[2:]) >> 5)
  2368. s2 := 2097151 & (load3(s[5:]) >> 2)
  2369. s3 := 2097151 & (load4(s[7:]) >> 7)
  2370. s4 := 2097151 & (load4(s[10:]) >> 4)
  2371. s5 := 2097151 & (load3(s[13:]) >> 1)
  2372. s6 := 2097151 & (load4(s[15:]) >> 6)
  2373. s7 := 2097151 & (load3(s[18:]) >> 3)
  2374. s8 := 2097151 & load3(s[21:])
  2375. s9 := 2097151 & (load4(s[23:]) >> 5)
  2376. s10 := 2097151 & (load3(s[26:]) >> 2)
  2377. s11 := 2097151 & (load4(s[28:]) >> 7)
  2378. s12 := 2097151 & (load4(s[31:]) >> 4)
  2379. s13 := 2097151 & (load3(s[34:]) >> 1)
  2380. s14 := 2097151 & (load4(s[36:]) >> 6)
  2381. s15 := 2097151 & (load3(s[39:]) >> 3)
  2382. s16 := 2097151 & load3(s[42:])
  2383. s17 := 2097151 & (load4(s[44:]) >> 5)
  2384. s18 := 2097151 & (load3(s[47:]) >> 2)
  2385. s19 := 2097151 & (load4(s[49:]) >> 7)
  2386. s20 := 2097151 & (load4(s[52:]) >> 4)
  2387. s21 := 2097151 & (load3(s[55:]) >> 1)
  2388. s22 := 2097151 & (load4(s[57:]) >> 6)
  2389. s23 := (load4(s[60:]) >> 3)
  2390. s11 += s23 * 666643
  2391. s12 += s23 * 470296
  2392. s13 += s23 * 654183
  2393. s14 -= s23 * 997805
  2394. s15 += s23 * 136657
  2395. s16 -= s23 * 683901
  2396. s23 = 0
  2397. s10 += s22 * 666643
  2398. s11 += s22 * 470296
  2399. s12 += s22 * 654183
  2400. s13 -= s22 * 997805
  2401. s14 += s22 * 136657
  2402. s15 -= s22 * 683901
  2403. s22 = 0
  2404. s9 += s21 * 666643
  2405. s10 += s21 * 470296
  2406. s11 += s21 * 654183
  2407. s12 -= s21 * 997805
  2408. s13 += s21 * 136657
  2409. s14 -= s21 * 683901
  2410. s21 = 0
  2411. s8 += s20 * 666643
  2412. s9 += s20 * 470296
  2413. s10 += s20 * 654183
  2414. s11 -= s20 * 997805
  2415. s12 += s20 * 136657
  2416. s13 -= s20 * 683901
  2417. s20 = 0
  2418. s7 += s19 * 666643
  2419. s8 += s19 * 470296
  2420. s9 += s19 * 654183
  2421. s10 -= s19 * 997805
  2422. s11 += s19 * 136657
  2423. s12 -= s19 * 683901
  2424. s19 = 0
  2425. s6 += s18 * 666643
  2426. s7 += s18 * 470296
  2427. s8 += s18 * 654183
  2428. s9 -= s18 * 997805
  2429. s10 += s18 * 136657
  2430. s11 -= s18 * 683901
  2431. s18 = 0
  2432. var carry [17]int64
  2433. carry[6] = (s6 + (1 << 20)) >> 21
  2434. s7 += carry[6]
  2435. s6 -= carry[6] << 21
  2436. carry[8] = (s8 + (1 << 20)) >> 21
  2437. s9 += carry[8]
  2438. s8 -= carry[8] << 21
  2439. carry[10] = (s10 + (1 << 20)) >> 21
  2440. s11 += carry[10]
  2441. s10 -= carry[10] << 21
  2442. carry[12] = (s12 + (1 << 20)) >> 21
  2443. s13 += carry[12]
  2444. s12 -= carry[12] << 21
  2445. carry[14] = (s14 + (1 << 20)) >> 21
  2446. s15 += carry[14]
  2447. s14 -= carry[14] << 21
  2448. carry[16] = (s16 + (1 << 20)) >> 21
  2449. s17 += carry[16]
  2450. s16 -= carry[16] << 21
  2451. carry[7] = (s7 + (1 << 20)) >> 21
  2452. s8 += carry[7]
  2453. s7 -= carry[7] << 21
  2454. carry[9] = (s9 + (1 << 20)) >> 21
  2455. s10 += carry[9]
  2456. s9 -= carry[9] << 21
  2457. carry[11] = (s11 + (1 << 20)) >> 21
  2458. s12 += carry[11]
  2459. s11 -= carry[11] << 21
  2460. carry[13] = (s13 + (1 << 20)) >> 21
  2461. s14 += carry[13]
  2462. s13 -= carry[13] << 21
  2463. carry[15] = (s15 + (1 << 20)) >> 21
  2464. s16 += carry[15]
  2465. s15 -= carry[15] << 21
  2466. s5 += s17 * 666643
  2467. s6 += s17 * 470296
  2468. s7 += s17 * 654183
  2469. s8 -= s17 * 997805
  2470. s9 += s17 * 136657
  2471. s10 -= s17 * 683901
  2472. s17 = 0
  2473. s4 += s16 * 666643
  2474. s5 += s16 * 470296
  2475. s6 += s16 * 654183
  2476. s7 -= s16 * 997805
  2477. s8 += s16 * 136657
  2478. s9 -= s16 * 683901
  2479. s16 = 0
  2480. s3 += s15 * 666643
  2481. s4 += s15 * 470296
  2482. s5 += s15 * 654183
  2483. s6 -= s15 * 997805
  2484. s7 += s15 * 136657
  2485. s8 -= s15 * 683901
  2486. s15 = 0
  2487. s2 += s14 * 666643
  2488. s3 += s14 * 470296
  2489. s4 += s14 * 654183
  2490. s5 -= s14 * 997805
  2491. s6 += s14 * 136657
  2492. s7 -= s14 * 683901
  2493. s14 = 0
  2494. s1 += s13 * 666643
  2495. s2 += s13 * 470296
  2496. s3 += s13 * 654183
  2497. s4 -= s13 * 997805
  2498. s5 += s13 * 136657
  2499. s6 -= s13 * 683901
  2500. s13 = 0
  2501. s0 += s12 * 666643
  2502. s1 += s12 * 470296
  2503. s2 += s12 * 654183
  2504. s3 -= s12 * 997805
  2505. s4 += s12 * 136657
  2506. s5 -= s12 * 683901
  2507. s12 = 0
  2508. carry[0] = (s0 + (1 << 20)) >> 21
  2509. s1 += carry[0]
  2510. s0 -= carry[0] << 21
  2511. carry[2] = (s2 + (1 << 20)) >> 21
  2512. s3 += carry[2]
  2513. s2 -= carry[2] << 21
  2514. carry[4] = (s4 + (1 << 20)) >> 21
  2515. s5 += carry[4]
  2516. s4 -= carry[4] << 21
  2517. carry[6] = (s6 + (1 << 20)) >> 21
  2518. s7 += carry[6]
  2519. s6 -= carry[6] << 21
  2520. carry[8] = (s8 + (1 << 20)) >> 21
  2521. s9 += carry[8]
  2522. s8 -= carry[8] << 21
  2523. carry[10] = (s10 + (1 << 20)) >> 21
  2524. s11 += carry[10]
  2525. s10 -= carry[10] << 21
  2526. carry[1] = (s1 + (1 << 20)) >> 21
  2527. s2 += carry[1]
  2528. s1 -= carry[1] << 21
  2529. carry[3] = (s3 + (1 << 20)) >> 21
  2530. s4 += carry[3]
  2531. s3 -= carry[3] << 21
  2532. carry[5] = (s5 + (1 << 20)) >> 21
  2533. s6 += carry[5]
  2534. s5 -= carry[5] << 21
  2535. carry[7] = (s7 + (1 << 20)) >> 21
  2536. s8 += carry[7]
  2537. s7 -= carry[7] << 21
  2538. carry[9] = (s9 + (1 << 20)) >> 21
  2539. s10 += carry[9]
  2540. s9 -= carry[9] << 21
  2541. carry[11] = (s11 + (1 << 20)) >> 21
  2542. s12 += carry[11]
  2543. s11 -= carry[11] << 21
  2544. s0 += s12 * 666643
  2545. s1 += s12 * 470296
  2546. s2 += s12 * 654183
  2547. s3 -= s12 * 997805
  2548. s4 += s12 * 136657
  2549. s5 -= s12 * 683901
  2550. s12 = 0
  2551. carry[0] = s0 >> 21
  2552. s1 += carry[0]
  2553. s0 -= carry[0] << 21
  2554. carry[1] = s1 >> 21
  2555. s2 += carry[1]
  2556. s1 -= carry[1] << 21
  2557. carry[2] = s2 >> 21
  2558. s3 += carry[2]
  2559. s2 -= carry[2] << 21
  2560. carry[3] = s3 >> 21
  2561. s4 += carry[3]
  2562. s3 -= carry[3] << 21
  2563. carry[4] = s4 >> 21
  2564. s5 += carry[4]
  2565. s4 -= carry[4] << 21
  2566. carry[5] = s5 >> 21
  2567. s6 += carry[5]
  2568. s5 -= carry[5] << 21
  2569. carry[6] = s6 >> 21
  2570. s7 += carry[6]
  2571. s6 -= carry[6] << 21
  2572. carry[7] = s7 >> 21
  2573. s8 += carry[7]
  2574. s7 -= carry[7] << 21
  2575. carry[8] = s8 >> 21
  2576. s9 += carry[8]
  2577. s8 -= carry[8] << 21
  2578. carry[9] = s9 >> 21
  2579. s10 += carry[9]
  2580. s9 -= carry[9] << 21
  2581. carry[10] = s10 >> 21
  2582. s11 += carry[10]
  2583. s10 -= carry[10] << 21
  2584. carry[11] = s11 >> 21
  2585. s12 += carry[11]
  2586. s11 -= carry[11] << 21
  2587. s0 += s12 * 666643
  2588. s1 += s12 * 470296
  2589. s2 += s12 * 654183
  2590. s3 -= s12 * 997805
  2591. s4 += s12 * 136657
  2592. s5 -= s12 * 683901
  2593. s12 = 0
  2594. carry[0] = s0 >> 21
  2595. s1 += carry[0]
  2596. s0 -= carry[0] << 21
  2597. carry[1] = s1 >> 21
  2598. s2 += carry[1]
  2599. s1 -= carry[1] << 21
  2600. carry[2] = s2 >> 21
  2601. s3 += carry[2]
  2602. s2 -= carry[2] << 21
  2603. carry[3] = s3 >> 21
  2604. s4 += carry[3]
  2605. s3 -= carry[3] << 21
  2606. carry[4] = s4 >> 21
  2607. s5 += carry[4]
  2608. s4 -= carry[4] << 21
  2609. carry[5] = s5 >> 21
  2610. s6 += carry[5]
  2611. s5 -= carry[5] << 21
  2612. carry[6] = s6 >> 21
  2613. s7 += carry[6]
  2614. s6 -= carry[6] << 21
  2615. carry[7] = s7 >> 21
  2616. s8 += carry[7]
  2617. s7 -= carry[7] << 21
  2618. carry[8] = s8 >> 21
  2619. s9 += carry[8]
  2620. s8 -= carry[8] << 21
  2621. carry[9] = s9 >> 21
  2622. s10 += carry[9]
  2623. s9 -= carry[9] << 21
  2624. carry[10] = s10 >> 21
  2625. s11 += carry[10]
  2626. s10 -= carry[10] << 21
  2627. out[0] = byte(s0 >> 0)
  2628. out[1] = byte(s0 >> 8)
  2629. out[2] = byte((s0 >> 16) | (s1 << 5))
  2630. out[3] = byte(s1 >> 3)
  2631. out[4] = byte(s1 >> 11)
  2632. out[5] = byte((s1 >> 19) | (s2 << 2))
  2633. out[6] = byte(s2 >> 6)
  2634. out[7] = byte((s2 >> 14) | (s3 << 7))
  2635. out[8] = byte(s3 >> 1)
  2636. out[9] = byte(s3 >> 9)
  2637. out[10] = byte((s3 >> 17) | (s4 << 4))
  2638. out[11] = byte(s4 >> 4)
  2639. out[12] = byte(s4 >> 12)
  2640. out[13] = byte((s4 >> 20) | (s5 << 1))
  2641. out[14] = byte(s5 >> 7)
  2642. out[15] = byte((s5 >> 15) | (s6 << 6))
  2643. out[16] = byte(s6 >> 2)
  2644. out[17] = byte(s6 >> 10)
  2645. out[18] = byte((s6 >> 18) | (s7 << 3))
  2646. out[19] = byte(s7 >> 5)
  2647. out[20] = byte(s7 >> 13)
  2648. out[21] = byte(s8 >> 0)
  2649. out[22] = byte(s8 >> 8)
  2650. out[23] = byte((s8 >> 16) | (s9 << 5))
  2651. out[24] = byte(s9 >> 3)
  2652. out[25] = byte(s9 >> 11)
  2653. out[26] = byte((s9 >> 19) | (s10 << 2))
  2654. out[27] = byte(s10 >> 6)
  2655. out[28] = byte((s10 >> 14) | (s11 << 7))
  2656. out[29] = byte(s11 >> 1)
  2657. out[30] = byte(s11 >> 9)
  2658. out[31] = byte(s11 >> 17)
  2659. }
  2660. func ScReduce32(s *Key) {
  2661. s0 := 2097151 & load3(s[:])
  2662. s1 := 2097151 & (load4(s[2:]) >> 5)
  2663. s2 := 2097151 & (load3(s[5:]) >> 2)
  2664. s3 := 2097151 & (load4(s[7:]) >> 7)
  2665. s4 := 2097151 & (load4(s[10:]) >> 4)
  2666. s5 := 2097151 & (load3(s[13:]) >> 1)
  2667. s6 := 2097151 & (load4(s[15:]) >> 6)
  2668. s7 := 2097151 & (load3(s[18:]) >> 3)
  2669. s8 := 2097151 & load3(s[21:])
  2670. s9 := 2097151 & (load4(s[23:]) >> 5)
  2671. s10 := 2097151 & (load3(s[26:]) >> 2)
  2672. s11 := (load4(s[28:]) >> 7)
  2673. s12 := int64(0)
  2674. var carry [12]int64
  2675. carry[0] = (s0 + (1 << 20)) >> 21
  2676. s1 += carry[0]
  2677. s0 -= carry[0] << 21
  2678. carry[2] = (s2 + (1 << 20)) >> 21
  2679. s3 += carry[2]
  2680. s2 -= carry[2] << 21
  2681. carry[4] = (s4 + (1 << 20)) >> 21
  2682. s5 += carry[4]
  2683. s4 -= carry[4] << 21
  2684. carry[6] = (s6 + (1 << 20)) >> 21
  2685. s7 += carry[6]
  2686. s6 -= carry[6] << 21
  2687. carry[8] = (s8 + (1 << 20)) >> 21
  2688. s9 += carry[8]
  2689. s8 -= carry[8] << 21
  2690. carry[10] = (s10 + (1 << 20)) >> 21
  2691. s11 += carry[10]
  2692. s10 -= carry[10] << 21
  2693. carry[1] = (s1 + (1 << 20)) >> 21
  2694. s2 += carry[1]
  2695. s1 -= carry[1] << 21
  2696. carry[3] = (s3 + (1 << 20)) >> 21
  2697. s4 += carry[3]
  2698. s3 -= carry[3] << 21
  2699. carry[5] = (s5 + (1 << 20)) >> 21
  2700. s6 += carry[5]
  2701. s5 -= carry[5] << 21
  2702. carry[7] = (s7 + (1 << 20)) >> 21
  2703. s8 += carry[7]
  2704. s7 -= carry[7] << 21
  2705. carry[9] = (s9 + (1 << 20)) >> 21
  2706. s10 += carry[9]
  2707. s9 -= carry[9] << 21
  2708. carry[11] = (s11 + (1 << 20)) >> 21
  2709. s12 += carry[11]
  2710. s11 -= carry[11] << 21
  2711. s0 += s12 * 666643
  2712. s1 += s12 * 470296
  2713. s2 += s12 * 654183
  2714. s3 -= s12 * 997805
  2715. s4 += s12 * 136657
  2716. s5 -= s12 * 683901
  2717. s12 = 0
  2718. carry[0] = s0 >> 21
  2719. s1 += carry[0]
  2720. s0 -= carry[0] << 21
  2721. carry[1] = s1 >> 21
  2722. s2 += carry[1]
  2723. s1 -= carry[1] << 21
  2724. carry[2] = s2 >> 21
  2725. s3 += carry[2]
  2726. s2 -= carry[2] << 21
  2727. carry[3] = s3 >> 21
  2728. s4 += carry[3]
  2729. s3 -= carry[3] << 21
  2730. carry[4] = s4 >> 21
  2731. s5 += carry[4]
  2732. s4 -= carry[4] << 21
  2733. carry[5] = s5 >> 21
  2734. s6 += carry[5]
  2735. s5 -= carry[5] << 21
  2736. carry[6] = s6 >> 21
  2737. s7 += carry[6]
  2738. s6 -= carry[6] << 21
  2739. carry[7] = s7 >> 21
  2740. s8 += carry[7]
  2741. s7 -= carry[7] << 21
  2742. carry[8] = s8 >> 21
  2743. s9 += carry[8]
  2744. s8 -= carry[8] << 21
  2745. carry[9] = s9 >> 21
  2746. s10 += carry[9]
  2747. s9 -= carry[9] << 21
  2748. carry[10] = s10 >> 21
  2749. s11 += carry[10]
  2750. s10 -= carry[10] << 21
  2751. carry[11] = s11 >> 21
  2752. s12 += carry[11]
  2753. s11 -= carry[11] << 21
  2754. s0 += s12 * 666643
  2755. s1 += s12 * 470296
  2756. s2 += s12 * 654183
  2757. s3 -= s12 * 997805
  2758. s4 += s12 * 136657
  2759. s5 -= s12 * 683901
  2760. carry[0] = s0 >> 21
  2761. s1 += carry[0]
  2762. s0 -= carry[0] << 21
  2763. carry[1] = s1 >> 21
  2764. s2 += carry[1]
  2765. s1 -= carry[1] << 21
  2766. carry[2] = s2 >> 21
  2767. s3 += carry[2]
  2768. s2 -= carry[2] << 21
  2769. carry[3] = s3 >> 21
  2770. s4 += carry[3]
  2771. s3 -= carry[3] << 21
  2772. carry[4] = s4 >> 21
  2773. s5 += carry[4]
  2774. s4 -= carry[4] << 21
  2775. carry[5] = s5 >> 21
  2776. s6 += carry[5]
  2777. s5 -= carry[5] << 21
  2778. carry[6] = s6 >> 21
  2779. s7 += carry[6]
  2780. s6 -= carry[6] << 21
  2781. carry[7] = s7 >> 21
  2782. s8 += carry[7]
  2783. s7 -= carry[7] << 21
  2784. carry[8] = s8 >> 21
  2785. s9 += carry[8]
  2786. s8 -= carry[8] << 21
  2787. carry[9] = s9 >> 21
  2788. s10 += carry[9]
  2789. s9 -= carry[9] << 21
  2790. carry[10] = s10 >> 21
  2791. s11 += carry[10]
  2792. s10 -= carry[10] << 21
  2793. s[0] = byte(s0 >> 0)
  2794. s[1] = byte(s0 >> 8)
  2795. s[2] = byte((s0 >> 16) | (s1 << 5))
  2796. s[3] = byte(s1 >> 3)
  2797. s[4] = byte(s1 >> 11)
  2798. s[5] = byte((s1 >> 19) | (s2 << 2))
  2799. s[6] = byte(s2 >> 6)
  2800. s[7] = byte((s2 >> 14) | (s3 << 7))
  2801. s[8] = byte(s3 >> 1)
  2802. s[9] = byte(s3 >> 9)
  2803. s[10] = byte((s3 >> 17) | (s4 << 4))
  2804. s[11] = byte(s4 >> 4)
  2805. s[12] = byte(s4 >> 12)
  2806. s[13] = byte((s4 >> 20) | (s5 << 1))
  2807. s[14] = byte(s5 >> 7)
  2808. s[15] = byte((s5 >> 15) | (s6 << 6))
  2809. s[16] = byte(s6 >> 2)
  2810. s[17] = byte(s6 >> 10)
  2811. s[18] = byte((s6 >> 18) | (s7 << 3))
  2812. s[19] = byte(s7 >> 5)
  2813. s[20] = byte(s7 >> 13)
  2814. s[21] = byte(s8 >> 0)
  2815. s[22] = byte(s8 >> 8)
  2816. s[23] = byte((s8 >> 16) | (s9 << 5))
  2817. s[24] = byte(s9 >> 3)
  2818. s[25] = byte(s9 >> 11)
  2819. s[26] = byte((s9 >> 19) | (s10 << 2))
  2820. s[27] = byte(s10 >> 6)
  2821. s[28] = byte((s10 >> 14) | (s11 << 7))
  2822. s[29] = byte(s11 >> 1)
  2823. s[30] = byte(s11 >> 9)
  2824. s[31] = byte(s11 >> 17)
  2825. }