curve.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. package tools
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "math/big"
  7. )
  8. var (
  9. MinP = big.NewInt(11)
  10. )
  11. // 4a³ + 27b² = 0 - проверка кривой на сингулярность
  12. func NewCurve(a, b *big.Int) (*Curve, error) {
  13. c := &Curve{
  14. a: new(big.Int).Set(a),
  15. b: new(big.Int).Set(b),
  16. }
  17. return c, c.IsSingular()
  18. }
  19. /*
  20. func NewRandom(a, b *big.Int) (*Curve, error) {
  21. c := Curve{
  22. a: new(big.Int).Set(a),
  23. b: new(big.Int).Set(b),
  24. }
  25. if err := c.IsSingular(); err != nil {
  26. return nil, err
  27. }
  28. }
  29. */
  30. type Curve struct {
  31. a *big.Int // константа a
  32. b *big.Int // константа b
  33. p *big.Int // размер конечного поля
  34. g *Point // базовая точка подгруппы
  35. //n *big.Int // порядок подгруппы
  36. //h *big.Int // кофактор подгруппы
  37. }
  38. func (s *Curve) A() (res *big.Int) {
  39. return intCopy(s.a)
  40. }
  41. func (s *Curve) B() (res *big.Int) {
  42. return intCopy(s.b)
  43. }
  44. func (s *Curve) G() (res *Point) {
  45. if s.g != nil {
  46. res = s.g.Copy()
  47. }
  48. return
  49. }
  50. func (s *Curve) P() (res *big.Int) {
  51. if s.p != nil {
  52. res = intCopy(s.p)
  53. }
  54. return
  55. }
  56. // Проверка, установлен ли размер конечного поля
  57. func (s *Curve) IsValidP() (err error) {
  58. if err = s.IsValidConstants(); err == nil {
  59. if s.p == nil {
  60. err = errors.New("размер конечного поля не установлен")
  61. }
  62. }
  63. return
  64. }
  65. func (s *Curve) IsValidG() (err error) {
  66. if err = s.IsValidP(); err == nil {
  67. if s.g == nil {
  68. err = errors.New("базовая точка подгруппы g не определена")
  69. }
  70. }
  71. return
  72. }
  73. // Возвращает строку уравнения кривой
  74. func (s *Curve) FormulaString() string {
  75. return fmt.Sprintf(
  76. "y² = x³ + %sx + %s",
  77. mustBigInt(s.a),
  78. mustBigInt(s.b),
  79. )
  80. }
  81. // Проверка кривой на сингулярность (4a³ + 27b² = 0)
  82. func (s *Curve) IsSingular() (err error) {
  83. if err = s.IsValidConstants(); err != nil {
  84. return
  85. }
  86. l := new(big.Int).Mul(new(big.Int).Exp(s.a, big.NewInt(3), nil), big.NewInt(4))
  87. r := new(big.Int).Mul(new(big.Int).Exp(s.b, big.NewInt(2), nil), big.NewInt(27))
  88. if l.Add(l, r).Cmp(big.NewInt(0)) == 0 {
  89. err = fmt.Errorf("кривая [ %s ] сингулярна и не рекомендуется к использованию", s.FormulaString())
  90. }
  91. return
  92. }
  93. // Проверка констант уравнения на валидность
  94. func (s *Curve) IsValidConstants() error {
  95. if s.a == nil {
  96. return errors.New("константа [ a ] не определена")
  97. }
  98. if s.b == nil {
  99. return errors.New("константа [ b ] не определена")
  100. }
  101. return nil
  102. }
  103. // Установка размера конечного поля
  104. func (s *Curve) SetP(p *big.Int) (err error) {
  105. if s.p != nil {
  106. return errors.New("резмер конечного поля уже определен")
  107. }
  108. if err = s.IsValidConstants(); err != nil {
  109. return
  110. }
  111. if !IsPrime(p) {
  112. err = fmt.Errorf("число [ %s ] не является простым. Размер конечного поля должен быть простым числом", p)
  113. return
  114. }
  115. s.p = p
  116. return
  117. }
  118. func (s *Curve) Point(x, y *big.Int) *Point {
  119. return NewPoint(x, y, s)
  120. }
  121. func (s *Curve) InverseMod(k, p *big.Int) (res *big.Int, err error) {
  122. if err = s.IsValidP(); err != nil {
  123. return
  124. }
  125. if k == nil {
  126. err = errors.New("[ k ] не определено")
  127. return
  128. } else if rk := k.Cmp(intZero); rk == 0 {
  129. err = errors.New("[ k ] == 0. Деление на 0 невозможно")
  130. return
  131. } else if rk < 0 {
  132. // k ** -1 = p - (-k) ** -1 (mod p)
  133. // point - self.inverseMod(-k, point)
  134. var iMod *big.Int
  135. if iMod, err = s.InverseMod(Neg(k), p); err == nil {
  136. res = Sub(p, iMod)
  137. }
  138. } else {
  139. s, olds := big.NewInt(0), big.NewInt(1)
  140. t, oldt := big.NewInt(1), big.NewInt(0)
  141. r, oldr := intCopy(p), intCopy(k)
  142. for r.Cmp(intZero) != 0 {
  143. quot := Div(oldr, r)
  144. oldr, r = r, Sub(oldr, Mul(quot, r))
  145. olds, s = s, Sub(olds, Mul(quot, s))
  146. oldt, t = t, Sub(oldt, Mul(quot, t))
  147. }
  148. // gcd, x, y = old_r, old_s, old_t
  149. res = Mod(olds, p)
  150. }
  151. return
  152. }
  153. func (s *Curve) Points(dx *big.Int) (p1, p2 *Point, err error) {
  154. if err = s.IsValidG(); err != nil {
  155. return
  156. }
  157. return s.points(dx)
  158. }
  159. // Определение координат пары зеркальных точек по x
  160. func (s *Curve) points(dx *big.Int) (p1, p2 *Point, err error) {
  161. dxx := intCopy(dx)
  162. // Инициализируем результирующие точки пустыми
  163. p1, p2 = s.Point(nil, nil), s.Point(nil, nil)
  164. var dy *big.Int
  165. // Операции, обратной делению по модулю, не существует, поэтому
  166. // для определения координаты по y, необходимо, путем перебора с подстановкой y,
  167. // проверить равенство левой части уравнения, разделенного по модулю на p с
  168. // правой частью, так же разделенной по модулю на p
  169. for i := big.NewInt(0); i.Cmp(s.p) < 0; i.Add(i, big.NewInt(1)) {
  170. // i ** 2 % s.p == (dx ** 3 + s.a * dx + self.b) % self.p > 0
  171. l := Mod(Exp64(i, 2), s.p)
  172. r := Mod(
  173. Add(
  174. Exp64(dx, 3),
  175. Add(
  176. Mul(s.a, dx),
  177. s.b,
  178. ),
  179. ),
  180. s.p,
  181. )
  182. if l.Cmp(r) == 0 {
  183. dy = i
  184. break
  185. }
  186. }
  187. if dy == nil {
  188. err = fmt.Errorf("не удалось найти пару зеркальных точек на кривой после x [ %s ]", dxx)
  189. } else {
  190. p1.x, p1.y = dx, dy
  191. p2.x = intCopy(p1.x)
  192. p2.y = Mod(Neg(p1.y), s.p)
  193. }
  194. return
  195. }
  196. func (s *Curve) SearchClosePoints(x *big.Int, ctx context.Context) (p1, p2 *Point, err error) {
  197. if err = s.IsValidG(); err != nil {
  198. return
  199. }
  200. return s.searhClosePoints(x, ctx)
  201. }
  202. func (s *Curve) searhClosePoints(x *big.Int, ctx context.Context) (p1, p2 *Point, err error) {
  203. cx := intCopy(x)
  204. if x.Cmp(s.p) >= 0 {
  205. x = Sub(s.p, big.NewInt(1))
  206. } else if x.Cmp(intZero) < 0 {
  207. x = big.NewInt(0)
  208. }
  209. //kx := Sub64(x, 1)
  210. kx := intCopy(x)
  211. ch := make(chan struct{})
  212. go func() {
  213. defer close(ch)
  214. for {
  215. select {
  216. case <-ctx.Done():
  217. return
  218. default:
  219. //log.Println("xkx", x, kx)
  220. if x.Cmp(s.p) >= 0 && kx.Cmp(intZero) <= 0 {
  221. err = fmt.Errorf("не удалось найти точки, близкие к [ %s ]", cx)
  222. return
  223. } else {
  224. // Поиск вправо
  225. if x.Cmp(s.p) <= 0 {
  226. if p1, p2, err = s.points(x); err == nil {
  227. if p1.IsInCurve() == nil {
  228. return
  229. }
  230. }
  231. x = Add64(x, 1)
  232. }
  233. // Поиск влево
  234. if kx.Cmp(intZero) < 0 {
  235. if p1, p2, err = s.points(kx); err == nil {
  236. if p1.IsInCurve() == nil {
  237. return
  238. }
  239. }
  240. kx = Sub64(kx, 1)
  241. }
  242. }
  243. }
  244. }
  245. }()
  246. select {
  247. case <-ch:
  248. case <-ctx.Done():
  249. err = fmt.Errorf("Поиск точки, близкой к [ %v ] прерван - время вышло", x)
  250. }
  251. return
  252. }
  253. func (s *Curve) SetG(g *Point) (err error) {
  254. if s.g != nil {
  255. err = errors.New("базовая точка подгруппы g уже определена")
  256. return
  257. }
  258. if err = s.IsValidP(); err != nil {
  259. return
  260. }
  261. if err = g.IsInCurve(); err == nil && g.curve == s {
  262. s.g = g
  263. }
  264. return
  265. }
  266. func (s *Curve) SetGRandom(ctx context.Context) (err error) {
  267. if s.g != nil {
  268. err = errors.New("базовая точка подгруппы g уже определена")
  269. return
  270. }
  271. if err = s.IsValidP(); err != nil {
  272. return
  273. }
  274. x := Random(
  275. Div(s.p, big.NewInt(2)),
  276. Sub(s.p, big.NewInt(10)),
  277. )
  278. //log.Println(x)
  279. p1, p2, err := s.searhClosePoints(x, ctx)
  280. if err != nil {
  281. return
  282. }
  283. if err = p1.IsInCurve(); err == nil {
  284. s.g = p1
  285. } else if err = p2.IsInCurve(); err == nil {
  286. s.g = p2
  287. } else {
  288. err = errors.New("не удалось найти точку g, пренадлежащую кривой")
  289. }
  290. return
  291. }
  292. /*
  293. // Поиск порядка подгруппы
  294. func (s *Curve) SetN() (err error) {
  295. if s.n != nil {
  296. return errors.New("порядок подгруппы уже определен")
  297. }
  298. if err = s.IsValidP(); err != nil {
  299. return
  300. }
  301. dx, dy := intCopy(s.g.x), Mod(Neg(s.g.y), s.p)
  302. tmpG := s.g.Copy()
  303. s.n = big.NewInt(1)
  304. for {
  305. s.n.Add(s.n, big.NewInt(1))
  306. if tmpG, err = tmpG.Add(s.g); err != nil {
  307. return
  308. }
  309. if tmpG.x.Cmp(dx) == 0 && tmpG.y.Cmp(dy) == 0 {
  310. s.n.Add(s.n, big.NewInt(1))
  311. return
  312. }
  313. }
  314. }
  315. func (s *Curve) KeyPub(priv *big.Int) (pub *Point, err error) {
  316. if err = s.IsValidN(); err != nil {
  317. return
  318. }
  319. pub, err = s.g.Mul(priv)
  320. return
  321. }
  322. func (s *Curve) RandomKeyPair() (priv *big.Int, pub *Point, err error) {
  323. if err = s.IsValidN(); err != nil {
  324. return
  325. }
  326. priv = Random(big.NewInt(1), Sub64(s.n, 1))
  327. pub, err = s.g.Mul(priv)
  328. return
  329. }
  330. // Вычисление общего секрета
  331. func (s *Curve) PointSecret(mPriv *big.Int, fPub *Point) (res *Point, err error) {
  332. if err = s.IsValidN(); err != nil {
  333. return
  334. }
  335. res, err = fPub.Mul(mPriv)
  336. return
  337. }
  338. type ELKeyPriv struct {
  339. d *big.Int
  340. }
  341. type ELKeyPub struct {
  342. e1 *Point
  343. e2 *Point
  344. }
  345. type ELKeyPair struct {
  346. curve *Curve
  347. priv *ELKeyPriv
  348. pub *ELKeyPub
  349. dTable map[byte]*Point
  350. }
  351. func (s *ELKeyPair) setupDataTable() error {
  352. if s.dTable != nil {
  353. return nil
  354. }
  355. s.dTable = make(map[byte]*Point)
  356. dx := big.NewInt(0)
  357. //var points []*Point
  358. //var p *Point
  359. for i := byte(0); i <= 254; i++ {
  360. p, _, err := s.curve.searhClosePoints(dx)
  361. if err != nil {
  362. return err
  363. }
  364. // check already exists - todo
  365. dx = Add64(p.x, 1)
  366. s.dTable[i] = p
  367. log.Println(i, p)
  368. }
  369. return nil
  370. }
  371. type ELMessage struct {
  372. c1 *Point
  373. cd []*Point
  374. }
  375. // c1 = r x e1
  376. // c2 = P + r x e2
  377. func (s *ELKeyPair) EncodeMessage(data []byte) (mes *ELMessage, err error) {
  378. r := Random(big.NewInt(1), Sub64(s.curve.p, 1))
  379. c1, err := s.pub.e1.Mul(r)
  380. if err != nil {
  381. return nil, err
  382. }
  383. mes = &ELMessage{
  384. c1: c1,
  385. cd: make([]*Point, len(data)),
  386. }
  387. for i, d := range data {
  388. p := s.dTable[d]
  389. c2, err := s.pub.e2.Mul(r)
  390. if err != nil {
  391. return nil, err
  392. }
  393. cd, err := p.Add(c2)
  394. if err != nil {
  395. return nil, err
  396. }
  397. mes.cd[i] = cd
  398. }
  399. return mes, nil
  400. }
  401. // p = c2 – (d x c1)
  402. func (s *ELKeyPair) DecodeMessage(mes *ELMessage) ([]byte, error) {
  403. res := make([]byte, len(mes.cd))
  404. part, err := mes.c1.Mul(s.priv.d)
  405. if err != nil {
  406. return nil, err
  407. }
  408. part, _ = part.Neg()
  409. for _, c2 := range mes.cd {
  410. p, err := c2.Add(part)
  411. if err != nil {
  412. return nil, err
  413. }
  414. log.Println(p)
  415. }
  416. return res, nil
  417. }
  418. func (s *Curve) ELKeyPair() (*ELKeyPair, error) {
  419. e1, _, err := s.searhClosePoints(Random(big.NewInt(1), Sub64(s.p, 1)))
  420. if err != nil {
  421. return nil, err
  422. }
  423. d := Random(big.NewInt(1), Sub64(s.n, 1))
  424. e2, err := e1.Mul(d)
  425. if err != nil {
  426. return nil, err
  427. }
  428. res := &ELKeyPair{
  429. curve: s,
  430. priv: &ELKeyPriv{
  431. d: d,
  432. },
  433. pub: &ELKeyPub{
  434. e1: e1,
  435. e2: e2,
  436. },
  437. }
  438. return res, res.setupDataTable()
  439. }
  440. */
  441. /*
  442. func (s *Curve) HEncode(b byte, pub *Point) (cm1, cm2 *Point, err error) {
  443. var p1 *Point
  444. if p1, _, err = s.points(big.NewInt(int64(b))); err != nil {
  445. return
  446. }
  447. c1 = pub.Add()
  448. }
  449. */
  450. /*
  451. // 𝐶𝑚 = (𝑘 × 𝐺, 𝑃𝑚 + 𝑘 × 𝑃𝐵)
  452. func (s *Curve) HellmanEncode(b byte, pub *Point) (cm1, cm2 *Point, err error) {
  453. k := Random(big.NewInt(1), Sub64(s.n, 1))
  454. if cm1, err = s.g.Mul(k); err != nil {
  455. return
  456. }
  457. cm2, err = pub.Mul(Add64(k, int64(b)))
  458. return
  459. }
  460. */
  461. /*
  462. func (s *Curve) HellmanDecode(cm1, cm2 *Point, priv *big.Int) {
  463. }
  464. */