Files
crypto/core/curves/native/bls12381/fp_test.go
T

347 lines
6.8 KiB
Go

//
// Copyright Coinbase, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
package bls12381
import (
crand "crypto/rand"
"math/big"
"math/rand"
"testing"
"github.com/stretchr/testify/require"
"github.com/sonr-io/sonr/crypto/internal"
)
func TestFpSetOne(t *testing.T) {
var fp fp
fp.SetOne()
require.NotNil(t, fp)
require.Equal(t, fp, r)
}
func TestFpSetUint64(t *testing.T) {
var act fp
act.SetUint64(1 << 60)
require.NotNil(t, act)
// Remember it will be in montgomery form
require.Equal(t, act[0], uint64(0xf6ea9fde37db5e8c))
}
func TestFpAdd(t *testing.T) {
var lhs, rhs, exp, res fp
lhs.SetOne()
rhs.SetOne()
exp.SetUint64(2)
res.Add(&lhs, &rhs)
require.NotNil(t, res)
require.Equal(t, 1, res.Equal(&exp))
// Fuzz test
for i := 0; i < 25; i++ {
// Divide by 4 to prevent overflow false errors
l := rand.Uint64() >> 2
r := rand.Uint64() >> 2
e := l + r
lhs.SetUint64(l)
rhs.SetUint64(r)
exp.SetUint64(e)
res.Add(&lhs, &rhs)
require.NotNil(t, res)
require.Equal(t, exp, res)
}
}
func TestFpSub(t *testing.T) {
var lhs, rhs, exp, res fp
lhs.SetOne()
rhs.SetOne()
exp.SetZero()
res.Sub(&lhs, &rhs)
require.NotNil(t, res)
require.Equal(t, 1, res.Equal(&exp))
// Fuzz test
for i := 0; i < 25; i++ {
// Divide by 4 to prevent overflow false errors
l := rand.Uint64() >> 2
r := rand.Uint64() >> 2
if l < r {
l, r = r, l
}
e := l - r
lhs.SetUint64(l)
rhs.SetUint64(r)
exp.SetUint64(e)
res.Sub(&lhs, &rhs)
require.NotNil(t, res)
require.Equal(t, exp, res)
}
}
func TestFpMul(t *testing.T) {
var lhs, rhs, exp, res fp
lhs.SetOne()
rhs.SetOne()
exp.SetOne()
res.Mul(&lhs, &rhs)
require.NotNil(t, res)
require.Equal(t, 1, res.Equal(&exp))
// Fuzz test
for i := 0; i < 25; i++ {
// Divide by 4 to prevent overflow false errors
l := rand.Uint32()
r := rand.Uint32()
e := uint64(l) * uint64(r)
lhs.SetUint64(uint64(l))
rhs.SetUint64(uint64(r))
exp.SetUint64(e)
res.Mul(&lhs, &rhs)
require.NotNil(t, res)
require.Equal(t, exp, res)
}
}
func TestFpDouble(t *testing.T) {
var a, e, res fp
a.SetUint64(2)
e.SetUint64(4)
require.Equal(t, &e, res.Double(&a))
for i := 0; i < 25; i++ {
tv := rand.Uint32()
ttv := uint64(tv) * 2
a.SetUint64(uint64(tv))
e.SetUint64(ttv)
require.Equal(t, &e, res.Double(&a))
}
}
func TestFpSquare(t *testing.T) {
var a, e, res fp
a.SetUint64(4)
e.SetUint64(16)
require.Equal(t, 1, e.Equal(res.Square(&a)))
a.SetUint64(2854263694)
e.SetUint64(8146821234886525636)
require.Equal(t, 1, e.Equal(res.Square(&a)))
for i := 0; i < 25; i++ {
j := rand.Uint32()
exp := uint64(j) * uint64(j)
e.SetUint64(exp)
a.SetUint64(uint64(j))
require.Equal(t, 1, e.Equal(res.Square(&a)), "exp = %d, j = %d", exp, j)
}
}
func TestFpNeg(t *testing.T) {
var g, a, e fp
g.SetLimbs(&[Limbs]uint64{7, 0, 0, 0, 0, 0})
a.SetOne()
a.Neg(&a)
e.SetRaw(
&[Limbs]uint64{
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x07e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x040ab3263eff0206,
},
)
require.Equal(t, 1, e.Equal(&a))
a.Neg(&g)
e.SetRaw(
&[Limbs]uint64{
0x21baffffffe90017,
0x445bffa5cba3ffed,
0xd028c5627db257bc,
0x14275ad5a2de0d96,
0x3e7434202365960e,
0x0249d4217f792796,
},
)
require.Equal(t, e, a)
}
func TestFpExp(t *testing.T) {
var a, e, by fp
e.SetUint64(8)
a.SetUint64(2)
by.SetUint64(3)
require.Equal(t, &e, a.Exp(&a, &by))
}
func TestFpSqrt(t *testing.T) {
var t1, t2, t3 fp
t1.SetUint64(2)
t2.Neg(&t1)
t3.Square(&t1)
_, wasSquare := t3.Sqrt(&t3)
require.Equal(t, 1, wasSquare)
require.Equal(t, 1, t1.Equal(&t3)|t2.Equal(&t3))
t1.SetUint64(5)
_, wasSquare = t1.Sqrt(&t1)
require.Equal(t, 0, wasSquare)
}
func TestFpInvert(t *testing.T) {
var two, twoInv, a, lhs, rhs, rhsInv fp
twoInv.SetRaw(
&[Limbs]uint64{
0x1804000000015554,
0x855000053ab00001,
0x633cb57c253c276f,
0x6e22d1ec31ebb502,
0xd3916126f2d14ca2,
0x17fbb8571a006596,
},
)
two.SetUint64(2)
_, inverted := a.Invert(&two)
require.Equal(t, 1, inverted)
require.Equal(t, &a, &twoInv)
lhs.SetUint64(9)
rhs.SetUint64(3)
_, inverted = rhsInv.Invert(&rhs)
require.Equal(t, 1, inverted)
require.Equal(t, &rhs, lhs.Mul(&lhs, &rhsInv))
rhs.SetZero()
_, inverted = lhs.Invert(&rhs)
require.Equal(t, 0, inverted)
}
func TestFpCMove(t *testing.T) {
var t1, t2, tt fp
t1.SetUint64(5)
t2.SetUint64(10)
require.Equal(t, &t1, tt.CMove(&t1, &t2, 0))
require.Equal(t, &t2, tt.CMove(&t1, &t2, 1))
}
func TestFpBytes(t *testing.T) {
var t1, t2 fp
t1.SetUint64(99)
seq := t1.Bytes()
_, suc := t2.SetBytes(&seq)
require.Equal(t, 1, suc)
require.Equal(t, t1, t2)
for i := 0; i < 25; i++ {
t1.SetUint64(rand.Uint64())
seq = t1.Bytes()
_, suc = t2.SetBytes(&seq)
require.Equal(t, 1, suc)
require.Equal(t, t1, t2)
}
}
func TestFpBigInt(t *testing.T) {
var t1, t2, e fp
t1.SetBigInt(big.NewInt(9999))
t2.SetBigInt(t1.BigInt())
require.Equal(t, t1, t2)
e.SetRaw(
&[Limbs]uint64{
0x922af810e5e35f31,
0x6bc75973ed382d59,
0xd4716c9d4d491d42,
0x69d98d1ebeeb3f6e,
0x7e425d7b46d4a82b,
0x12d04b0965870e92,
},
)
b := new(
big.Int,
).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9})
t1.SetBigInt(b)
require.Equal(t, e, t1)
e.Neg(&e)
b.Neg(b)
t1.SetBigInt(b)
require.Equal(t, e, t1)
}
func TestFpSetBytesWideBigInt(t *testing.T) {
var a fp
var tv2 [96]byte
for i := 0; i < 25; i++ {
_, _ = crand.Read(tv2[:])
e := new(big.Int).SetBytes(tv2[:])
e.Mod(e, biModulus)
tv := internal.ReverseScalarBytes(tv2[:])
copy(tv2[:], tv)
a.SetBytesWide(&tv2)
require.Equal(t, 0, e.Cmp(a.BigInt()))
}
}
func TestFpToMontgomery(t *testing.T) {
var v fp
v.SetUint64(2)
require.Equal(
t,
fp{
0x321300000006554f,
0xb93c0018d6c40005,
0x57605e0db0ddbb51,
0x8b256521ed1f9bcb,
0x6cf28d7901622c03,
0x11ebab9dbb81e28c,
},
v,
)
}
func TestFpFromMontgomery(t *testing.T) {
var v fp
e := fp{2, 0, 0, 0, 0, 0}
v.SetUint64(2)
v.fromMontgomery(&v)
require.Equal(t, e, v)
}
func TestFpLexicographicallyLargest(t *testing.T) {
require.Equal(t, 0, new(fp).SetZero().LexicographicallyLargest())
require.Equal(t, 0, new(fp).SetOne().LexicographicallyLargest())
require.Equal(t, 0, (&fp{
0xa1fafffffffe5557,
0x995bfff976a3fffe,
0x03f41d24d174ceb4,
0xf6547998c1995dbd,
0x778a468f507a6034,
0x020559931f7f8103,
}).LexicographicallyLargest())
require.Equal(t, 1, (&fp{
0x1804000000015554,
0x855000053ab00001,
0x633cb57c253c276f,
0x6e22d1ec31ebb502,
0xd3916126f2d14ca2,
0x17fbb8571a006596,
}).LexicographicallyLargest())
require.Equal(t, 1, (&fp{
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x07e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x040ab3263eff0206,
}).LexicographicallyLargest())
}