-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
153 lines (131 loc) · 4.29 KB
/
util.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package idemix
import (
"crypto/rand"
"crypto/sha256"
"github.com/hyperledger/fabric-amcl/amcl"
"github.com/hyperledger/fabric-amcl/amcl/FP256BN"
"github.com/pkg/errors"
)
// GenG1 is a generator of Group G1
var GenG1 = FP256BN.NewECPbigs(
FP256BN.NewBIGints(FP256BN.CURVE_Gx),
FP256BN.NewBIGints(FP256BN.CURVE_Gy))
// GenG2 is a generator of Group G2
var GenG2 = FP256BN.NewECP2fp2s(
FP256BN.NewFP2bigs(FP256BN.NewBIGints(FP256BN.CURVE_Pxa), FP256BN.NewBIGints(FP256BN.CURVE_Pxb)),
FP256BN.NewFP2bigs(FP256BN.NewBIGints(FP256BN.CURVE_Pya), FP256BN.NewBIGints(FP256BN.CURVE_Pyb)))
// GenGT is a generator of Group GT
var GenGT = FP256BN.Fexp(FP256BN.Ate(GenG2, GenG1))
// GroupOrder is the order of the groups
var GroupOrder = FP256BN.NewBIGints(FP256BN.CURVE_Order)
// FieldBytes is the bytelength of the group order
var FieldBytes = int(FP256BN.MODBYTES)
// RandModOrder returns a random element in 0, ..., GroupOrder-1
func RandModOrder(rng *amcl.RAND) *FP256BN.BIG {
// curve order q
q := FP256BN.NewBIGints(FP256BN.CURVE_Order)
// Take random element in Zq
return FP256BN.Randomnum(q, rng)
}
// HashModOrder hashes data into 0, ..., GroupOrder-1
func HashModOrder(data []byte) *FP256BN.BIG {
digest := sha256.Sum256(data)
digestBig := FP256BN.FromBytes(digest[:])
digestBig.Mod(GroupOrder)
return digestBig
}
func appendBytes(data []byte, index int, bytesToAdd []byte) int {
copy(data[index:], bytesToAdd)
return index + len(bytesToAdd)
}
func appendBytesG1(data []byte, index int, E *FP256BN.ECP) int {
length := 2*FieldBytes + 1
E.ToBytes(data[index:index+length], false)
return index + length
}
func EcpToBytes(E *FP256BN.ECP) []byte {
length := 2*FieldBytes + 1
res := make([]byte, length)
E.ToBytes(res, false)
return res
}
func appendBytesG2(data []byte, index int, E *FP256BN.ECP2) int {
length := 4 * FieldBytes
E.ToBytes(data[index : index+length])
return index + length
}
func appendBytesBig(data []byte, index int, B *FP256BN.BIG) int {
length := FieldBytes
B.ToBytes(data[index : index+length])
return index + length
}
func appendBytesString(data []byte, index int, s string) int {
bytes := []byte(s)
copy(data[index:], bytes)
return index + len(bytes)
}
// MakeNym creates a new unlinkable pseudonym
func MakeNym(sk *FP256BN.BIG, IPk *IssuerPublicKey, rng *amcl.RAND) (*FP256BN.ECP, *FP256BN.BIG) {
// Construct a commitment to the sk
// Nym = h_{sk}^sk \cdot h_r^r
RandNym := RandModOrder(rng)
Nym := EcpFromProto(IPk.HSk).Mul2(sk, EcpFromProto(IPk.HRand), RandNym)
return Nym, RandNym
}
// BigToBytes takes an *amcl.BIG and returns a []byte representation
func BigToBytes(big *FP256BN.BIG) []byte {
ret := make([]byte, FieldBytes)
big.ToBytes(ret)
return ret
}
// EcpToProto converts a *amcl.ECP into the proto struct *ECP
func EcpToProto(p *FP256BN.ECP) *ECP {
return &ECP{
X: BigToBytes(p.GetX()),
Y: BigToBytes(p.GetY())}
}
// EcpFromProto converts a proto struct *ECP into an *amcl.ECP
func EcpFromProto(p *ECP) *FP256BN.ECP {
return FP256BN.NewECPbigs(FP256BN.FromBytes(p.GetX()), FP256BN.FromBytes(p.GetY()))
}
// Ecp2ToProto converts a *amcl.ECP2 into the proto struct *ECP2
func Ecp2ToProto(p *FP256BN.ECP2) *ECP2 {
return &ECP2{
Xa: BigToBytes(p.GetX().GetA()),
Xb: BigToBytes(p.GetX().GetB()),
Ya: BigToBytes(p.GetY().GetA()),
Yb: BigToBytes(p.GetY().GetB())}
}
// Ecp2FromProto converts a proto struct *ECP2 into an *amcl.ECP2
func Ecp2FromProto(p *ECP2) *FP256BN.ECP2 {
return FP256BN.NewECP2fp2s(
FP256BN.NewFP2bigs(FP256BN.FromBytes(p.GetXa()), FP256BN.FromBytes(p.GetXb())),
FP256BN.NewFP2bigs(FP256BN.FromBytes(p.GetYa()), FP256BN.FromBytes(p.GetYb())))
}
// GetRand returns a new *amcl.RAND with a fresh seed
func GetRand() (*amcl.RAND, error) {
seedLength := 32
b := make([]byte, seedLength)
_, err := rand.Read(b)
if err != nil {
return nil, errors.Wrap(err, "error getting randomness for seed")
}
rng := amcl.NewRAND()
rng.Clean()
rng.Seed(seedLength, b)
return rng, nil
}
// Modadd takes input BIGs a, b, m, and returns a+b modulo m
func Modadd(a, b, m *FP256BN.BIG) *FP256BN.BIG {
c := a.Plus(b)
c.Mod(m)
return c
}
// Modsub takes input BIGs a, b, m and returns a-b modulo m
func Modsub(a, b, m *FP256BN.BIG) *FP256BN.BIG {
return Modadd(a, FP256BN.Modneg(b, m), m)
}