-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
84 lines (70 loc) · 1.78 KB
/
main.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
package main
import (
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
"math/big"
)
type ECPoint struct {
X, Y *big.Int
}
func seeding() []byte {
seed := make([]byte, 32)
_, err := rand.Read(seed)
if err != nil {
fmt.Println("Error generating seed:", err)
return nil
}
return seed
}
func main() {
curve := elliptic.P256()
points := generateECPoints(seeding(), 3, curve)
fmt.Println(curve.IsOnCurve(points[0].X, points[0].Y))
fmt.Println(curve.IsOnCurve(points[1].X, points[1].Y))
prover(points[0], points[1], curve)
}
func generateECPoints(seed []byte, n int, curve elliptic.Curve) []ECPoint {
var points []ECPoint
for i := 0; len(points) < n; i++ {
// Create a new hash for each x value
hashInput := append(seed, byte(i))
// P is the order of the curve
x := hashToBigInt(hashInput, curve.Params().P)
y, yNeg := findYForX(curve, x)
if y != nil {
if randBit(seed) == 0 {
points = append(points, ECPoint{X: new(big.Int).Set(x), Y: y})
} else {
points = append(points, ECPoint{X: new(big.Int).Set(x), Y: yNeg})
}
}
}
return points
}
func findYForX(curve elliptic.Curve, x *big.Int) (*big.Int, *big.Int) {
xCubed := new(big.Int).Exp(x, big.NewInt(3), nil)
a := big.NewInt(-3)
aX := new(big.Int).Mul(a, x)
rightSide := new(big.Int).Add(xCubed, aX)
rightSide.Add(rightSide, curve.Params().B)
rightSide.Mod(rightSide, curve.Params().P)
y := new(big.Int).ModSqrt(rightSide, curve.Params().P)
if y == nil {
return nil, nil
}
yNeg := new(big.Int).Neg(y)
yNeg.Mod(yNeg, curve.Params().P)
return y, yNeg
}
func randBit(seed []byte) int {
hash := sha256.Sum256(seed)
return int(hash[0] & 1)
}
func hashToBigInt(data []byte, mod *big.Int) *big.Int {
hash := sha256.Sum256(data)
x := new(big.Int).SetBytes(hash[:])
x.Mod(x, mod)
return x
}