|  | @@ -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) {
 |