forked from coinbase/kryptology
-
Notifications
You must be signed in to change notification settings - Fork 0
/
isogeny.go
62 lines (52 loc) · 1.74 KB
/
isogeny.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package native
// IsogenyParams are the parameters needed to map from an isogeny to the main curve
type IsogenyParams struct {
XNum [][FieldLimbs]uint64
XDen [][FieldLimbs]uint64
YNum [][FieldLimbs]uint64
YDen [][FieldLimbs]uint64
}
// Map from the isogeny curve to the main curve using the parameters
func (p *IsogenyParams) Map(xIn, yIn *Field) (x, y *Field) {
var xNum, xDen, yNum, yDen, tv [FieldLimbs]uint64
var wasInverted int
xnumL := len(p.XNum)
xdenL := len(p.XDen)
ynumL := len(p.YNum)
ydenL := len(p.YDen)
degree := 0
for _, i := range []int{xnumL, xdenL, ynumL, ydenL} {
if degree < i {
degree = i
}
}
xs := make([][FieldLimbs]uint64, degree)
xs[0] = xIn.Params.R // x[0] = x^0
xs[1] = xIn.Value // x[1] = x^1
xIn.Arithmetic.Square(&xs[2], &xIn.Value) // x[2] = x^2
for i := 3; i < degree; i++ {
// x[i] = x^i
xIn.Arithmetic.Mul(&xs[i], &xs[i-1], &xIn.Value)
}
computeIsoK(&xNum, &xs, &p.XNum, xIn.Arithmetic)
computeIsoK(&xDen, &xs, &p.XDen, xIn.Arithmetic)
computeIsoK(&yNum, &xs, &p.YNum, xIn.Arithmetic)
computeIsoK(&yDen, &xs, &p.YDen, xIn.Arithmetic)
xIn.Arithmetic.Invert(&wasInverted, &xDen, &xDen)
x = new(Field).Set(xIn)
xIn.Arithmetic.Mul(&tv, &xNum, &xDen)
xIn.Arithmetic.Selectznz(&x.Value, &x.Value, &tv, wasInverted)
yIn.Arithmetic.Invert(&wasInverted, &yDen, &yDen)
y = new(Field).Set(yIn)
yIn.Arithmetic.Mul(&tv, &yNum, &yDen)
yIn.Arithmetic.Selectznz(&y.Value, &y.Value, &tv, wasInverted)
yIn.Arithmetic.Mul(&y.Value, &y.Value, &yIn.Value)
return
}
func computeIsoK(out *[FieldLimbs]uint64, xxs, k *[][FieldLimbs]uint64, f FieldArithmetic) {
var tv [FieldLimbs]uint64
for i := range *k {
f.Mul(&tv, &(*xxs)[i], &(*k)[i])
f.Add(out, out, &tv)
}
}