init: v1.0.0
This commit is contained in:
@@ -0,0 +1,618 @@
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"xdx.jelly/xgcl/gmath"
|
||||
)
|
||||
|
||||
var twoTo256 = new(big.Int).Lsh(big.NewInt(1), 256)
|
||||
|
||||
func gfPFromBigInt(A *big.Int) *gfP {
|
||||
a := &gfP{}
|
||||
buf := make([]byte, 32)
|
||||
A.FillBytes(buf)
|
||||
a.Unmarshal(buf)
|
||||
montEncode(a, a)
|
||||
return a
|
||||
}
|
||||
|
||||
func randomInt(r io.Reader, max *big.Int) *big.Int {
|
||||
a, _ := rand.Int(r, max)
|
||||
return a
|
||||
}
|
||||
|
||||
func (e *gfP) random(r io.Reader) *gfP {
|
||||
e.Set(gfPFromBigInt(randomInt(r, P)))
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *gfP2) random(r io.Reader) *gfP2 {
|
||||
e.x.random(r)
|
||||
e.y.random(r)
|
||||
return e
|
||||
}
|
||||
|
||||
func (f *gfP6) random(r io.Reader) *gfP6 {
|
||||
f.x.random(r)
|
||||
f.z.random(r)
|
||||
f.y.random(r)
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *gfP12) random(r io.Reader) *gfP12 {
|
||||
f.x.random(r)
|
||||
f.y.random(r)
|
||||
return f
|
||||
}
|
||||
|
||||
func testOp(t *testing.T, arg1, arg2 *big.Int, op1 func(*big.Int, *big.Int, *big.Int), op2 func(*gfP, *gfP, *gfP), equal func(*gfP, *gfP) bool) {
|
||||
var a, b *gfP
|
||||
|
||||
a = gfPFromBigInt(arg1)
|
||||
if arg2 != nil {
|
||||
b = gfPFromBigInt(arg2)
|
||||
}
|
||||
|
||||
C := new(big.Int)
|
||||
op1(C, arg1, arg2)
|
||||
c1 := gfPFromBigInt(C)
|
||||
|
||||
c2 := &gfP{}
|
||||
op2(c2, a, b)
|
||||
if !equal(c1, c2) {
|
||||
fmt.Println("failed:")
|
||||
fmt.Println("\ta =", a)
|
||||
fmt.Println("\tb =", b)
|
||||
fmt.Println("\tc1 =", c1)
|
||||
fmt.Println("\tc2 =", c2)
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
func TestGFpSqrt(t *testing.T) {
|
||||
for i := 0; i < 100000; i++ {
|
||||
a := randomInt(rand.Reader, twoTo256)
|
||||
a.Mul(a, a).Mod(a, N)
|
||||
testOp(t,
|
||||
big.NewInt(1),
|
||||
nil,
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.ModSqrt(a, P)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
c.Sqrt(a)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
c := &gfP{}
|
||||
gfpAdd(c, a, b)
|
||||
return *a == *b || *c == gfP{}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGFpNeg(t *testing.T) {
|
||||
a := &gfP{0xe56f9b27e351457c, 0x21f2934b1a7aeedb, 0xd603ab4ff58ec745, 0xb640000002a3a6f1}
|
||||
gfpNeg(a, a)
|
||||
if *a != (gfP{1, 0, 0, 0}) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
for i := 0; i < 1000000; i++ {
|
||||
a := randomInt(rand.Reader, P)
|
||||
a.Mul(a, a).Mod(a, N)
|
||||
testOp(t,
|
||||
randomInt(rand.Reader, P),
|
||||
nil,
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.Neg(a).Mod(c, P)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
gfpNeg(c, a)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
return *a == *b
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGFpAdd(t *testing.T) {
|
||||
for i := 0; i < 1000000; i++ {
|
||||
testOp(t,
|
||||
randomInt(rand.Reader, twoTo256),
|
||||
randomInt(rand.Reader, twoTo256),
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.Add(a, b).Mod(c, P)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
gfpAdd(c, a, b)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
return *a == *b
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGFpSub(t *testing.T) {
|
||||
for i := 0; i < 1000000; i++ {
|
||||
a := randomInt(rand.Reader, twoTo256)
|
||||
b := randomInt(rand.Reader, twoTo256)
|
||||
testOp(t,
|
||||
a,
|
||||
b.Sub(a, big.NewInt(1)),
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.Sub(a, b).Mod(c, P)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
gfpSub(c, a, b)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
return *a == *b
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGFpHalf(t *testing.T) {
|
||||
for i := 0; i < 100000; i++ {
|
||||
testOp(t,
|
||||
randomInt(rand.Reader, P),
|
||||
nil,
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.Set(a)
|
||||
if c.Bit(0) == 1 {
|
||||
c.Add(a, P)
|
||||
}
|
||||
c.Rsh(c, 1)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
c.half(a)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
return *a == *b
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// FIXME: amd64平台不支持 a and b > p
|
||||
func TestGFpMul(t *testing.T) {
|
||||
for i := 0; i < 100000; i++ {
|
||||
testOp(t,
|
||||
randomInt(rand.Reader, P),
|
||||
randomInt(rand.Reader, P),
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.Mul(a, b).Mod(c, P)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
gfpMul(c, a, b)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
return *a == *b
|
||||
},
|
||||
)
|
||||
|
||||
testOp(t,
|
||||
randomInt(rand.Reader, twoTo256),
|
||||
randomInt(rand.Reader, twoTo256),
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.Mul(a, b).Mod(c, P)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
gfpMul(c, a, b)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
return *a == *b
|
||||
},
|
||||
)
|
||||
|
||||
testOp(t,
|
||||
new(big.Int).Sub(twoTo256, big.NewInt(int64(i+1))),
|
||||
new(big.Int).Sub(twoTo256, big.NewInt(int64(i+2))),
|
||||
func(c *big.Int, a *big.Int, b *big.Int) {
|
||||
c.Mul(a, b).Mod(c, P)
|
||||
},
|
||||
func(c *gfP, a *gfP, b *gfP) {
|
||||
gfpMul(c, a, b)
|
||||
},
|
||||
func(a *gfP, b *gfP) bool {
|
||||
return *a == *b
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpeedGFp(t *testing.T) {
|
||||
a := newGFp(123)
|
||||
b := newGFp(123)
|
||||
c := newGFp(1)
|
||||
|
||||
buf := make([]byte, 32)
|
||||
|
||||
a.Marshal(buf)
|
||||
A := new(big.Int).SetBytes(buf)
|
||||
b.Marshal(buf)
|
||||
B := new(big.Int).SetBytes(buf)
|
||||
c.Marshal(buf)
|
||||
C := new(big.Int).SetBytes(buf)
|
||||
|
||||
// fmt.Println(a, b, c)
|
||||
begin := time.Now()
|
||||
total := 10000000
|
||||
for i := 0; i < total; i++ {
|
||||
gfpMul(c, a, b)
|
||||
}
|
||||
elaspe := time.Since(begin)
|
||||
fmt.Println("time: ", elaspe.Milliseconds(), "ms")
|
||||
fmt.Println(int(float64(total) / float64(elaspe.Milliseconds()) * 1000))
|
||||
|
||||
begin = time.Now()
|
||||
for i := 0; i < total; i++ {
|
||||
C.Mul(A, B)
|
||||
}
|
||||
elaspe = time.Since(begin)
|
||||
fmt.Println("time: ", elaspe.Milliseconds(), "ms")
|
||||
fmt.Println(int(float64(total) / float64(elaspe.Milliseconds()) * 1000))
|
||||
|
||||
}
|
||||
|
||||
func (e *gfP2) Exp(a *gfP2, power *big.Int) *gfP2 {
|
||||
sum := (&gfP2{}).SetOne()
|
||||
t := &gfP2{}
|
||||
|
||||
for i := power.BitLen() - 1; i >= 0; i-- {
|
||||
t.Square(sum)
|
||||
if power.Bit(i) != 0 {
|
||||
sum.Mul(t, a)
|
||||
} else {
|
||||
sum.Set(t)
|
||||
}
|
||||
}
|
||||
|
||||
e.Set(sum)
|
||||
return e
|
||||
}
|
||||
|
||||
// Exp set c = a^power and return c
|
||||
func (f *gfP6) Exp(a *gfP6, power *big.Int) *gfP6 {
|
||||
sum := (&gfP6{}).SetOne()
|
||||
t := &gfP6{}
|
||||
|
||||
for i := power.BitLen() - 1; i >= 0; i-- {
|
||||
t.Square(sum)
|
||||
if power.Bit(i) != 0 {
|
||||
sum.Mul(t, a)
|
||||
} else {
|
||||
sum.Set(t)
|
||||
}
|
||||
}
|
||||
|
||||
f.Set(sum)
|
||||
return f
|
||||
}
|
||||
func TestGFp(t *testing.T) {
|
||||
one := newGFp(1)
|
||||
//one := &gfP{1}
|
||||
//two := &gfP{2}
|
||||
gfpMul(one, r2, one)
|
||||
gfpMul(one, &gfP{1}, one)
|
||||
montDecode(one, one)
|
||||
if *one != (gfP{1}) {
|
||||
t.Fail()
|
||||
fmt.Println(one)
|
||||
return
|
||||
}
|
||||
|
||||
// a := (&gfP{}).random(rand.Reader)
|
||||
a := &gfP{0x0a1c7970e5df544d, 0xe74504e9a96b56cc, 0xcda02d92d4d62924, 0x7d2bc576fdf597d1}
|
||||
b := &gfP{}
|
||||
c := &gfP{}
|
||||
fmt.Println("Test Exponent")
|
||||
b.exp(a, pMinus1)
|
||||
//b.exp(a,[4]uint64{2,0,0,0})
|
||||
//fmt.Println("a:", b)
|
||||
//gfpMul(c,a,a)
|
||||
//fmt.Println("c:",c)
|
||||
//gfpSub(b,c,b)
|
||||
// montDecode(b, b)
|
||||
if *b != *newGFp(1) {
|
||||
t.Fail()
|
||||
fmt.Println(b)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
var rN1 = &gfP{0x0a1c7970e5df544d, 0xe74504e9a96b56cc, 0xcda02d92d4d62924, 0x7d2bc576fdf597d1}
|
||||
fmt.Println("Test Rn")
|
||||
gfpMul(b, rN1, r3)
|
||||
montDecode(b, b)
|
||||
if *b != (gfP{1}) {
|
||||
t.Fail()
|
||||
fmt.Println(b)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
|
||||
fmt.Println("Test Invert")
|
||||
a = newGFp(1)
|
||||
c.Invert(a)
|
||||
fmt.Println(a, c)
|
||||
gfpMul(c, c, a)
|
||||
montDecode(c, c)
|
||||
if *c != (gfP{1}) {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
}
|
||||
|
||||
func TestGfP2(t *testing.T) {
|
||||
|
||||
p2Minus1 := new(big.Int)
|
||||
p2Minus1.Mul(P, P)
|
||||
p2Minus1.Sub(p2Minus1, gmath.BigInt1)
|
||||
|
||||
a := (&gfP2{}).random(rand.Reader)
|
||||
b := &gfP2{}
|
||||
c := &gfP2{}
|
||||
|
||||
fmt.Println("Test gfP2 mul and square")
|
||||
fmt.Println("a: ", a)
|
||||
b.Mul(a, a)
|
||||
fmt.Println("a^2:", b)
|
||||
|
||||
c.Square(a)
|
||||
fmt.Println("a*a:", c)
|
||||
if !c.Sub(c, b).IsZero() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
|
||||
fmt.Println("Test exponential")
|
||||
c.Exp(a, p2Minus1)
|
||||
if !c.IsOne() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
|
||||
fmt.Println("Test Invert")
|
||||
c.Invert(a)
|
||||
c.Mul(c, a)
|
||||
if !c.IsOne() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
}
|
||||
|
||||
func TestGFp2Sqrt(t *testing.T) {
|
||||
for i := 0; i < 100000; i++ {
|
||||
a := (&gfP2{}).random(rand.Reader)
|
||||
a.Mul(a, a)
|
||||
b := *a
|
||||
if !a.Sqrt(a) {
|
||||
t.Fatal()
|
||||
}
|
||||
a.Square(a)
|
||||
if *a != b {
|
||||
t.Fatal()
|
||||
}
|
||||
c := &gfP2{}
|
||||
if !c.Sqrt(a) {
|
||||
t.Fatal()
|
||||
}
|
||||
a.Square(c)
|
||||
if *a != b {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGfP6(t *testing.T) {
|
||||
p6Minus1 := new(big.Int)
|
||||
p6Minus1.Exp(P, gmath.BigInt6, nil)
|
||||
p6Minus1.Sub(p6Minus1, gmath.BigInt1)
|
||||
|
||||
a := (&gfP6{}).random(rand.Reader)
|
||||
b := &gfP6{}
|
||||
c := &gfP6{}
|
||||
fmt.Println(a)
|
||||
|
||||
fmt.Println("Test gfP6 mul and square")
|
||||
fmt.Println("a: ", a)
|
||||
b.Mul(a, a)
|
||||
fmt.Println("a^2:", b)
|
||||
|
||||
c.Square(a)
|
||||
fmt.Println("a*a:", c)
|
||||
if !c.Sub(c, b).IsZero() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Test exponential")
|
||||
|
||||
c.Exp(a, p6Minus1)
|
||||
//c.Exp(a,gmath.BigInt1)
|
||||
if !c.IsOne() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
|
||||
fmt.Println("Test Invert")
|
||||
c.Invert(a)
|
||||
c.Mul(c, a)
|
||||
if !c.IsOne() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
}
|
||||
|
||||
func TestGfP12(t *testing.T) {
|
||||
p12Minus1 := new(big.Int)
|
||||
p12Minus1.Exp(P, gmath.BigInt12, nil)
|
||||
p12Minus1.Sub(p12Minus1, gmath.BigInt1)
|
||||
|
||||
a := (&gfP12{}).random(rand.Reader)
|
||||
b := &gfP12{}
|
||||
c := &gfP12{}
|
||||
fmt.Println(a)
|
||||
|
||||
fmt.Println("Test gfP12 mul and square")
|
||||
fmt.Println("a: ", a)
|
||||
b.Mul(a, a)
|
||||
fmt.Println("a^2:", b)
|
||||
|
||||
c.Square(a)
|
||||
fmt.Println("a*a:", c)
|
||||
if !c.Sub(c, b).IsZero() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Test exponential")
|
||||
|
||||
c.Exp(a, p12Minus1)
|
||||
//c.Exp(a,gmath.BigInt1)
|
||||
if !c.IsOne() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
|
||||
fmt.Println("Test Invert")
|
||||
c.Invert(a)
|
||||
c.Mul(c, a)
|
||||
if !c.IsOne() {
|
||||
t.Fail()
|
||||
fmt.Println(c)
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
|
||||
}
|
||||
|
||||
func TestFrobenius6(t *testing.T) {
|
||||
p2 := new(big.Int).Mul(P, P)
|
||||
a := (&gfP6{}).random(rand.Reader)
|
||||
b := &gfP6{}
|
||||
c := &gfP6{}
|
||||
b.Frobenius(a)
|
||||
c.Exp(a, P)
|
||||
if *b != *c {
|
||||
fmt.Println("a:", a)
|
||||
fmt.Println("b:", b)
|
||||
fmt.Println("c:", c)
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
b.FrobeniusP2(a)
|
||||
c.Exp(a, p2)
|
||||
if *b != *c {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestFrobenius12(t *testing.T) {
|
||||
p2 := new(big.Int).Mul(P, P)
|
||||
a := (&gfP12{}).random(rand.Reader)
|
||||
b := &gfP12{}
|
||||
c := &gfP12{}
|
||||
|
||||
fmt.Println("Test Frobenius on GFP12")
|
||||
b.Frobenius(a)
|
||||
c.Exp(a, P)
|
||||
if *b != *c {
|
||||
fmt.Println("a:", a)
|
||||
fmt.Println("b:", b)
|
||||
fmt.Println("c:", c)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
|
||||
fmt.Println("Test Frobenius2 on GFP12")
|
||||
b.FrobeniusP2(a)
|
||||
c.Exp(a, p2)
|
||||
if *b != *c {
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
fmt.Println("pass")
|
||||
}
|
||||
|
||||
func present(p *gfP) string {
|
||||
|
||||
return fmt.Sprintf("gfP{0x%x,0x%x,0x%x,0x%x}", p[0], p[1], p[2], p[3])
|
||||
}
|
||||
|
||||
// ExampleGFP12Gen generate gfP12Gen
|
||||
func TestGFP12Gen(t *testing.T) {
|
||||
e := Pair(&G1{*curveGen}, &G2{*twistGen}).p
|
||||
fmt.Printf(`
|
||||
var gfP12Gen *gfP12 = &gfP12{
|
||||
x: gfP6{
|
||||
x: gfP2{
|
||||
x: %s,
|
||||
y: %s,
|
||||
},
|
||||
y: gfP2{
|
||||
x: %s,
|
||||
y: %s,
|
||||
},
|
||||
z: gfP2{
|
||||
x: %s,
|
||||
y: %s,
|
||||
},
|
||||
},
|
||||
y: gfP6{
|
||||
x: gfP2{
|
||||
x: %s,
|
||||
y: %s,
|
||||
},
|
||||
y: gfP2{
|
||||
x: %s,
|
||||
y: %s,
|
||||
},
|
||||
z: gfP2{
|
||||
x: %s,
|
||||
y: %s,
|
||||
},
|
||||
},
|
||||
}
|
||||
`, present(&e.x.x.x),
|
||||
present(&e.x.x.y),
|
||||
present(&e.x.y.x),
|
||||
present(&e.x.y.y),
|
||||
present(&e.x.z.x),
|
||||
present(&e.x.z.y),
|
||||
present(&e.y.x.x),
|
||||
present(&e.y.x.y),
|
||||
present(&e.y.y.x),
|
||||
present(&e.y.y.y),
|
||||
present(&e.y.z.x),
|
||||
present(&e.y.z.y))
|
||||
}
|
||||
Reference in New Issue
Block a user