forked from MixinNetwork/mobilecoin-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.go
125 lines (108 loc) · 2.66 KB
/
mod.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package api
import (
"encoding/binary"
"encoding/hex"
"github.com/bwesterb/go-ristretto"
"github.com/dchest/blake2b"
)
func KeyImageFromPrivate(private *ristretto.Scalar) *ristretto.Point {
var p ristretto.Point
p.ScalarMultBase(private)
hp := hashToPoint(&p)
var point ristretto.Point
return point.ScalarMult(hp, private)
}
func hashToPoint(public *ristretto.Point) *ristretto.Point {
hash := blake2b.New512()
hash.Write([]byte(HASH_TO_POINT_DOMAIN_TAG))
hash.Write(public.Bytes())
var key [64]byte
copy(key[:], hash.Sum(nil))
var r1Bytes, r2Bytes [32]byte
copy(r1Bytes[:], key[:32])
copy(r2Bytes[:], key[32:])
var r, r1, r2 ristretto.Point
return r.Add(r1.SetElligator(&r1Bytes), r2.SetElligator(&r2Bytes))
}
func hashToScalar(r *ristretto.Point, a *ristretto.Scalar) *ristretto.Scalar {
var point ristretto.Point
var hs ristretto.Scalar
hash := blake2b.New512()
hash.Write([]byte(HASH_TO_SCALAR_DOMAIN_TAG))
hash.Write(point.ScalarMult(r, a).Bytes())
var key [64]byte
copy(key[:], hash.Sum(nil))
return hs.SetReduced(&key)
}
func uint64ToScalar(i uint64) *ristretto.Scalar {
var buf [32]byte
binary.LittleEndian.PutUint64(buf[:], i)
var s ristretto.Scalar
return s.SetBytes(&buf)
}
func hexToScalar(h string) *ristretto.Scalar {
buf, err := hex.DecodeString(h)
if err != nil {
panic(err)
}
var buf32 [32]byte
copy(buf32[:], buf)
var s ristretto.Scalar
return s.SetBytes(&buf32)
}
func hexToPoint(h string) *ristretto.Point {
buf, err := hex.DecodeString(h)
if err != nil {
panic(err)
}
var buf32 [32]byte
copy(buf32[:], buf)
var s ristretto.Point
s.SetBytes(&buf32)
return &s
}
func multiscalarMul(scalars []*ristretto.Scalar, points []*ristretto.Point) *ristretto.Point {
var p ristretto.Point
p.SetZero()
for i := range scalars {
var t ristretto.Point
t.ScalarMult(points[i], scalars[i])
p.Add(&p, &t)
}
return &p
}
func createSharedSecret(public *ristretto.Point, private *ristretto.Scalar) *ristretto.Point {
var r ristretto.Point
return r.ScalarMult(public, private)
}
func fromBytesModOrderWide(data []byte) *ristretto.Scalar {
var data64 [64]byte
copy(data64[:], data)
var hs ristretto.Scalar
return hs.SetReduced(&data64)
}
func resizeUint64ToPow2(vec []uint64) []uint64 {
l := nextPowerOfTwo(len(vec))
for i := len(vec); i < l; i++ {
vec = append(vec, vec[i-1])
}
return vec
}
func resizeScalarToPow2(vec []*ristretto.Scalar) []*ristretto.Scalar {
l := nextPowerOfTwo(len(vec))
for i := len(vec); i < l; i++ {
var zero ristretto.Scalar
vec = append(vec, zero.Add(&zero, vec[i-1]))
}
return vec
}
func nextPowerOfTwo(v int) int {
v--
v |= v >> 1
v |= v >> 2
v |= v >> 4
v |= v >> 8
v |= v >> 16
v++
return v
}