Files
crypto/core/curves/native/bls12381/g1_test.go

432 lines
11 KiB
Go

package bls12381
import (
crand "crypto/rand"
"encoding/hex"
"testing"
"github.com/stretchr/testify/require"
"github.com/sonr-io/crypto/core/curves/native"
)
func TestG1IsOnCurve(t *testing.T) {
require.Equal(t, 1, new(G1).Identity().IsOnCurve())
require.Equal(t, 1, new(G1).Generator().IsOnCurve())
z := fp{
0xba7afa1f9a6fe250,
0xfa0f5b595eafe731,
0x3bdc477694c306e7,
0x2149be4b3949fa24,
0x64aa6e0649b2078c,
0x12b108ac33643c3e,
}
gen := new(G1).Generator()
test := G1{
x: *(gen.x.Mul(&gen.x, &z)),
y: *(gen.y.Mul(&gen.y, &z)),
z: z,
}
require.Equal(t, 1, test.IsOnCurve())
test.x = z
require.Equal(t, 0, test.IsOnCurve())
}
func TestG1Equality(t *testing.T) {
a := new(G1).Generator()
b := new(G1).Identity()
require.Equal(t, 1, a.Equal(a))
require.Equal(t, 1, b.Equal(b))
require.Equal(t, 0, a.Equal(b))
require.Equal(t, 0, b.Equal(a))
z := fp{
0xba7afa1f9a6fe250,
0xfa0f5b595eafe731,
0x3bdc477694c306e7,
0x2149be4b3949fa24,
0x64aa6e0649b2078c,
0x12b108ac33643c3e,
}
c := G1{}
c.x.Mul(&a.x, &z)
c.y.Mul(&a.y, &z)
c.z.Set(&z)
require.Equal(t, 1, c.IsOnCurve())
require.Equal(t, 1, a.Equal(&c))
require.Equal(t, 0, b.Equal(&c))
c.y.Neg(&c.y)
require.Equal(t, 1, c.IsOnCurve())
require.Equal(t, 0, a.Equal(&c))
c.y.Neg(&c.y)
c.x.Set(&z)
require.Equal(t, 0, c.IsOnCurve())
}
func TestG1Double(t *testing.T) {
t0 := new(G1).Identity()
t0.Double(t0)
require.Equal(t, 1, t0.IsIdentity())
require.Equal(t, 1, t0.IsOnCurve())
t0.Double(t0.Generator())
require.Equal(t, 0, t0.IsIdentity())
require.Equal(t, 1, t0.IsOnCurve())
e := G1{
x: fp{
0x53e978ce58a9ba3c,
0x3ea0583c4f3d65f9,
0x4d20bb47f0012960,
0xa54c664ae5b2b5d9,
0x26b552a39d7eb21f,
0x0008895d26e68785,
},
y: fp{
0x70110b3298293940,
0xda33c5393f1f6afc,
0xb86edfd16a5aa785,
0xaec6d1c9e7b1c895,
0x25cfc2b522d11720,
0x06361c83f8d09b15,
},
z: r,
}
require.Equal(t, 1, e.Equal(t0))
}
func TestG1Add(t *testing.T) {
g := new(G1).Generator()
a := new(G1).Identity()
b := new(G1).Identity()
c := new(G1).Add(a, b)
require.Equal(t, 1, c.IsIdentity())
require.Equal(t, 1, c.IsOnCurve())
b.Generator()
z := fp{
0xba7afa1f9a6fe250,
0xfa0f5b595eafe731,
0x3bdc477694c306e7,
0x2149be4b3949fa24,
0x64aa6e0649b2078c,
0x12b108ac33643c3e,
}
b.x.Mul(&b.x, &z)
b.y.Mul(&b.y, &z)
b.z.Set(&z)
c.Add(a, b)
require.Equal(t, 0, c.IsIdentity())
require.Equal(t, 1, g.Equal(c))
a.Generator()
a.Double(a)
a.Double(a)
b.Generator()
b.Double(b)
c.Add(a, b)
d := new(G1).Generator()
for i := 0; i < 5; i++ {
d.Add(d, g)
}
require.Equal(t, 0, c.IsIdentity())
require.Equal(t, 1, c.IsOnCurve())
require.Equal(t, 0, d.IsIdentity())
require.Equal(t, 1, d.IsOnCurve())
require.Equal(t, 1, c.Equal(d))
beta := fp{
0xcd03c9e48671f071,
0x5dab22461fcda5d2,
0x587042afd3851b95,
0x8eb60ebe01bacb9e,
0x03f97d6e83d050d2,
0x18f0206554638741,
}
beta.Square(&beta)
a.Generator()
a.Double(a)
a.Double(a)
b.x.Mul(&a.x, &beta)
b.y.Neg(&a.y)
b.z.Set(&a.z)
require.Equal(t, 1, a.IsOnCurve())
require.Equal(t, 1, b.IsOnCurve())
c.Add(a, b)
d.x.Set(&fp{
0x29e1e987ef68f2d0,
0xc5f3ec531db03233,
0xacd6c4b6ca19730f,
0x18ad9e827bc2bab7,
0x46e3b2c5785cc7a9,
0x07e571d42d22ddd6,
})
d.y.Set(&fp{
0x94d117a7e5a539e7,
0x8e17ef673d4b5d22,
0x9d746aaf508a33ea,
0x8c6d883d2516c9a2,
0x0bc3b8d5fb0447f7,
0x07bfa4c7210f4f44,
})
d.z.SetOne()
require.Equal(t, 1, c.Equal(d))
}
func TestG1Sub(t *testing.T) {
a := new(G1).Generator()
b := new(G1).Generator()
require.Equal(t, 1, a.Sub(a, b).IsIdentity())
b.Double(b)
a.Generator()
require.Equal(t, 1, b.Sub(b, a).Equal(a))
}
func TestG1Mul(t *testing.T) {
g := new(G1).Generator()
a := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{
0x2b568297a56da71c,
0xd8c39ecb0ef375d1,
0x435c38da67bfbf96,
0x8088a05026b659b2,
})
b := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{
0x785fdd9b26ef8b85,
0xc997f25837695c18,
0x4c8dbc39e7b756c1,
0x70d9b6cc6d87df20,
})
c := Bls12381FqNew().Mul(a, b)
t1 := new(G1).Generator()
t1.Mul(t1, a)
t1.Mul(t1, b)
require.Equal(t, 1, t1.Equal(g.Mul(g, c)))
}
func TestG1Neg(t *testing.T) {
a := new(G1).Generator()
b := new(G1).Neg(a)
require.Equal(t, 1, new(G1).Add(a, b).IsIdentity())
require.Equal(t, 1, new(G1).Sub(a, b.Neg(b)).IsIdentity())
a.Identity()
require.Equal(t, 1, a.Neg(a).IsIdentity())
}
func TestG1InCorrectSubgroup(t *testing.T) {
// ZCash test vector
a := G1{
x: fp{
0x0abaf895b97e43c8,
0xba4c6432eb9b61b0,
0x12506f52adfe307f,
0x75028c3439336b72,
0x84744f05b8e9bd71,
0x113d554fb09554f7,
},
y: fp{
0x73e90e88f5cf01c0,
0x37007b65dd3197e2,
0x5cf9a1992f0d7c78,
0x4f83c10b9eb3330d,
0xf6a63f6f07f60961,
0x0c53b5b97e634df3,
},
z: *(new(fp).SetOne()),
}
require.Equal(t, 0, a.InCorrectSubgroup())
require.Equal(t, 1, new(G1).Identity().InCorrectSubgroup())
require.Equal(t, 1, new(G1).Generator().InCorrectSubgroup())
}
func TestG1MulByX(t *testing.T) {
// multiplying by `x` a point in G1 is the same as multiplying by
// the equivalent scalar.
generator := new(G1).Generator()
x := Bls12381FqNew().SetUint64(paramX)
x.Neg(x)
lhs := new(G1).Mul(generator, x)
rhs := new(G1).MulByX(generator)
require.Equal(t, 1, lhs.Equal(rhs))
pt := new(G1).Generator()
s := Bls12381FqNew().SetUint64(42)
pt.Mul(pt, s)
lhs.Mul(pt, x)
rhs.MulByX(pt)
require.Equal(t, 1, lhs.Equal(rhs))
}
func TestG1ClearCofactor(t *testing.T) {
// the generator (and the identity) are always on the curve,
// even after clearing the cofactor
generator := new(G1).Generator()
generator.ClearCofactor(generator)
require.Equal(t, 1, generator.IsOnCurve())
id := new(G1).Identity()
id.ClearCofactor(id)
require.Equal(t, 1, id.IsOnCurve())
z := fp{
0x3d2d1c670671394e,
0x0ee3a800a2f7c1ca,
0x270f4f21da2e5050,
0xe02840a53f1be768,
0x55debeb597512690,
0x08bd25353dc8f791,
}
point := G1{
x: fp{
0x48af5ff540c817f0,
0xd73893acaf379d5a,
0xe6c43584e18e023c,
0x1eda39c30f188b3e,
0xf618c6d3ccc0f8d8,
0x0073542cd671e16c,
},
y: fp{
0x57bf8be79461d0ba,
0xfc61459cee3547c3,
0x0d23567df1ef147b,
0x0ee187bcce1d9b64,
0xb0c8cfbe9dc8fdc1,
0x1328661767ef368b,
},
z: *(&fp{}).Set(&z),
}
point.x.Mul(&point.x, &z)
point.z.Square(&z)
point.z.Mul(&point.z, &z)
require.Equal(t, 1, point.IsOnCurve())
require.Equal(t, 0, point.InCorrectSubgroup())
clearedPoint := new(G1).ClearCofactor(&point)
require.Equal(t, 1, clearedPoint.IsOnCurve())
require.Equal(t, 1, clearedPoint.InCorrectSubgroup())
// in BLS12-381 the cofactor in G1 can be
// cleared multiplying by (1-x)
hEff := Bls12381FqNew().SetOne()
hEff.Add(hEff, Bls12381FqNew().SetUint64(paramX))
point.Mul(&point, hEff)
require.Equal(t, 1, clearedPoint.Equal(&point))
}
func TestG1Hash(t *testing.T) {
dst := []byte("QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_")
tests := []struct {
input, expected string
}{
{
"",
"052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a108ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265",
},
{
"abc",
"03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a7943388a49a3aee664ba5379a7655d3c68900be2f69030b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67af215533311f0b8dfaaa154fa6b88176c229f2885d",
},
{
"abcdef0123456789",
"11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d9803a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709",
},
{
"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
"15f68eaa693b95ccb85215dc65fa81038d69629f70aeee0d0f677cf22285e7bf58d7cb86eefe8f2e9bc3f8cb84fac4881807a1d50c29f430b8cafc4f8638dfeeadf51211e1602a5f184443076715f91bb90a48ba1e370edce6ae1062f5e6dd38",
},
{
"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"082aabae8b7dedb0e78aeb619ad3bfd9277a2f77ba7fad20ef6aabdc6c31d19ba5a6d12283553294c1825c4b3ca2dcfe05b84ae5a942248eea39e1d91030458c40153f3b654ab7872d779ad1e942856a20c438e8d99bc8abfbf74729ce1f7ac8",
},
}
pt := new(G1).Identity()
ept := new(G1).Identity()
var b [WideFieldBytes]byte
for _, tst := range tests {
i := []byte(tst.input)
e, _ := hex.DecodeString(tst.expected)
copy(b[:], e)
_, _ = ept.FromUncompressed(&b)
pt.Hash(native.EllipticPointHasherSha256(), i, dst)
require.Equal(t, 1, pt.Equal(ept))
}
}
func TestSerialization(t *testing.T) {
a := new(
G1,
).Hash(native.EllipticPointHasherSha256(), []byte("a"), []byte("BLS12381G1_XMD:SHA-256_SSWU_RO_"))
b := new(
G1,
).Hash(native.EllipticPointHasherSha256(), []byte("b"), []byte("BLS12381G1_XMD:SHA-256_SSWU_RO_"))
aBytes := a.ToCompressed()
bBytes := b.ToCompressed()
aa, err := new(G1).FromCompressed(&aBytes)
require.NoError(t, err)
require.Equal(t, 1, a.Equal(aa))
bb, err := new(G1).FromCompressed(&bBytes)
require.NoError(t, err)
require.Equal(t, 1, b.Equal(bb))
auBytes := a.ToUncompressed()
buBytes := b.ToUncompressed()
_, err = aa.FromUncompressed(&auBytes)
require.NoError(t, err)
require.Equal(t, 1, a.Equal(aa))
_, err = bb.FromUncompressed(&buBytes)
require.NoError(t, err)
require.Equal(t, 1, b.Equal(bb))
bBytes = a.ToCompressed()
a.Neg(a)
aBytes = a.ToCompressed()
_, err = aa.FromCompressed(&aBytes)
require.NoError(t, err)
require.Equal(t, 1, a.Equal(aa))
_, err = aa.FromCompressed(&bBytes)
require.NoError(t, err)
require.Equal(t, 0, a.Equal(aa))
require.Equal(t, 1, aa.Equal(a.Neg(a)))
}
func TestSumOfProducts(t *testing.T) {
var b [64]byte
h0, _ := new(G1).Random(crand.Reader)
_, _ = crand.Read(b[:])
s := Bls12381FqNew().SetBytesWide(&b)
_, _ = crand.Read(b[:])
sTilde := Bls12381FqNew().SetBytesWide(&b)
_, _ = crand.Read(b[:])
c := Bls12381FqNew().SetBytesWide(&b)
lhs := new(G1).Mul(h0, s)
rhs, _ := new(G1).SumOfProducts([]*G1{h0}, []*native.Field{s})
require.Equal(t, 1, lhs.Equal(rhs))
u := new(G1).Mul(h0, s)
uTilde := new(G1).Mul(h0, sTilde)
sHat := Bls12381FqNew().Mul(c, s)
sHat.Sub(sTilde, sHat)
rhs.Mul(u, c)
rhs.Add(rhs, new(G1).Mul(h0, sHat))
require.Equal(t, 1, uTilde.Equal(rhs))
_, _ = rhs.SumOfProducts([]*G1{u, h0}, []*native.Field{c, sHat})
require.Equal(t, 1, uTilde.Equal(rhs))
}