fp6.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. // Copyright 2020 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package bls12381
  17. import (
  18. "errors"
  19. "math/big"
  20. )
  21. type fp6Temp struct {
  22. t [6]*fe2
  23. }
  24. type fp6 struct {
  25. fp2 *fp2
  26. fp6Temp
  27. }
  28. func newFp6Temp() fp6Temp {
  29. t := [6]*fe2{}
  30. for i := 0; i < len(t); i++ {
  31. t[i] = &fe2{}
  32. }
  33. return fp6Temp{t}
  34. }
  35. func newFp6(f *fp2) *fp6 {
  36. t := newFp6Temp()
  37. if f == nil {
  38. return &fp6{newFp2(), t}
  39. }
  40. return &fp6{f, t}
  41. }
  42. func (e *fp6) fromBytes(b []byte) (*fe6, error) {
  43. if len(b) < 288 {
  44. return nil, errors.New("input string should be larger than 288 bytes")
  45. }
  46. fp2 := e.fp2
  47. u2, err := fp2.fromBytes(b[:96])
  48. if err != nil {
  49. return nil, err
  50. }
  51. u1, err := fp2.fromBytes(b[96:192])
  52. if err != nil {
  53. return nil, err
  54. }
  55. u0, err := fp2.fromBytes(b[192:])
  56. if err != nil {
  57. return nil, err
  58. }
  59. return &fe6{*u0, *u1, *u2}, nil
  60. }
  61. func (e *fp6) toBytes(a *fe6) []byte {
  62. fp2 := e.fp2
  63. out := make([]byte, 288)
  64. copy(out[:96], fp2.toBytes(&a[2]))
  65. copy(out[96:192], fp2.toBytes(&a[1]))
  66. copy(out[192:], fp2.toBytes(&a[0]))
  67. return out
  68. }
  69. func (e *fp6) new() *fe6 {
  70. return new(fe6)
  71. }
  72. func (e *fp6) zero() *fe6 {
  73. return new(fe6)
  74. }
  75. func (e *fp6) one() *fe6 {
  76. return new(fe6).one()
  77. }
  78. func (e *fp6) add(c, a, b *fe6) {
  79. fp2 := e.fp2
  80. fp2.add(&c[0], &a[0], &b[0])
  81. fp2.add(&c[1], &a[1], &b[1])
  82. fp2.add(&c[2], &a[2], &b[2])
  83. }
  84. func (e *fp6) addAssign(a, b *fe6) {
  85. fp2 := e.fp2
  86. fp2.addAssign(&a[0], &b[0])
  87. fp2.addAssign(&a[1], &b[1])
  88. fp2.addAssign(&a[2], &b[2])
  89. }
  90. func (e *fp6) double(c, a *fe6) {
  91. fp2 := e.fp2
  92. fp2.double(&c[0], &a[0])
  93. fp2.double(&c[1], &a[1])
  94. fp2.double(&c[2], &a[2])
  95. }
  96. func (e *fp6) doubleAssign(a *fe6) {
  97. fp2 := e.fp2
  98. fp2.doubleAssign(&a[0])
  99. fp2.doubleAssign(&a[1])
  100. fp2.doubleAssign(&a[2])
  101. }
  102. func (e *fp6) sub(c, a, b *fe6) {
  103. fp2 := e.fp2
  104. fp2.sub(&c[0], &a[0], &b[0])
  105. fp2.sub(&c[1], &a[1], &b[1])
  106. fp2.sub(&c[2], &a[2], &b[2])
  107. }
  108. func (e *fp6) subAssign(a, b *fe6) {
  109. fp2 := e.fp2
  110. fp2.subAssign(&a[0], &b[0])
  111. fp2.subAssign(&a[1], &b[1])
  112. fp2.subAssign(&a[2], &b[2])
  113. }
  114. func (e *fp6) neg(c, a *fe6) {
  115. fp2 := e.fp2
  116. fp2.neg(&c[0], &a[0])
  117. fp2.neg(&c[1], &a[1])
  118. fp2.neg(&c[2], &a[2])
  119. }
  120. func (e *fp6) mul(c, a, b *fe6) {
  121. fp2, t := e.fp2, e.t
  122. fp2.mul(t[0], &a[0], &b[0])
  123. fp2.mul(t[1], &a[1], &b[1])
  124. fp2.mul(t[2], &a[2], &b[2])
  125. fp2.add(t[3], &a[1], &a[2])
  126. fp2.add(t[4], &b[1], &b[2])
  127. fp2.mulAssign(t[3], t[4])
  128. fp2.add(t[4], t[1], t[2])
  129. fp2.subAssign(t[3], t[4])
  130. fp2.mulByNonResidue(t[3], t[3])
  131. fp2.add(t[5], t[0], t[3])
  132. fp2.add(t[3], &a[0], &a[1])
  133. fp2.add(t[4], &b[0], &b[1])
  134. fp2.mulAssign(t[3], t[4])
  135. fp2.add(t[4], t[0], t[1])
  136. fp2.subAssign(t[3], t[4])
  137. fp2.mulByNonResidue(t[4], t[2])
  138. fp2.add(&c[1], t[3], t[4])
  139. fp2.add(t[3], &a[0], &a[2])
  140. fp2.add(t[4], &b[0], &b[2])
  141. fp2.mulAssign(t[3], t[4])
  142. fp2.add(t[4], t[0], t[2])
  143. fp2.subAssign(t[3], t[4])
  144. fp2.add(&c[2], t[1], t[3])
  145. c[0].set(t[5])
  146. }
  147. func (e *fp6) mulAssign(a, b *fe6) {
  148. fp2, t := e.fp2, e.t
  149. fp2.mul(t[0], &a[0], &b[0])
  150. fp2.mul(t[1], &a[1], &b[1])
  151. fp2.mul(t[2], &a[2], &b[2])
  152. fp2.add(t[3], &a[1], &a[2])
  153. fp2.add(t[4], &b[1], &b[2])
  154. fp2.mulAssign(t[3], t[4])
  155. fp2.add(t[4], t[1], t[2])
  156. fp2.subAssign(t[3], t[4])
  157. fp2.mulByNonResidue(t[3], t[3])
  158. fp2.add(t[5], t[0], t[3])
  159. fp2.add(t[3], &a[0], &a[1])
  160. fp2.add(t[4], &b[0], &b[1])
  161. fp2.mulAssign(t[3], t[4])
  162. fp2.add(t[4], t[0], t[1])
  163. fp2.subAssign(t[3], t[4])
  164. fp2.mulByNonResidue(t[4], t[2])
  165. fp2.add(&a[1], t[3], t[4])
  166. fp2.add(t[3], &a[0], &a[2])
  167. fp2.add(t[4], &b[0], &b[2])
  168. fp2.mulAssign(t[3], t[4])
  169. fp2.add(t[4], t[0], t[2])
  170. fp2.subAssign(t[3], t[4])
  171. fp2.add(&a[2], t[1], t[3])
  172. a[0].set(t[5])
  173. }
  174. func (e *fp6) square(c, a *fe6) {
  175. fp2, t := e.fp2, e.t
  176. fp2.square(t[0], &a[0])
  177. fp2.mul(t[1], &a[0], &a[1])
  178. fp2.doubleAssign(t[1])
  179. fp2.sub(t[2], &a[0], &a[1])
  180. fp2.addAssign(t[2], &a[2])
  181. fp2.squareAssign(t[2])
  182. fp2.mul(t[3], &a[1], &a[2])
  183. fp2.doubleAssign(t[3])
  184. fp2.square(t[4], &a[2])
  185. fp2.mulByNonResidue(t[5], t[3])
  186. fp2.add(&c[0], t[0], t[5])
  187. fp2.mulByNonResidue(t[5], t[4])
  188. fp2.add(&c[1], t[1], t[5])
  189. fp2.addAssign(t[1], t[2])
  190. fp2.addAssign(t[1], t[3])
  191. fp2.addAssign(t[0], t[4])
  192. fp2.sub(&c[2], t[1], t[0])
  193. }
  194. func (e *fp6) mulBy01Assign(a *fe6, b0, b1 *fe2) {
  195. fp2, t := e.fp2, e.t
  196. fp2.mul(t[0], &a[0], b0)
  197. fp2.mul(t[1], &a[1], b1)
  198. fp2.add(t[5], &a[1], &a[2])
  199. fp2.mul(t[2], b1, t[5])
  200. fp2.subAssign(t[2], t[1])
  201. fp2.mulByNonResidue(t[2], t[2])
  202. fp2.add(t[5], &a[0], &a[2])
  203. fp2.mul(t[3], b0, t[5])
  204. fp2.subAssign(t[3], t[0])
  205. fp2.add(&a[2], t[3], t[1])
  206. fp2.add(t[4], b0, b1)
  207. fp2.add(t[5], &a[0], &a[1])
  208. fp2.mulAssign(t[4], t[5])
  209. fp2.subAssign(t[4], t[0])
  210. fp2.sub(&a[1], t[4], t[1])
  211. fp2.add(&a[0], t[2], t[0])
  212. }
  213. func (e *fp6) mulBy01(c, a *fe6, b0, b1 *fe2) {
  214. fp2, t := e.fp2, e.t
  215. fp2.mul(t[0], &a[0], b0)
  216. fp2.mul(t[1], &a[1], b1)
  217. fp2.add(t[2], &a[1], &a[2])
  218. fp2.mulAssign(t[2], b1)
  219. fp2.subAssign(t[2], t[1])
  220. fp2.mulByNonResidue(t[2], t[2])
  221. fp2.add(t[3], &a[0], &a[2])
  222. fp2.mulAssign(t[3], b0)
  223. fp2.subAssign(t[3], t[0])
  224. fp2.add(&c[2], t[3], t[1])
  225. fp2.add(t[4], b0, b1)
  226. fp2.add(t[3], &a[0], &a[1])
  227. fp2.mulAssign(t[4], t[3])
  228. fp2.subAssign(t[4], t[0])
  229. fp2.sub(&c[1], t[4], t[1])
  230. fp2.add(&c[0], t[2], t[0])
  231. }
  232. func (e *fp6) mulBy1(c, a *fe6, b1 *fe2) {
  233. fp2, t := e.fp2, e.t
  234. fp2.mul(t[0], &a[2], b1)
  235. fp2.mul(&c[2], &a[1], b1)
  236. fp2.mul(&c[1], &a[0], b1)
  237. fp2.mulByNonResidue(&c[0], t[0])
  238. }
  239. func (e *fp6) mulByNonResidue(c, a *fe6) {
  240. fp2, t := e.fp2, e.t
  241. t[0].set(&a[0])
  242. fp2.mulByNonResidue(&c[0], &a[2])
  243. c[2].set(&a[1])
  244. c[1].set(t[0])
  245. }
  246. func (e *fp6) mulByBaseField(c, a *fe6, b *fe2) {
  247. fp2 := e.fp2
  248. fp2.mul(&c[0], &a[0], b)
  249. fp2.mul(&c[1], &a[1], b)
  250. fp2.mul(&c[2], &a[2], b)
  251. }
  252. func (e *fp6) exp(c, a *fe6, s *big.Int) {
  253. z := e.one()
  254. for i := s.BitLen() - 1; i >= 0; i-- {
  255. e.square(z, z)
  256. if s.Bit(i) == 1 {
  257. e.mul(z, z, a)
  258. }
  259. }
  260. c.set(z)
  261. }
  262. func (e *fp6) inverse(c, a *fe6) {
  263. fp2, t := e.fp2, e.t
  264. fp2.square(t[0], &a[0])
  265. fp2.mul(t[1], &a[1], &a[2])
  266. fp2.mulByNonResidue(t[1], t[1])
  267. fp2.subAssign(t[0], t[1])
  268. fp2.square(t[1], &a[1])
  269. fp2.mul(t[2], &a[0], &a[2])
  270. fp2.subAssign(t[1], t[2])
  271. fp2.square(t[2], &a[2])
  272. fp2.mulByNonResidue(t[2], t[2])
  273. fp2.mul(t[3], &a[0], &a[1])
  274. fp2.subAssign(t[2], t[3])
  275. fp2.mul(t[3], &a[2], t[2])
  276. fp2.mul(t[4], &a[1], t[1])
  277. fp2.addAssign(t[3], t[4])
  278. fp2.mulByNonResidue(t[3], t[3])
  279. fp2.mul(t[4], &a[0], t[0])
  280. fp2.addAssign(t[3], t[4])
  281. fp2.inverse(t[3], t[3])
  282. fp2.mul(&c[0], t[0], t[3])
  283. fp2.mul(&c[1], t[2], t[3])
  284. fp2.mul(&c[2], t[1], t[3])
  285. }
  286. func (e *fp6) frobeniusMap(c, a *fe6, power uint) {
  287. fp2 := e.fp2
  288. fp2.frobeniusMap(&c[0], &a[0], power)
  289. fp2.frobeniusMap(&c[1], &a[1], power)
  290. fp2.frobeniusMap(&c[2], &a[2], power)
  291. switch power % 6 {
  292. case 0:
  293. return
  294. case 3:
  295. neg(&c[0][0], &a[1][1])
  296. c[1][1].set(&a[1][0])
  297. fp2.neg(&a[2], &a[2])
  298. default:
  299. fp2.mul(&c[1], &c[1], &frobeniusCoeffs61[power%6])
  300. fp2.mul(&c[2], &c[2], &frobeniusCoeffs62[power%6])
  301. }
  302. }
  303. func (e *fp6) frobeniusMapAssign(a *fe6, power uint) {
  304. fp2 := e.fp2
  305. fp2.frobeniusMapAssign(&a[0], power)
  306. fp2.frobeniusMapAssign(&a[1], power)
  307. fp2.frobeniusMapAssign(&a[2], power)
  308. t := e.t
  309. switch power % 6 {
  310. case 0:
  311. return
  312. case 3:
  313. neg(&t[0][0], &a[1][1])
  314. a[1][1].set(&a[1][0])
  315. a[1][0].set(&t[0][0])
  316. fp2.neg(&a[2], &a[2])
  317. default:
  318. fp2.mulAssign(&a[1], &frobeniusCoeffs61[power%6])
  319. fp2.mulAssign(&a[2], &frobeniusCoeffs62[power%6])
  320. }
  321. }