// GoGOST -- Pure Go GOST cryptographic functions library
-// Copyright (C) 2015-2020 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2015-2022 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
bigInt1 *big.Int = big.NewInt(1)
bigInt2 *big.Int = big.NewInt(2)
bigInt3 *big.Int = big.NewInt(3)
+ bigInt4 *big.Int = big.NewInt(4)
)
type Curve struct {
P *big.Int // Characteristic of the underlying prime field
Q *big.Int // Elliptic curve subgroup order
+ Co *big.Int // Cofactor
+
// Equation coefficients of the elliptic curve in canonical form
A *big.Int
B *big.Int
X *big.Int
Y *big.Int
- // Temporary variable for the add method
- t *big.Int
- tx *big.Int
- ty *big.Int
-
// Cached s/t parameters for Edwards curve points conversion
edS *big.Int
edT *big.Int
}
-func NewCurve(p, q, a, b, x, y, e, d *big.Int) (*Curve, error) {
+func NewCurve(p, q, a, b, x, y, e, d, co *big.Int) (*Curve, error) {
c := Curve{
Name: "unknown",
P: p,
B: b,
X: x,
Y: y,
- t: big.NewInt(0),
- tx: big.NewInt(0),
- ty: big.NewInt(0),
}
r1 := big.NewInt(0)
r2 := big.NewInt(0)
c.E = e
c.D = d
}
+ if co == nil {
+ c.Co = bigInt1
+ } else {
+ c.Co = co
+ }
return &c, nil
}
+func (c *Curve) PointSize() int {
+ return PointSize(c.P)
+}
+
func (c *Curve) pos(v *big.Int) {
if v.Cmp(zero) < 0 {
v.Add(v, c.P)
}
func (c *Curve) add(p1x, p1y, p2x, p2y *big.Int) {
+ var t, tx, ty big.Int
if p1x.Cmp(p2x) == 0 && p1y.Cmp(p2y) == 0 {
// double
- c.t.Mul(p1x, p1x)
- c.t.Mul(c.t, bigInt3)
- c.t.Add(c.t, c.A)
- c.tx.Mul(bigInt2, p1y)
- c.tx.ModInverse(c.tx, c.P)
- c.t.Mul(c.t, c.tx)
- c.t.Mod(c.t, c.P)
+ t.Mul(p1x, p1x)
+ t.Mul(&t, bigInt3)
+ t.Add(&t, c.A)
+ tx.Mul(bigInt2, p1y)
+ tx.ModInverse(&tx, c.P)
+ t.Mul(&t, &tx)
+ t.Mod(&t, c.P)
} else {
- c.tx.Sub(p2x, p1x)
- c.tx.Mod(c.tx, c.P)
- c.pos(c.tx)
- c.ty.Sub(p2y, p1y)
- c.ty.Mod(c.ty, c.P)
- c.pos(c.ty)
- c.t.ModInverse(c.tx, c.P)
- c.t.Mul(c.t, c.ty)
- c.t.Mod(c.t, c.P)
+ tx.Sub(p2x, p1x)
+ tx.Mod(&tx, c.P)
+ c.pos(&tx)
+ ty.Sub(p2y, p1y)
+ ty.Mod(&ty, c.P)
+ c.pos(&ty)
+ t.ModInverse(&tx, c.P)
+ t.Mul(&t, &ty)
+ t.Mod(&t, c.P)
}
- c.tx.Mul(c.t, c.t)
- c.tx.Sub(c.tx, p1x)
- c.tx.Sub(c.tx, p2x)
- c.tx.Mod(c.tx, c.P)
- c.pos(c.tx)
- c.ty.Sub(p1x, c.tx)
- c.ty.Mul(c.ty, c.t)
- c.ty.Sub(c.ty, p1y)
- c.ty.Mod(c.ty, c.P)
- c.pos(c.ty)
- p1x.Set(c.tx)
- p1y.Set(c.ty)
+ tx.Mul(&t, &t)
+ tx.Sub(&tx, p1x)
+ tx.Sub(&tx, p2x)
+ tx.Mod(&tx, c.P)
+ c.pos(&tx)
+ ty.Sub(p1x, &tx)
+ ty.Mul(&ty, &t)
+ ty.Sub(&ty, p1y)
+ ty.Mod(&ty, c.P)
+ c.pos(&ty)
+ p1x.Set(&tx)
+ p1y.Set(&ty)
}
func (c *Curve) Exp(degree, xS, yS *big.Int) (*big.Int, *big.Int, error) {
}
return tx, ty, nil
}
+
+func (our *Curve) Equal(their *Curve) bool {
+ return our.P.Cmp(their.P) == 0 &&
+ our.Q.Cmp(their.Q) == 0 &&
+ our.A.Cmp(their.A) == 0 &&
+ our.B.Cmp(their.B) == 0 &&
+ our.X.Cmp(their.X) == 0 &&
+ our.Y.Cmp(their.Y) == 0 &&
+ ((our.E == nil && their.E == nil) || our.E.Cmp(their.E) == 0) &&
+ ((our.D == nil && their.D == nil) || our.D.Cmp(their.D) == 0) &&
+ our.Co.Cmp(their.Co) == 0
+}