native: allow to use EQUAL opcode for BLS12-381 points comparison
That's the way how C# node handles equality checks for stackitem.Interop types for these points. Ref. https://github.com/nspcc-dev/neo-go/issues/3002#issuecomment-1591220501. Along the way, add GT case for CryptoLib's bls12381Equal method. It should be there since #2940. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
parent
a2daad6ba6
commit
71bcb8bade
5 changed files with 275 additions and 109 deletions
|
@ -178,32 +178,11 @@ func curveFromStackitem(si stackitem.Item) (elliptic.Curve, error) {
|
|||
}
|
||||
|
||||
func (c *Crypto) bls12381Serialize(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
val := args[0].(*stackitem.Interop).Value()
|
||||
var res []byte
|
||||
switch p := val.(type) {
|
||||
case *bls12381.G1Affine:
|
||||
compressed := p.Bytes()
|
||||
res = compressed[:]
|
||||
case *bls12381.G1Jac:
|
||||
g1Affine := new(bls12381.G1Affine)
|
||||
g1Affine.FromJacobian(p)
|
||||
compressed := g1Affine.Bytes()
|
||||
res = compressed[:]
|
||||
case *bls12381.G2Affine:
|
||||
compressed := p.Bytes()
|
||||
res = compressed[:]
|
||||
case *bls12381.G2Jac:
|
||||
g2Affine := new(bls12381.G2Affine)
|
||||
g2Affine.FromJacobian(p)
|
||||
compressed := g2Affine.Bytes()
|
||||
res = compressed[:]
|
||||
case *bls12381.GT:
|
||||
compressed := p.Bytes()
|
||||
res = compressed[:]
|
||||
default:
|
||||
panic(errors.New("unknown bls12381 point type"))
|
||||
val, ok := args[0].(*stackitem.Interop).Value().(blsPoint)
|
||||
if !ok {
|
||||
panic(errors.New("not a bls12381 point"))
|
||||
}
|
||||
return stackitem.NewByteArray(res)
|
||||
return stackitem.NewByteArray(val.Bytes())
|
||||
}
|
||||
|
||||
func (c *Crypto) bls12381Deserialize(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
|
@ -235,51 +214,32 @@ func (c *Crypto) bls12381Deserialize(_ *interop.Context, args []stackitem.Item)
|
|||
}
|
||||
res = gt
|
||||
}
|
||||
return stackitem.NewInterop(res)
|
||||
return stackitem.NewInterop(blsPoint{point: res})
|
||||
}
|
||||
|
||||
func (c *Crypto) bls12381Equal(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
a := args[0].(*stackitem.Interop).Value()
|
||||
b := args[1].(*stackitem.Interop).Value()
|
||||
var res bool
|
||||
switch x := a.(type) {
|
||||
case *bls12381.G1Affine:
|
||||
y, ok := b.(*bls12381.G1Affine)
|
||||
if !ok {
|
||||
panic(errors.New("y is not bls12381 G1Affine point"))
|
||||
}
|
||||
res = x.Equal(y)
|
||||
case *bls12381.G1Jac:
|
||||
y, ok := b.(*bls12381.G1Jac)
|
||||
if !ok {
|
||||
panic(errors.New("y is not bls12381 G1Jac point"))
|
||||
}
|
||||
res = x.Equal(y)
|
||||
case *bls12381.G2Affine:
|
||||
y, ok := b.(*bls12381.G2Affine)
|
||||
if !ok {
|
||||
panic(errors.New("y is not bls12381 G2Affine point"))
|
||||
}
|
||||
res = x.Equal(y)
|
||||
case *bls12381.G2Jac:
|
||||
y, ok := b.(*bls12381.G2Jac)
|
||||
if !ok {
|
||||
panic(errors.New("y is not bls12381 G2Jac point"))
|
||||
}
|
||||
res = x.Equal(y)
|
||||
default:
|
||||
panic(fmt.Errorf("unexpected x bls12381 point type: %T", x))
|
||||
a, okA := args[0].(*stackitem.Interop).Value().(blsPoint)
|
||||
b, okB := args[1].(*stackitem.Interop).Value().(blsPoint)
|
||||
if !(okA && okB) {
|
||||
panic("some of the arguments are not a bls12381 point")
|
||||
}
|
||||
res, err := a.EqualsCheckType(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return stackitem.NewBool(res)
|
||||
}
|
||||
|
||||
func (c *Crypto) bls12381Add(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
a := args[0].(*stackitem.Interop).Value()
|
||||
b := args[1].(*stackitem.Interop).Value()
|
||||
a, okA := args[0].(*stackitem.Interop).Value().(blsPoint)
|
||||
b, okB := args[1].(*stackitem.Interop).Value().(blsPoint)
|
||||
if !(okA && okB) {
|
||||
panic("some of the arguments are not a bls12381 point")
|
||||
}
|
||||
var res interface{}
|
||||
switch x := a.(type) {
|
||||
switch x := a.point.(type) {
|
||||
case *bls12381.G1Affine:
|
||||
switch y := b.(type) {
|
||||
switch y := b.point.(type) {
|
||||
case *bls12381.G1Affine:
|
||||
xJac := new(bls12381.G1Jac)
|
||||
xJac.FromAffine(x)
|
||||
|
@ -296,7 +256,7 @@ func (c *Crypto) bls12381Add(_ *interop.Context, args []stackitem.Item) stackite
|
|||
case *bls12381.G1Jac:
|
||||
resJac := new(bls12381.G1Jac)
|
||||
resJac.Set(x)
|
||||
switch y := b.(type) {
|
||||
switch y := b.point.(type) {
|
||||
case *bls12381.G1Affine:
|
||||
resJac.AddMixed(y)
|
||||
case *bls12381.G1Jac:
|
||||
|
@ -306,7 +266,7 @@ func (c *Crypto) bls12381Add(_ *interop.Context, args []stackitem.Item) stackite
|
|||
}
|
||||
res = resJac
|
||||
case *bls12381.G2Affine:
|
||||
switch y := b.(type) {
|
||||
switch y := b.point.(type) {
|
||||
case *bls12381.G2Affine:
|
||||
xJac := new(bls12381.G2Jac)
|
||||
xJac.FromAffine(x)
|
||||
|
@ -323,7 +283,7 @@ func (c *Crypto) bls12381Add(_ *interop.Context, args []stackitem.Item) stackite
|
|||
case *bls12381.G2Jac:
|
||||
resJac := new(bls12381.G2Jac)
|
||||
resJac.Set(x)
|
||||
switch y := b.(type) {
|
||||
switch y := b.point.(type) {
|
||||
case *bls12381.G2Affine:
|
||||
resJac.AddMixed(y)
|
||||
case *bls12381.G2Jac:
|
||||
|
@ -335,7 +295,7 @@ func (c *Crypto) bls12381Add(_ *interop.Context, args []stackitem.Item) stackite
|
|||
case *bls12381.GT:
|
||||
resGT := new(bls12381.GT)
|
||||
resGT.Set(x)
|
||||
switch y := b.(type) {
|
||||
switch y := b.point.(type) {
|
||||
case *bls12381.GT:
|
||||
// It's multiplication, see https://github.com/neo-project/Neo.Cryptography.BLS12_381/issues/4.
|
||||
resGT.Mul(x, y)
|
||||
|
@ -346,7 +306,7 @@ func (c *Crypto) bls12381Add(_ *interop.Context, args []stackitem.Item) stackite
|
|||
default:
|
||||
panic(fmt.Errorf("unexpected bls12381 point type: %T", x))
|
||||
}
|
||||
return stackitem.NewInterop(res)
|
||||
return stackitem.NewInterop(blsPoint{point: res})
|
||||
}
|
||||
|
||||
func scalarFromBytes(bytes []byte, neg bool) (*fr.Element, error) {
|
||||
|
@ -368,7 +328,10 @@ func scalarFromBytes(bytes []byte, neg bool) (*fr.Element, error) {
|
|||
}
|
||||
|
||||
func (c *Crypto) bls12381Mul(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
a := args[0].(*stackitem.Interop).Value()
|
||||
a, okA := args[0].(*stackitem.Interop).Value().(blsPoint)
|
||||
if !okA {
|
||||
panic("multiplier is not a bls12381 point")
|
||||
}
|
||||
mulBytes, err := args[1].TryBytes()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("invalid multiplier: %w", err))
|
||||
|
@ -385,7 +348,7 @@ func (c *Crypto) bls12381Mul(_ *interop.Context, args []stackitem.Item) stackite
|
|||
alpha.BigInt(alphaBi)
|
||||
|
||||
var res interface{}
|
||||
switch x := a.(type) {
|
||||
switch x := a.point.(type) {
|
||||
case *bls12381.G1Affine:
|
||||
// The result is in Jacobian form in the reference implementation.
|
||||
g1Jac := new(bls12381.G1Jac)
|
||||
|
@ -423,17 +386,20 @@ func (c *Crypto) bls12381Mul(_ *interop.Context, args []stackitem.Item) stackite
|
|||
default:
|
||||
panic(fmt.Errorf("unexpected bls12381 point type: %T", x))
|
||||
}
|
||||
return stackitem.NewInterop(res)
|
||||
return stackitem.NewInterop(blsPoint{point: res})
|
||||
}
|
||||
|
||||
func (c *Crypto) bls12381Pairing(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
a := args[0].(*stackitem.Interop).Value()
|
||||
b := args[1].(*stackitem.Interop).Value()
|
||||
a, okA := args[0].(*stackitem.Interop).Value().(blsPoint)
|
||||
b, okB := args[1].(*stackitem.Interop).Value().(blsPoint)
|
||||
if !(okA && okB) {
|
||||
panic("some of the arguments are not a bls12381 point")
|
||||
}
|
||||
var (
|
||||
x *bls12381.G1Affine
|
||||
y *bls12381.G2Affine
|
||||
)
|
||||
switch p := a.(type) {
|
||||
switch p := a.point.(type) {
|
||||
case *bls12381.G1Affine:
|
||||
x = p
|
||||
case *bls12381.G1Jac:
|
||||
|
@ -442,7 +408,7 @@ func (c *Crypto) bls12381Pairing(_ *interop.Context, args []stackitem.Item) stac
|
|||
default:
|
||||
panic(fmt.Errorf("unexpected bls12381 point type (g1): %T", x))
|
||||
}
|
||||
switch p := b.(type) {
|
||||
switch p := b.point.(type) {
|
||||
case *bls12381.G2Affine:
|
||||
y = p
|
||||
case *bls12381.G2Jac:
|
||||
|
@ -455,7 +421,7 @@ func (c *Crypto) bls12381Pairing(_ *interop.Context, args []stackitem.Item) stac
|
|||
if err != nil {
|
||||
panic(fmt.Errorf("failed to perform pairing operation"))
|
||||
}
|
||||
return stackitem.NewInterop(interface{}(>))
|
||||
return stackitem.NewInterop(blsPoint{>})
|
||||
}
|
||||
|
||||
// Metadata implements the Contract interface.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue