|
|
package blindsecp256k1
import ( "encoding/hex" "math/big" "testing"
"github.com/btcsuite/btcd/btcec" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" )
// TODO abstract the test to work with any curve, and be
// called from a test that testes all the tests with the
// main curves
func TestFlow(t *testing.T) { curv := btcec.S256() // signer: create new signer key pair
sk := NewPrivateKey(curv) signerPubK := sk.Public(curv)
// signer: when user requests new R parameter to blind a new msg,
// create new signerR (public) with its secret k
k, signerR := NewRequestParameters(curv)
// user: blinds the msg using signer's R
msg := new(big.Int).SetBytes([]byte("test")) msgBlinded, userSecretData, err := Blind(curv, msg, signerR) require.Nil(t, err)
// signer: signs the blinded message using its private key & secret k
sBlind, err := sk.BlindSign(curv, msgBlinded, k) require.Nil(t, err)
// user: unblinds the blinded signature
sig := Unblind(curv, sBlind, userSecretData) sigB := sig.Bytes() sig2, err := NewSignatureFromBytes(sigB) assert.Nil(t, err) assert.Equal(t, sig, sig2)
// signature can be verified with signer PublicKey
verified := Verify(curv, msg, sig, signerPubK) assert.True(t, verified) }
func TestHashMOddBytes(t *testing.T) { // This test is made with same values than
// https://github.com/arnaucube/blindsecp256k1-js to ensure
// compatibility
mStr := "3024162961766929396601888431330224482373544644288322432261208139289299439809" m, ok := new(big.Int).SetString(mStr, 10) require.True(t, ok) mBytes := m.Bytes()
hBytes := crypto.Keccak256(mBytes[3:]) h := new(big.Int).SetBytes(hBytes) assert.Equal(t, "57523339312508913023232057765773019244858443678197951618720342803494056599369", h.String())
hBytes = crypto.Keccak256(append(mBytes, []byte{0x12, 0x34}...)) h = new(big.Int).SetBytes(hBytes) assert.Equal(t, "9697834584560956691445940439424778243200861871421750951058436814122640359156", h.String()) }
// func newBigIntWithBitLen(n int) *big.Int {
// b := make([]byte, n/8)
// for i := 0; i < len(b); i++ {
// b[i] = 255
// }
// bi := new(big.Int).SetBytes(b[:])
// return bi
// }
//
// func TestMinBigIntBytesLen(t *testing.T) {
// k := big.NewInt(1)
// sk := PrivateKey(*k)
//
// mBlinded := newBigIntWithBitLen(MinBigIntBytesLen)
// require.Equal(t, MinBigIntBytesLen, mBlinded.BitLen())
// _, err := sk.BlindSign(mBlinded, k)
// assert.Nil(t, err)
//
// mBlinded = new(big.Int).Div(mBlinded, big.NewInt(2))
// require.Equal(t, MinBigIntBytesLen-1, mBlinded.BitLen())
// _, err = sk.BlindSign(mBlinded, k)
// assert.Equal(t, "mBlinded too small", err.Error())
// }
func TestPointCompressDecompress(t *testing.T) { curv := btcec.S256() c := Curve{curv}
G := &Point{ X: curv.Gx, Y: curv.Gy, } p := &Point{ X: curv.Gx, Y: curv.Gy, } b := p.Compress() assert.Equal(t, "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800", hex.EncodeToString(b[:])) p2, err := DecompressPoint(curv, b) require.Nil(t, err) assert.Equal(t, p, p2)
for i := 2; i < 1000; i++ { p := c.Mul(G, big.NewInt(int64(i))) b := p.Compress() assert.Equal(t, 33, len(b))
p2, err := DecompressPoint(curv, b) require.Nil(t, err) assert.Equal(t, p, p2) } }
func TestSignatureCompressDecompress(t *testing.T) { curv := btcec.S256() c := Curve{curv}
G := &Point{ X: curv.Gx, Y: curv.Gy, } f := G sig := &Signature{ S: big.NewInt(1), F: f, } b := sig.Compress() assert.Equal(t, "01000000000000000000000000000000000000000000000000000000000000007"+ "9be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800", hex.EncodeToString(b[:])) sig2, err := DecompressSignature(curv, b) require.Nil(t, err) assert.Equal(t, sig, sig2)
f = G P := curv.Params().P // Q = (P+1)/4
Q := new(big.Int).Div(new(big.Int).Add(P, big.NewInt(1)), big.NewInt(4)) // nolint:gomnd
sig = &Signature{ S: Q, F: f, } b = sig.Compress() assert.Equal(t, "0cffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff3f7"+ "9be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800", hex.EncodeToString(b[:])) sig2, err = DecompressSignature(curv, b) require.Nil(t, err) require.Equal(t, sig, sig2)
for i := 2; i < 10; i++ { s := new(big.Int).Mod(new(big.Int).Mul(Q, big.NewInt(int64(i))), P) f := c.Mul(G, big.NewInt(int64(i))) sig := &Signature{ S: s, F: f, } b := sig.Compress() assert.Equal(t, 65, len(b))
sig2, err := DecompressSignature(curv, b) require.Nil(t, err) assert.Equal(t, sig, sig2) } }
func BenchmarkCompressDecompress(b *testing.B) { curv := btcec.S256() c := Curve{curv}
const n = 256 var points [n]*Point var compPoints [n][33]byte G := &Point{ X: curv.Gx, Y: curv.Gy, }
for i := 0; i < n; i++ { points[i] = c.Mul(G, big.NewInt(int64(i))) } for i := 0; i < n; i++ { compPoints[i] = points[i].Compress() }
b.Run("Compress", func(b *testing.B) { for i := 0; i < b.N; i++ { _ = points[i%n].Compress() } }) b.Run("DecompressPoint", func(b *testing.B) { for i := 0; i < b.N; i++ { _, _ = DecompressPoint(curv, compPoints[i%n]) } }) }
|