ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

pairs

2021-04-14 11:04:22  阅读:211  来源: 互联网

标签:pairs NewInt big gfP2 module Mul pool


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

标签:pairs,NewInt,big,gfP2,module,Mul,pool
来源: https://www.cnblogs.com/Janly/p/14656753.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有