-
Notifications
You must be signed in to change notification settings - Fork 22
/
scalarmult.go
91 lines (76 loc) · 1.8 KB
/
scalarmult.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package curve256k1
import "sync"
func (p *PointJacobian) ScalarMult(q *PointJacobian, k []byte) *PointJacobian {
s := normalizeScalar(k)
var table lookupTable
table.Init(q)
var tmp PointJacobian
var v, zero PointJacobian
zero.Zero()
v.Zero()
// first byte
b := s[0]
table.SelectInto(&tmp, b>>4)
v.Add(&v, &tmp)
v.Double(&v)
v.Double(&v)
v.Double(&v)
v.Double(&v)
table.SelectInto(&tmp, b&0xf)
v.Add(&v, &tmp)
for i := 1; i < len(s); i++ {
b := s[i]
v.Double(&v)
v.Double(&v)
v.Double(&v)
v.Double(&v)
table.SelectInto(&tmp, b>>4)
v.Add(&v, &tmp)
v.Double(&v)
v.Double(&v)
v.Double(&v)
v.Double(&v)
table.SelectInto(&tmp, b&0xf)
v.Add(&v, &tmp)
}
p.Set(&v)
return p
}
var baseTable [64]lookupTable
var initOnce sync.Once
func initBaseTable() {
initOnce.Do(func() {
var gen Point
var base PointJacobian
base.FromAffine(gen.NewGenerator())
for i := 0; i < 64; i++ {
baseTable[i].Init(&base)
base.Double(&base)
base.Double(&base)
base.Double(&base)
base.Double(&base)
}
})
}
func (p *PointJacobian) ScalarBaseMult(k []byte) *PointJacobian {
initBaseTable()
s := normalizeScalar(k)
var q PointJacobian
q.FromAffine(new(Point).NewGenerator())
var v PointJacobian
v.Zero()
for i, j := 0, len(baseTable)-1; i < len(s); i++ {
b := s[i]
// hi-nibble
var tmp PointJacobian
baseTable[j].SelectInto(&tmp, b>>4)
v.Add(&v, &tmp)
j--
// low-nibble
baseTable[j].SelectInto(&tmp, b&0xf)
v.Add(&v, &tmp)
j--
}
p.Set(&v)
return p
}