|
@@ -1,9 +1,9 @@
|
|
|
package tools
|
|
|
|
|
|
import (
|
|
|
+ "context"
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
- "log"
|
|
|
"math/big"
|
|
|
)
|
|
|
|
|
@@ -12,8 +12,7 @@ var (
|
|
|
)
|
|
|
|
|
|
// 4a³ + 27b² = 0 - проверка кривой на сингулярность
|
|
|
-
|
|
|
-func New(a, b *big.Int) (*Curve, error) {
|
|
|
+func NewCurve(a, b *big.Int) (*Curve, error) {
|
|
|
c := &Curve{
|
|
|
a: new(big.Int).Set(a),
|
|
|
b: new(big.Int).Set(b),
|
|
@@ -21,13 +20,26 @@ func New(a, b *big.Int) (*Curve, error) {
|
|
|
return c, c.IsSingular()
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+func NewRandom(a, b *big.Int) (*Curve, error) {
|
|
|
+ c := Curve{
|
|
|
+ a: new(big.Int).Set(a),
|
|
|
+ b: new(big.Int).Set(b),
|
|
|
+ }
|
|
|
+ if err := c.IsSingular(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+*/
|
|
|
+
|
|
|
type Curve struct {
|
|
|
a *big.Int // константа a
|
|
|
b *big.Int // константа b
|
|
|
p *big.Int // размер конечного поля
|
|
|
g *Point // базовая точка подгруппы
|
|
|
- n *big.Int // порядок подгруппы
|
|
|
- h *big.Int // кофактор подгруппы
|
|
|
+ //n *big.Int // порядок подгруппы
|
|
|
+ //h *big.Int // кофактор подгруппы
|
|
|
}
|
|
|
|
|
|
func (s *Curve) A() (res *big.Int) {
|
|
@@ -38,6 +50,20 @@ func (s *Curve) B() (res *big.Int) {
|
|
|
return intCopy(s.b)
|
|
|
}
|
|
|
|
|
|
+func (s *Curve) G() (res *Point) {
|
|
|
+ if s.g != nil {
|
|
|
+ res = s.g.Copy()
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Curve) P() (res *big.Int) {
|
|
|
+ if s.p != nil {
|
|
|
+ res = intCopy(s.p)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
// Проверка, установлен ли размер конечного поля
|
|
|
func (s *Curve) IsValidP() (err error) {
|
|
|
if err = s.IsValidConstants(); err == nil {
|
|
@@ -57,15 +83,6 @@ func (s *Curve) IsValidG() (err error) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-func (s *Curve) IsValidN() (err error) {
|
|
|
- if err = s.IsValidG(); err == nil {
|
|
|
- if s.n == nil {
|
|
|
- err = errors.New("порядок подгруппы не определен")
|
|
|
- }
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
// Возвращает строку уравнения кривой
|
|
|
func (s *Curve) FormulaString() string {
|
|
|
return fmt.Sprintf(
|
|
@@ -112,9 +129,6 @@ func (s *Curve) SetP(p *big.Int) (err error) {
|
|
|
return
|
|
|
}
|
|
|
s.p = p
|
|
|
- // сброс подгруппы
|
|
|
- s.n = nil
|
|
|
- s.h = nil
|
|
|
return
|
|
|
}
|
|
|
|
|
@@ -157,10 +171,10 @@ func (s *Curve) InverseMod(k, p *big.Int) (res *big.Int, err error) {
|
|
|
}
|
|
|
|
|
|
func (s *Curve) Points(dx *big.Int) (p1, p2 *Point, err error) {
|
|
|
- if err = s.IsValidN(); err != nil {
|
|
|
+ if err = s.IsValidG(); err != nil {
|
|
|
return
|
|
|
}
|
|
|
- return s.points(x)
|
|
|
+ return s.points(dx)
|
|
|
}
|
|
|
|
|
|
// Определение координат пары зеркальных точек по x
|
|
@@ -201,14 +215,14 @@ func (s *Curve) points(dx *big.Int) (p1, p2 *Point, err error) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-func (s *Curve) SearchClosePoints(x *big.Int) (p1, p2 *Point, err error) {
|
|
|
- if err = s.IsValidN(); err != nil {
|
|
|
+func (s *Curve) SearchClosePoints(x *big.Int, ctx context.Context) (p1, p2 *Point, err error) {
|
|
|
+ if err = s.IsValidG(); err != nil {
|
|
|
return
|
|
|
}
|
|
|
- return s.searhClosePoints(x)
|
|
|
+ return s.searhClosePoints(x, ctx)
|
|
|
}
|
|
|
|
|
|
-func (s *Curve) searhClosePoints(x *big.Int) (p1, p2 *Point, err error) {
|
|
|
+func (s *Curve) searhClosePoints(x *big.Int, ctx context.Context) (p1, p2 *Point, err error) {
|
|
|
cx := intCopy(x)
|
|
|
if x.Cmp(s.p) >= 0 {
|
|
|
x = Sub(s.p, big.NewInt(1))
|
|
@@ -217,31 +231,45 @@ func (s *Curve) searhClosePoints(x *big.Int) (p1, p2 *Point, err error) {
|
|
|
}
|
|
|
//kx := Sub64(x, 1)
|
|
|
kx := intCopy(x)
|
|
|
- for {
|
|
|
- //log.Println("xkx", x, kx)
|
|
|
- if x.Cmp(s.p) >= 0 && kx.Cmp(intZero) <= 0 {
|
|
|
- err = fmt.Errorf("не удалось найти точки, близкие к [ %s ]", cx)
|
|
|
- break
|
|
|
- } else {
|
|
|
- // Поиск вправо
|
|
|
- if x.Cmp(s.p) <= 0 {
|
|
|
- if p1, p2, err = s.points(x); err == nil {
|
|
|
- if p1.IsInCurve() == nil {
|
|
|
- return
|
|
|
+ ch := make(chan struct{})
|
|
|
+ go func() {
|
|
|
+ defer close(ch)
|
|
|
+ for {
|
|
|
+ select {
|
|
|
+ case <-ctx.Done():
|
|
|
+ return
|
|
|
+ default:
|
|
|
+ //log.Println("xkx", x, kx)
|
|
|
+ if x.Cmp(s.p) >= 0 && kx.Cmp(intZero) <= 0 {
|
|
|
+ err = fmt.Errorf("не удалось найти точки, близкие к [ %s ]", cx)
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ // Поиск вправо
|
|
|
+ if x.Cmp(s.p) <= 0 {
|
|
|
+ if p1, p2, err = s.points(x); err == nil {
|
|
|
+ if p1.IsInCurve() == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ x = Add64(x, 1)
|
|
|
}
|
|
|
- }
|
|
|
- x = Add64(x, 1)
|
|
|
- }
|
|
|
- // Поиск влево
|
|
|
- if kx.Cmp(intZero) < 0 {
|
|
|
- if p1, p2, err = s.points(kx); err == nil {
|
|
|
- if p1.IsInCurve() == nil {
|
|
|
- return
|
|
|
+ // Поиск влево
|
|
|
+ if kx.Cmp(intZero) < 0 {
|
|
|
+ if p1, p2, err = s.points(kx); err == nil {
|
|
|
+ if p1.IsInCurve() == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ kx = Sub64(kx, 1)
|
|
|
}
|
|
|
}
|
|
|
- kx = Sub64(kx, 1)
|
|
|
}
|
|
|
}
|
|
|
+ }()
|
|
|
+ select {
|
|
|
+ case <-ch:
|
|
|
+ case <-ctx.Done():
|
|
|
+ err = fmt.Errorf("Поиск точки, близкой к [ %v ] прерван - время вышло", x)
|
|
|
}
|
|
|
return
|
|
|
}
|
|
@@ -260,7 +288,7 @@ func (s *Curve) SetG(g *Point) (err error) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-func (s *Curve) SetGRandom() (err error) {
|
|
|
+func (s *Curve) SetGRandom(ctx context.Context) (err error) {
|
|
|
if s.g != nil {
|
|
|
err = errors.New("базовая точка подгруппы g уже определена")
|
|
|
return
|
|
@@ -273,7 +301,7 @@ func (s *Curve) SetGRandom() (err error) {
|
|
|
Sub(s.p, big.NewInt(10)),
|
|
|
)
|
|
|
//log.Println(x)
|
|
|
- p1, p2, err := s.searhClosePoints(x)
|
|
|
+ p1, p2, err := s.searhClosePoints(x, ctx)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
@@ -287,6 +315,7 @@ func (s *Curve) SetGRandom() (err error) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
// Поиск порядка подгруппы
|
|
|
func (s *Curve) SetN() (err error) {
|
|
|
if s.n != nil {
|
|
@@ -445,6 +474,7 @@ func (s *Curve) ELKeyPair() (*ELKeyPair, error) {
|
|
|
}
|
|
|
return res, res.setupDataTable()
|
|
|
}
|
|
|
+*/
|
|
|
|
|
|
/*
|
|
|
func (s *Curve) HEncode(b byte, pub *Point) (cm1, cm2 *Point, err error) {
|