curve.go 11 KB

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