-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbulletproofs.go
105 lines (85 loc) · 2.19 KB
/
bulletproofs.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
package giota
import (
"github.com/peterdouglas/bp-go"
"math/big"
"github.com/decred/dcrd/dcrec/secp256k1"
"errors"
"github.com/decred/base58"
)
type PreProof struct {
commitment *Commitment
receiver *Address
sender *Address
value *big.Int
}
type ProofPrep []PreProof
type ECPoint struct {
X *big.Int
Y *big.Int
}
type Commitment struct {
Vector ECPoint
EncValue []byte
Blind *big.Int
sSecret *big.Int
Trytes Trytes
}
func (c *Commitment) Encode() (Trytes, error) {
pkCompressed := secp256k1.NewPublicKey(c.Vector.X, c.Vector.Y)
baseTr, err := AsciiToTrytes(base58.Encode(pkCompressed.SerializeCompressed()))
if err != nil {
return "", err
}
c.Trytes = baseTr
return c.Trytes, nil
}
func (c *Commitment) Decode() (ECPoint, error) {
for i := len(c.Trytes)-1; i > 0 ; i-- {
if string(c.Trytes)[i] != '9' {
c.Trytes = c.Trytes[:i+1]
break
}
}
asciKey, err := TrytesToAscii(c.Trytes)
if err != nil {
return ECPoint{}, err
}
byteKey := base58.Decode(asciKey)
pkKey, err := secp256k1.ParsePubKey(byteKey[:33])
return ECPoint{pkKey.GetX(), pkKey.GetY()}, nil
}
// Generate a single commitment from a commitment struct
func (c *Commitment) Generate(receiverKey *secp256k1.PublicKey, v, gamma *big.Int) error {
if v.Sign() < 0 {
c.Vector = ECPoint(bp_go.EC.G.Mult(v).Add(bp_go.EC.H.Mult(gamma)).Neg())
} else {
c.Vector = ECPoint(bp_go.EC.G.Mult(v).Add(bp_go.EC.H.Mult(gamma)))
}
c.Blind = gamma
// now we encrypt the value so the receiver can recreate the trans
ciphertext, err := secp256k1.Encrypt(receiverKey, v.Bytes())
if err != nil {
return err
}
c.EncValue = ciphertext
return nil
}
func (p *ProofPrep) GetVals() ([]*big.Int) {
valArr := make([]*big.Int, len(*p))
blindArr := make([]*big.Int, len(*p))
commitArr := make([]bp_go.ECPoint, len(*p))
totalEC := bp_go.EC.Zero()
total := int64(0)
for i, proof := range *p {
valArr[i] = proof.value
blindArr[i] = proof.commitment.Blind
bpEC := bp_go.ECPoint{X: proof.commitment.Vector.X, Y: proof.commitment.Vector.Y}
commitArr[i] = bpEC
totalEC.Add(bpEC)
total += proof.value.Int64()
}
if !totalEC.Equal(bp_go.EC.Zero()) {
errors.New("The total sum was not equal to zero")
}
return valArr
}