g := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(27))} // Generator
// define new random r
r := big.NewInt(int64(23)) // random r
// define new Schnorr crypto system using the values
schnorr, sk, err := Gen(ec, g, r)
if err!=nil {
fmt.println(err)
}
// define message to sign
m := []byte("hola")
// also we can hash the message, but it's not mandatory, as it will be done inside the schnorr.Sign, but we can perform it now, just to check the function
h := Hash([]byte("hola"), c)
if h.String() != "34719153732582497359642109898768696927847420320548121616059449972754491425079") {
fmt.Println("not correctly hashed")
}
s, rPoint, err := schnorr.Sign(sk, m)
if err!=nil {
fmt.println(err)
}
// verify Schnorr signature
verified, err := Verify(schnorr.EC, sk.PubK, m, s, rPoint)
- `Multiplication and Squaring on Pairing-Friendly
Fields`, Augusto Jun Devegili, Colm Ó hÉigeartaigh, Michael Scott, and Ricardo Dahab https://pdfs.semanticscholar.org/3e01/de88d7428076b2547b60072088507d881bf1.pdf
- `Optimal Pairings`, Frederik Vercauteren https://www.cosic.esat.kuleuven.be/bcrypt/optimal.pdf
@ -87,6 +436,134 @@ over Elliptic Curves`, Matthieu Rivain https://eprint.iacr.org/2011/338.pdf
- [x] Fq, Fq2, Fq6, Fq12 operations
- [x] G1, G2 operations
#### Usage
First let's define three basic functions to convert integer compositions to big integer compositions:
```go
func iToBig(a int) *big.Int {
return big.NewInt(int64(a))
}
func iiToBig(a, b int) [2]*big.Int {
return [2]*big.Int{iToBig(a), iToBig(b)}
}
func iiiToBig(a, b int) [2]*big.Int {
return [2]*big.Int{iToBig(a), iToBig(b)}
}
```
- Finite Fields (1, 2, 6, 12) operations
```go
// new finite field of order 1
fq1 := NewFq(iToBig(7))
// basic operations of finite field 1
res := fq1.Add(iToBig(4), iToBig(4))
res = fq1.Double(iToBig(5))
res = fq1.Sub(iToBig(5), iToBig(7))
res = fq1.Neg(iToBig(5))
res = fq1.Mul(iToBig(5), iToBig(11))
res = fq1.Inverse(iToBig(4))
res = fq1.Square(iToBig(5))
// new finite field of order 2
nonResidueFq2str := "-1" // i / Beta
nonResidueFq2, ok := new(big.Int).SetString(nonResidueFq2str, 10)
fq2 := Fq2{fq1, nonResidueFq2}
nonResidueFq6 := iiToBig(9, 1)
// basic operations of finite field of order 2
res := fq2.Add(iiToBig(4, 4), iiToBig(3, 4))
res = fq2.Double(iiToBig(5, 3))
res = fq2.Sub(iiToBig(5, 3), iiToBig(7, 2))
res = fq2.Neg(iiToBig(4, 4))
res = fq2.Mul(iiToBig(4, 4), iiToBig(3, 4))
res = fq2.Inverse(iiToBig(4, 4))
res = fq2.Div(iiToBig(4, 4), iiToBig(3, 4))
res = fq2.Square(iiToBig(4, 4))
// new finite field of order 6
nonResidueFq6 := iiToBig(9, 1) // TODO
fq6 := Fq6{fq2, nonResidueFq6}
// define two new values of Finite Field 6, in order to be able to perform the operations
a := [3][2]*big.Int{
iiToBig(1, 2),
iiToBig(3, 4),
iiToBig(5, 6)}
b := [3][2]*big.Int{
iiToBig(12, 11),
iiToBig(10, 9),
iiToBig(8, 7)}
// basic operations of finite field order 6
res := fq6.Add(a, b)
res = fq6.Sub(a, b)
res = fq6.Mul(a, b)
divRes := fq6.Div(mulRes, b)
// new finite field of order 12
q, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10) // i
if !ok {
fmt.Println("error parsing string to big integer")
}
fq1 := NewFq(q)
nonResidueFq2, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208582", 10) // i