* core/vm, crypto/bn256: switch over to cloudflare library * crypto/bn256: unmarshal constraint + start pure go impl * crypto/bn256: combo cloudflare and google lib * travis: drop 386 test job
		
			
				
	
	
		
			157 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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.
 | |
| 
 | |
| // gfP2 implements a field of size p² as a quadratic extension of the base field
 | |
| // where i²=-1.
 | |
| type gfP2 struct {
 | |
| 	x, y gfP // value is xi+y.
 | |
| }
 | |
| 
 | |
| func gfP2Decode(in *gfP2) *gfP2 {
 | |
| 	out := &gfP2{}
 | |
| 	montDecode(&out.x, &in.x)
 | |
| 	montDecode(&out.y, &in.y)
 | |
| 	return out
 | |
| }
 | |
| 
 | |
| func (e *gfP2) String() string {
 | |
| 	return "(" + e.x.String() + ", " + e.y.String() + ")"
 | |
| }
 | |
| 
 | |
| 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 = gfP{0}
 | |
| 	e.y = gfP{0}
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) SetOne() *gfP2 {
 | |
| 	e.x = gfP{0}
 | |
| 	e.y = *newGFp(1)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) IsZero() bool {
 | |
| 	zero := gfP{0}
 | |
| 	return e.x == zero && e.y == zero
 | |
| }
 | |
| 
 | |
| func (e *gfP2) IsOne() bool {
 | |
| 	zero, one := gfP{0}, *newGFp(1)
 | |
| 	return e.x == zero && e.y == one
 | |
| }
 | |
| 
 | |
| func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
 | |
| 	e.y.Set(&a.y)
 | |
| 	gfpNeg(&e.x, &a.x)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) Neg(a *gfP2) *gfP2 {
 | |
| 	gfpNeg(&e.x, &a.x)
 | |
| 	gfpNeg(&e.y, &a.y)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) Add(a, b *gfP2) *gfP2 {
 | |
| 	gfpAdd(&e.x, &a.x, &b.x)
 | |
| 	gfpAdd(&e.y, &a.y, &b.y)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
 | |
| 	gfpSub(&e.x, &a.x, &b.x)
 | |
| 	gfpSub(&e.y, &a.y, &b.y)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| // See "Multiplication and Squaring in Pairing-Friendly Fields",
 | |
| // http://eprint.iacr.org/2006/471.pdf
 | |
| func (e *gfP2) Mul(a, b *gfP2) *gfP2 {
 | |
| 	tx, t := &gfP{}, &gfP{}
 | |
| 	gfpMul(tx, &a.x, &b.y)
 | |
| 	gfpMul(t, &b.x, &a.y)
 | |
| 	gfpAdd(tx, tx, t)
 | |
| 
 | |
| 	ty := &gfP{}
 | |
| 	gfpMul(ty, &a.y, &b.y)
 | |
| 	gfpMul(t, &a.x, &b.x)
 | |
| 	gfpSub(ty, ty, t)
 | |
| 
 | |
| 	e.x.Set(tx)
 | |
| 	e.y.Set(ty)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 {
 | |
| 	gfpMul(&e.x, &a.x, b)
 | |
| 	gfpMul(&e.y, &a.y, b)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| // MulXi sets e=ξa where ξ=i+9 and then returns e.
 | |
| func (e *gfP2) MulXi(a *gfP2) *gfP2 {
 | |
| 	// (xi+y)(i+9) = (9x+y)i+(9y-x)
 | |
| 	tx := &gfP{}
 | |
| 	gfpAdd(tx, &a.x, &a.x)
 | |
| 	gfpAdd(tx, tx, tx)
 | |
| 	gfpAdd(tx, tx, tx)
 | |
| 	gfpAdd(tx, tx, &a.x)
 | |
| 
 | |
| 	gfpAdd(tx, tx, &a.y)
 | |
| 
 | |
| 	ty := &gfP{}
 | |
| 	gfpAdd(ty, &a.y, &a.y)
 | |
| 	gfpAdd(ty, ty, ty)
 | |
| 	gfpAdd(ty, ty, ty)
 | |
| 	gfpAdd(ty, ty, &a.y)
 | |
| 
 | |
| 	gfpSub(ty, ty, &a.x)
 | |
| 
 | |
| 	e.x.Set(tx)
 | |
| 	e.y.Set(ty)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) Square(a *gfP2) *gfP2 {
 | |
| 	// Complex squaring algorithm:
 | |
| 	// (xi+y)² = (x+y)(y-x) + 2*i*x*y
 | |
| 	tx, ty := &gfP{}, &gfP{}
 | |
| 	gfpSub(tx, &a.y, &a.x)
 | |
| 	gfpAdd(ty, &a.x, &a.y)
 | |
| 	gfpMul(ty, tx, ty)
 | |
| 
 | |
| 	gfpMul(tx, &a.x, &a.y)
 | |
| 	gfpAdd(tx, tx, tx)
 | |
| 
 | |
| 	e.x.Set(tx)
 | |
| 	e.y.Set(ty)
 | |
| 	return e
 | |
| }
 | |
| 
 | |
| func (e *gfP2) Invert(a *gfP2) *gfP2 {
 | |
| 	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
 | |
| 	// ftp://136.206.11.249/pub/crypto/pairings.pdf
 | |
| 	t1, t2 := &gfP{}, &gfP{}
 | |
| 	gfpMul(t1, &a.x, &a.x)
 | |
| 	gfpMul(t2, &a.y, &a.y)
 | |
| 	gfpAdd(t1, t1, t2)
 | |
| 
 | |
| 	inv := &gfP{}
 | |
| 	inv.Invert(t1)
 | |
| 
 | |
| 	gfpNeg(t1, &a.x)
 | |
| 
 | |
| 	gfpMul(&e.x, t1, inv)
 | |
| 	gfpMul(&e.y, &a.y, inv)
 | |
| 	return e
 | |
| }
 |