/
PoDR2_challenge.go
58 lines (54 loc) · 1.44 KB
/
PoDR2_challenge.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
package pbc
import (
"crypto/rand"
"errors"
"math/big"
"github.com/Nik-U/pbc"
"github.com/centrifuge/go-substrate-rpc-client/v4/types"
)
func PoDR2ChallengeGenerate(N int64, SharedParams string) []QElement {
pairing, _ := pbc.NewPairingFromString(SharedParams)
//Random number generated on the chain, length: len(Q)∈(0,Tag.N], number size: Q∈(0,Tag.N]
l := new(big.Int)
// Randomly select l blocks
for {
l, _ = rand.Int(rand.Reader, big.NewInt(N))
if l.Cmp(big.NewInt(0)) == +1 {
break
}
}
challenge := make([]QElement, l.Int64())
TagUnique := make(map[int64]struct{})
for i := int64(0); i < l.Int64(); i++ {
for {
I, _ := rand.Int(rand.Reader, big.NewInt(N))
I.Add(I, big.NewInt(1))
_, ok := TagUnique[I.Int64()]
if !ok {
TagUnique[I.Int64()] = struct{}{}
challenge[i].I = I.Int64()
break
} else {
continue
}
}
Q := pairing.NewZr().Rand().Bytes()
challenge[i].V = Q
}
return challenge
}
func PoDR2ChallengeGenerateFromChain(blockindex types.Bytes, blockrandom []types.Bytes) ([]QElement, error) {
if len(blockindex) != len(blockrandom) {
return nil, errors.New("The number of blocks and the number of random numbers are not equal")
}
challenge := make([]QElement, len(blockindex))
for j := 0; j < len(blockindex); j++ {
if int64(blockindex[j]) == 0 {
challenge[j].I = 1
} else {
challenge[j].I = int64(blockindex[j])
}
challenge[j].V = blockrandom[j]
}
return challenge, nil
}