]> Cypherpunks.ru repositories - gogost.git/blob - src/cypherpunks.ru/gogost/gost3410/edwards.go
Coordinates conversion from/to twisted Edwards to Weierstass form
[gogost.git] / src / cypherpunks.ru / gogost / gost3410 / edwards.go
1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2019 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 package gost3410
18
19 import (
20         "math/big"
21 )
22
23 func (c *Curve) IsEdwards() bool {
24         return c.E != nil
25 }
26
27 func (c *Curve) EdwardsST() (*big.Int, *big.Int) {
28         if c.edS != nil {
29                 return c.edS, c.edT
30         }
31         c.edS = big.NewInt(0)
32         c.edS.Set(c.E)
33         c.edS.Sub(c.edS, c.D)
34         c.pos(c.edS)
35         c.t.SetUint64(4)
36         c.t.ModInverse(c.t, c.P)
37         c.edS.Mul(c.edS, c.t)
38         c.edS.Mod(c.edS, c.P)
39         c.edT = big.NewInt(0)
40         c.edT.Set(c.E)
41         c.edT.Add(c.edT, c.D)
42         c.t.SetUint64(6)
43         c.t.ModInverse(c.t, c.P)
44         c.edT.Mul(c.edT, c.t)
45         c.edT.Mod(c.edT, c.P)
46         return c.edS, c.edT
47 }
48
49 // Convert Weierstrass X,Y coordinates to twisted Edwards U,V
50 func XY2UV(curve *Curve, x, y *big.Int) (*big.Int, *big.Int) {
51         if !curve.IsEdwards() {
52                 panic("non twisted Edwards curve")
53         }
54         edS, edT := curve.EdwardsST()
55         curve.t.Sub(x, edT)
56         curve.pos(curve.t)
57         u := big.NewInt(0)
58         u.ModInverse(y, curve.P)
59         u.Mul(u, curve.t)
60         u.Mod(u, curve.P)
61         v := big.NewInt(0).Set(curve.t)
62         v.Sub(v, edS)
63         curve.pos(v)
64         curve.t.Add(curve.t, edS)
65         curve.t.ModInverse(curve.t, curve.P)
66         v.Mul(v, curve.t)
67         v.Mod(v, curve.P)
68         return u, v
69 }
70
71 // Convert twisted Edwards U,V coordinates to Weierstrass X,Y
72 func UV2XY(curve *Curve, u, v *big.Int) (*big.Int, *big.Int) {
73         if !curve.IsEdwards() {
74                 panic("non twisted Edwards curve")
75         }
76         edS, edT := curve.EdwardsST()
77         curve.tx.Add(bigInt1, v)
78         curve.tx.Mul(curve.tx, edS)
79         curve.tx.Mod(curve.tx, curve.P)
80         curve.ty.Sub(bigInt1, v)
81         curve.pos(curve.ty)
82         x := big.NewInt(0)
83         x.ModInverse(curve.ty, curve.P)
84         x.Mul(x, curve.tx)
85         x.Add(x, edT)
86         x.Mod(x, curve.P)
87         y := big.NewInt(0)
88         y.Mul(u, curve.ty)
89         y.ModInverse(y, curve.P)
90         y.Mul(y, curve.tx)
91         y.Mod(y, curve.P)
92         return x, y
93 }