pairs

package bn256

// For details of the algorithms used, see "Multiplication and Squaring on
// Pairing-Friendly Fields, Devegili et al.
// http://eprint.iacr.org/2006/471.pdf.

import (
"fmt"
"math/big"
)

// gfP2 implements a field of size p² as a quadratic extension of the base
// field where i²=-1.
type gfP2 struct {
x, y *big.Int // value is xi+y.
}

func newGFp2(pool *bnPool) *gfP2 {
return &gfP2{pool.Get(), pool.Get()}
}

func (e *gfP2) String() string {
x := new(big.Int).Mod(e.x, p)
y := new(big.Int).Mod(e.y, p)
return "(" + x.String() + "," + y.String() + ")"
}

func (e *gfP2) Put(pool *bnPool) {
pool.Put(e.x)
pool.Put(e.y)
}

func (e *gfP2) Set(a *gfP2) *gfP2 {
e.x.Set(a.x)
e.y.Set(a.y)
return e
}

func (e *gfP2) SetZero() *gfP2 {
e.x.SetInt64(0)
e.y.SetInt64(0)
return e
}

func (e *gfP2) SetOne() *gfP2 {
e.x.SetInt64(0)
e.y.SetInt64(1)
return e
}

func (e *gfP2) Minimal() {
if e.x.Sign() < 0 || e.x.Cmp(p) >= 0 {
e.x.Mod(e.x, p)
}
if e.y.Sign() < 0 || e.y.Cmp(p) >= 0 {
e.y.Mod(e.y, p)
}
}

func (e *gfP2) IsZero() bool {
return e.x.Sign() == 0 && e.y.Sign() == 0
}

func (e *gfP2) IsOne() bool {
if e.x.Sign() != 0 {
return false
}
words := e.y.Bits()
return len(words) == 1 && words[0] == 1
}

func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
e.y.Set(a.y)
e.x.Neg(a.x)
return e
}

func (e *gfP2) Negative(a *gfP2) *gfP2 {
e.x.Neg(a.x)
e.y.Neg(a.y)
return e
}

func (e *gfP2) Add(a, b *gfP2) *gfP2 {
e.x.Add(a.x, b.x)
e.y.Add(a.y, b.y)
return e
}

func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
e.x.Sub(a.x, b.x)
e.y.Sub(a.y, b.y)
return e
}

func (e *gfP2) Double(a *gfP2) *gfP2 {
e.x.Lsh(a.x, 1)
e.y.Lsh(a.y, 1)
return e
}

func (c *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 {
sum := newGFp2(pool)
sum.SetOne()
t := newGFp2(pool)

for i := power.BitLen() - 1; i >= 0; i-- {
t.Square(sum, pool)
if power.Bit(i) != 0 {
sum.Mul(t, a, pool)
} else {
sum.Set(t)
}
}

c.Set(sum)

sum.Put(pool)
t.Put(pool)

return c
}

// See "Multiplication and Squaring in Pairing-Friendly Fields",
// http://eprint.iacr.org/2006/471.pdf
func (e *gfP2) Mul(a, b *gfP2, pool *bnPool) *gfP2 {
tx := pool.Get().Mul(a.x, b.y)
t := pool.Get().Mul(b.x, a.y)
tx.Add(tx, t)
tx.Mod(tx, p)

ty := pool.Get().Mul(a.y, b.y)
t.Mul(a.x, b.x)
ty.Sub(ty, t)
e.y.Mod(ty, p)
e.x.Set(tx)

pool.Put(tx)
pool.Put(ty)
pool.Put(t)

return e
}

func (e *gfP2) MulScalar(a *gfP2, b *big.Int) *gfP2 {
e.x.Mul(a.x, b)
e.y.Mul(a.y, b)
return e
}

// MulXi sets e=ξa where ξ=i+3 and then returns e.
func (e *gfP2) MulXi(a *gfP2, pool *bnPool) *gfP2 {
// (xi+y)(i+3) = (3x+y)i+(3y-x)
tx := pool.Get().Lsh(a.x, 1)
tx.Add(tx, a.x)
tx.Add(tx, a.y)

ty := pool.Get().Lsh(a.y, 1)
ty.Add(ty, a.y)
ty.Sub(ty, a.x)

e.x.Set(tx)
e.y.Set(ty)

pool.Put(tx)
pool.Put(ty)

return e
}

func (e *gfP2) Square(a *gfP2, pool *bnPool) *gfP2 {
// Complex squaring algorithm:
// (xi+b)² = (x+y)(y-x) + 2*i*x*y
t1 := pool.Get().Sub(a.y, a.x)
t2 := pool.Get().Add(a.x, a.y)
ty := pool.Get().Mul(t1, t2)
ty.Mod(ty, p)

t1.Mul(a.x, a.y)
t1.Lsh(t1, 1)

e.x.Mod(t1, p)
e.y.Set(ty)

pool.Put(t1)
pool.Put(t2)
pool.Put(ty)

return e
}

func (e *gfP2) Invert(a *gfP2, pool *bnPool) *gfP2 {
// See "Implementing cryptographic pairings", M. Scott, section 3.2.
// ftp://136.206.11.249/pub/crypto/pairings.pdf
// https://eprint.iacr.org/2006/144.pdf
t := pool.Get()
t.Mul(a.y, a.y)
t2 := pool.Get()
t2.Mul(a.x, a.x)
t.Add(t, t2)

inv := pool.Get()
inv.ModInverse(t, p)

e.x.Neg(a.x)
e.x.Mul(e.x, inv)
e.x.Mod(e.x, p)

e.y.Mul(a.y, inv)
e.y.Mod(e.y, p)

pool.Put(t)
pool.Put(t2)
pool.Put(inv)

return e
}

func makeF2(a int) *gfP2 {
return &gfP2{big.NewInt(0), big.NewInt(int64(a))}
}
var xk = 16
var yz = &gfP2{big.NewInt(16), big.NewInt(0)}

var module = 19
var ax = 14
func double(x, y int) (int , int, *gfP2) {
a := x * x * 3 + ax
b := y * 2
a %= module
b %= module
k := int(new(big.Int).Mul(big.NewInt(int64(a)), new(big.Int).ModInverse(big.NewInt(int64(b)), p)).Int64())
k %= module
kb := (y - k * x) % module
fmt.Println(k, kb)

yk := makeF2(0)
yk.Negative(yz)
yk.Add(yk, makeF2((k * xk + kb) % module))

x3 := (k * k - 2 * x) % module
yk.MulScalar(yk, new(big.Int).ModInverse(big.NewInt(int64(xk - x3)), p))
yk.Minimal()

y3 := (k * (x - x3) - y) % module
fmt.Println(x3, ",", y3)
fmt.Println("ki :", yk.x, ",", yk.y)
return x3, y3, yk
}

func add(x, y, x2, y2 int) (int , int, *gfP2) {
if(x == x2 && y2 == y){
return double(x, y)
}
a := y2 - y
b := x2 - x
a %= module
b %= module
k := int(new(big.Int).Mul(big.NewInt(int64(a)), new(big.Int).ModInverse(big.NewInt(int64(b)), p)).Int64())
k %= module
kb := (y - k * x) % module
fmt.Println(k, kb)

yk := makeF2(0)
yk.Negative(yz)
yk.Add(yk, makeF2((k * xk + kb) % module))

x3 := (k * k - x - x2) % module
yk.MulScalar(yk, new(big.Int).ModInverse(big.NewInt(int64(xk - x3)), p))
yk.Minimal()

y3 := (k * (x - x3) - y) % module
fmt.Println(x3, ",", y3)
fmt.Println("ki :", yk.x, ",", yk.y)
return x3, y3, yk
}

func showGf2(yk *gfP2) {
if (yk.x.Cmp(big.NewInt(0)) == 0){
fmt.Println(yk.y)
} else if (yk.y.Cmp(big.NewInt(0)) == 0){
if (yk.x.Cmp(big.NewInt(1)) == 0){
fmt.Println("i")
} else {
fmt.Println(yk.x, "i")
}
} else {
fmt.Println(yk.x, "i + ", yk.y)
}
}

func doublei(x, y *gfP2, pool *bnPool) (*gfP2, *gfP2) {
//a := x * x * 3 + ax
a := makeF2(0).MulScalar(x, big.NewInt(3))
a = a.Mul(a, x, pool)
a.Add(a, makeF2(ax))

b := makeF2(0).MulScalar(y, big.NewInt(2))
b.Minimal()
b.Invert(b, pool)
k := a.Mul(a, b, pool)
k.Minimal()
kx := makeF2(0).Mul(k, x, pool)
kb := makeF2(0).Negative(y)
kb.Sub(kb, kx)
kb.Minimal()
//(y - k * x) % module

x3 := makeF2(0).Mul(k, k, pool)
twox := makeF2(0).MulScalar(x, big.NewInt(2))
x3.Sub(x3, twox)
x3.Minimal()
//x3 := (k * k - 2 * x) % module
y3 := makeF2(0).Sub(x, x3)
y3.Mul(y3, k, pool)
y3.Sub(y3, y)
y3.Minimal()
//y3 := (k * (x - x3) - y) % module
showGf2(x3)
showGf2(y3)
return x3, y3
}

func equal(a, b *gfP2) bool {
return makeF2(0).Sub(a, b).IsZero()
}
func addi(x, y, x2, y2 *gfP2, pool *bnPool) (*gfP2, *gfP2) {
if(equal(x, x2) && equal(y2, y)){
return doublei(x, y, pool)
}
//a := y2 - y
//b := x2 - x
a := makeF2(0).Sub(y2, y)
b := makeF2(0).Sub(x2, x)
b.Minimal()
b.Invert(b, pool)
k := a.Mul(a, b, pool)
k.Minimal()

kx := makeF2(0).Mul(k, x, pool)
kb := makeF2(0).Negative(y)
kb.Sub(kb, kx)
kb.Minimal()

x3 := makeF2(0).Mul(k, k, pool)
x3.Sub(x3, x)
x3.Sub(x3, x2)
x3.Minimal()
//x3 := (k * k - x - x2) % module
y3 := makeF2(0).Sub(x, x3)
y3.Mul(y3, k, pool)
y3.Sub(y3, y)
y3.Minimal()
//y3 := (k * (x - x3) - y) % module
showGf2(x3)
showGf2(y3)
return x3, y3
}


/*
y*2 = x*3 + 14x + 3 mod 19
# 20 r 5 k 2
P (17, 9) (15,15), (15,4) (17, -9), (0, 0)
Q (16, 16i) (1, i) (1, -i), (16, -16i) (0, 0)
15i + 2
*/
func F() {
pool := new(bnPool)
module = 19
p = big.NewInt(int64(module))
//xk = 1
//yz = &gfP2{big.NewInt(1), big.NewInt(0)}

//i1, j1 := makeF2(xk), yz
//i2, j2 := addi(i1, j1, i1, j1, pool)
//i3, j3 := addi(i1, j1, i2, j2, pool)
//i4, j4 := addi(i1, j1, i3, j3, pool)
//showGf2(i4)
//showGf2(j4)
fmt.Println("-----------")

x1, y1 := 15, 15
//x2, y2 := add(x1, y1, x1, y1)
//x3, y3 := add(x1, y1, x2, y2)
// add(x1, y1, x3, y3)
x2, y2, f2 := double(x1, y1)
x3, y3, f3 := add(x2, y2, x1, y1)
_, _, f41 := add(x3, y3, x1, y1)
f3.Mul(f3, f2, pool)
f3.Mul(f3, f41, pool)
fmt.Println("dst0: ", f3.x, "\t", f3.y)
_, _, f4 := double(x2, y2)

f2_2 := makeF2(0).Mul(f2, f2, pool)
f2_2.Mul(f2_2, f4, pool)
f2_2.Minimal()
fmt.Println("dst: ", f2_2.x, "\t", f2_2.y)
f2_2.MulScalar(f2_2, new(big.Int).Mod(big.NewInt(int64(xk - x1)), p))
f2_2.Minimal()
f2_2.Exp(f2_2, big.NewInt(72), pool)
fmt.Println("d2st: ", f2_2.x, "\t", f2_2.y)


a := &gfP2{big.NewInt(15), big.NewInt(2)}
//a.Mul(a, a, pool)
a.Exp(a, big.NewInt(2), pool)

fmt.Println(a.x, "\t", a.y)
}

//func F3() {
// module = 23
// ax = 17
// p = big.NewInt(int64(module))
// x1, y1 := 10, 7
// x2, y2 := add(x1, y1, x1, y1)
// x3, y3 := add(x1, y1, x2, y2)
// add(x1, y1, x3, y3)
// //x2, y2 := double(x1, y1)
// //double(x2, y2)
//
// pool := new(bnPool)
// a := &gfP2{big.NewInt(15), big.NewInt(2)}
// //a.Mul(a, a, pool)
// a.Exp(a, big.NewInt(4), pool)
//
// fmt.Println(a.x, "\t", a.y)
//}


func doublex(x, y int) (int , int) {
a := x * x * 3 + ax
b := y * 2
a %= module
b %= module
k := int(new(big.Int).Mul(big.NewInt(int64(a)), new(big.Int).ModInverse(big.NewInt(int64(b)), p)).Int64())
k %= module
//kb := (y - k * x) % module
x3 := (k * k - 2 * x) % module
y3 := (k * (x - x3) - y) % module
fmt.Println(x3, ",", y3)
return x3, y3
}

func addx(x, y, x2, y2 int) (int , int) {
if(x == x2 && y2 == y){
return doublex(x, y)
}
a := y2 - y
b := x2 - x
a %= module
b %= module
if b < 0{
b += module
}
k := int(new(big.Int).Mul(big.NewInt(int64(a)), new(big.Int).ModInverse(big.NewInt(int64(b)), p)).Int64())
k %= module
//kb := (y - k * x) % module

x3 := (k * k - x - x2) % module
y3 := (k * (x - x3) - y) % module
fmt.Println(x3, ",", y3)
return x3, y3
}

//find elliptic generator y^2 = x^3 + 4 mod 11
func F11() {
sum := 0
m := 11
ax = 0
module = m
p = big.NewInt(int64(module))

for x := 0; x < m; x++{
y2 := x * x * x + 4
y2 %= m
for y := 0; y < m; y++{
if (y * y) % m == y2 {
sum++
fmt.Println("---------------")
fmt.Println(x, y)
if y == 0{
break
}
xo, yo := x, y
i := 2
for {
xo, yo = addx(x, y, xo, yo)
i++
if xo < 0{
xo += module
}
if yo < 0{
yo += module
}
if (x == xo) && (y == module - yo){
break
}
}
fmt.Println("order:", i)
}
}
}
fmt.Println("total:", sum+1)
}

/*
y^2 = x^3 + 4 mod 11
k = 2 r = 3 #E = 12
(0, 2) (0, -2)
(8, i) (8, -i)
~ Zr * Zr
*/
func FZr() {
pool := new(bnPool)

module = 11
p = big.NewInt(int64(module))
xk = 1
yz = &gfP2{big.NewInt(1), big.NewInt(0)}

ax = 0
i1, j1 := makeF2(0), makeF2(2)
i2, j2 := makeF2(8), &gfP2{big.NewInt(10), big.NewInt(0)}
addi(i1, j1, i2, j2, pool)
//showGf2(i4)
//showGf2(j4)
fmt.Println("-----------")

x1, y1 := 17, 9
//x2, y2 := add(x1, y1, x1, y1)
//x3, y3 := add(x1, y1, x2, y2)
// add(x1, y1, x3, y3)
x2, y2, f2 := double(x1, y1)
_, _, f4 := double(x2, y2)

f2_2 := makeF2(0).Mul(f2, f2, pool)
f2_2.Mul(f2_2, f4, pool)
f2_2.Minimal()
fmt.Println("dst: ", f2_2.x, "\t", f2_2.y)
f2_2.MulScalar(f2_2, new(big.Int).ModInverse(big.NewInt(int64(xk - x1)), p))
f2_2.Minimal()
f2_2.Exp(f2_2, big.NewInt(72), pool)
fmt.Println("d2st: ", f2_2.x, "\t", f2_2.y)


a := &gfP2{big.NewInt(15), big.NewInt(2)}
//a.Mul(a, a, pool)
a.Exp(a, big.NewInt(5), pool)

fmt.Println(a.x, "\t", a.y)
}


/*
y^2 = x ^3 + 13 mod 31
#E = 25 ?
*/
func F25() {
sum := 0
m := 31
for x := 0; x < m; x++{
y2 := x * x * x + 13
y2 %= m
for y := 0; y < m; y++{
if (y * y) % m == y2 {
fmt.Println(x, y)
sum++
}
}
}
fmt.Println("total:", sum+1)
}

func F5() {
sum := 0
m := 31
ax = 0
module = m
p = big.NewInt(int64(module))

for x := 0; x < m; x++{
y2 := x * x * x + 13
y2 %= m
for y := 0; y < m; y++{
if (y * y) % m == y2 {
sum++
fmt.Println("---------------")
fmt.Println(x, y)
if y == 0{
break
}
xo, yo := x, y
i := 2
for {
xo, yo = addx(x, y, xo, yo)
i++
if xo < 0{
xo += module
}
if yo < 0{
yo += module
}
if (x == xo) && (y == module - yo){
break
}
}
fmt.Println("order:", i)
}
}
}
fmt.Println("total:", sum+1)
}



//Frobenius
//y ^2 = x ^3+4x+3 mod 67
func FTr() {
sum := 0
module = 67
p = big.NewInt(67)
ax = 4
pool := new(bnPool)
x := &gfP2{big.NewInt(2), big.NewInt(16)}
y := &gfP2{big.NewInt(30), big.NewInt(39)}
bx := &gfP2{big.NewInt(2), big.NewInt(16)}
by := &gfP2{big.NewInt(30), big.NewInt(39)}

for i := 0; i < 67*67*67*67; i++{
//fmt.Println(i)
//if (i == 3){
// x, y = addi(x, y, x, y, pool)
//}
x, y = addi(bx, by, x, y, pool)
m := makeF2(0).Sub(bx, x)
n := makeF2(0).Add(by, y)
m.Minimal()
n.Minimal()
if (m.IsZero() && n.IsZero()){
fmt.Println("ok:", i)
break
}

{
j := makeF2(0).MulScalar(x, big.NewInt(4))
a := makeF2(0).Mul(x, x, pool)
a.Mul(a, x, pool)
a.Add(a, j)
a.Add(a, makeF2(3))
k := makeF2(0).Mul(y, y, pool)
a.Sub(a, k)
a.Minimal()
//fmt.Println(a.IsZero())
if (!a.IsZero()){
panic("mm")
}
}

x2 := makeF2(0)
x2.x.Neg(x.x)
x2.y.Set(x.y)
y2 := makeF2(0)
y2.x.Neg(y.x)
y2.y.Set(y.y)

//fmt.Println("----Tr----")
//ex, ey := addi(x, y, x2, y2, pool)
//if (ex.x.Sign() != 0 || ey.x.Sign() != 0){
// //panic(i)
// sum++
//}
//fmt.Println("--------")

j := makeF2(0).MulScalar(x2, big.NewInt(4))
a := makeF2(0).Mul(x2, x2, pool)
a.Mul(a, x2, pool)
a.Add(a, j)
a.Add(a, makeF2(3))
k := makeF2(0).Mul(y2, y2, pool)
a.Sub(a, k)
a.Minimal()
//fmt.Println(a.IsZero())
if (!a.IsZero()){
panic("m2")
}
}
//x2 := &gfP2{big.NewInt(-2), big.NewInt(16)}
//y2 := &gfP2{big.NewInt(-30), big.NewInt(39)}
//dy := makeF2(0).Mul(y, y, pool)
//dy2 := makeF2(0).Mul(y2, y2, pool)
//dy.Sub(dy, dy2)
//dy.Minimal()
//dx := makeF2(0).Mul(x, x, pool)
//dx.Add(dx, makeF2(4))
//dx.Mul(dx, x, pool)
//dx2 := makeF2(0).Mul(x2, x2, pool)
//dx2.Add(dx2, makeF2(4))
//dx2.Mul(dx2, x2, pool)
//dx.Sub(dx, dx2)
//dx.Minimal()
//showGf2(dy)
//showGf2(dx)
fmt.Println(sum)
}


//r - torson F

posted @ 2021-04-14 10:42  zJanly  阅读(137)  评论(0编辑  收藏  举报