arnaucube
arnaucube/go-blindsecp256k1Public Self-hosted repository
go-blindsecp256k1/blindsecp256k1_test.go
blindsecp256k1_test.goRaw
  1package blindsecp256k1
  2
  3import (
  4	"encoding/hex"
  5	"math/big"
  6	"testing"
  7
  8	"github.com/ethereum/go-ethereum/crypto"
  9	"github.com/stretchr/testify/assert"
 10	"github.com/stretchr/testify/require"
 11)
 12
 13func TestFlow(t *testing.T) {
 14	// signer: create new signer key pair
 15	sk, err := NewPrivateKey()
 16	require.Nil(t, err)
 17	signerPubK := sk.Public()
 18
 19	// signer: when user requests new R parameter to blind a new msg,
 20	// create new signerR (public) with its secret k
 21	k, signerR, err := NewRequestParameters()
 22	require.Nil(t, err)
 23
 24	// user: blinds the msg using signer's R
 25	// msg := new(big.Int).SetBytes([]byte("test"))
 26	msg := new(big.Int).SetBytes(crypto.Keccak256([]byte("test")))
 27	msgBlinded, userSecretData, err := Blind(msg, signerR)
 28	require.Nil(t, err)
 29
 30	// signer: signs the blinded message using its private key & secret k
 31	sBlind, err := sk.BlindSign(msgBlinded, k)
 32	require.Nil(t, err)
 33
 34	// user: unblinds the blinded signature
 35	sig := Unblind(sBlind, userSecretData)
 36	sigB := sig.Bytes()
 37	sig2, err := NewSignatureFromBytes(sigB)
 38	assert.Nil(t, err)
 39	assert.Equal(t, sig, sig2)
 40
 41	// signature can be verified with signer PublicKey
 42	verified := Verify(msg, sig, signerPubK)
 43	assert.True(t, verified)
 44}
 45
 46func TestSmallBlindedMsg(t *testing.T) {
 47	sk, err := NewPrivateKey()
 48	require.Nil(t, err)
 49	k := big.NewInt(1)
 50	smallMsgBlinded := big.NewInt(1)
 51
 52	// try to BlindSign a small value
 53	_, err = sk.BlindSign(smallMsgBlinded, k)
 54	require.NotNil(t, err)
 55	require.Equal(t, "mBlinded error: invalid length, need 32 bytes", err.Error())
 56}
 57
 58func TestHashMOddBytes(t *testing.T) {
 59	// This test is made with same values than
 60	// https://github.com/arnaucube/blindsecp256k1-js to ensure
 61	// compatibility
 62	mStr := "3024162961766929396601888431330224482373544644288322432261208139289299439809"
 63	m, ok := new(big.Int).SetString(mStr, 10)
 64	require.True(t, ok)
 65	mBytes := m.Bytes()
 66
 67	hBytes := crypto.Keccak256(mBytes[3:])
 68	h := new(big.Int).SetBytes(hBytes)
 69	assert.Equal(t,
 70		"57523339312508913023232057765773019244858443678197951618720342803494056599369",
 71		h.String())
 72
 73	hBytes = crypto.Keccak256(append(mBytes, []byte{0x12, 0x34}...))
 74	h = new(big.Int).SetBytes(hBytes)
 75	assert.Equal(t,
 76		"9697834584560956691445940439424778243200861871421750951058436814122640359156",
 77		h.String())
 78}
 79
 80// func newBigIntWithBitLen(n int) *big.Int {
 81//         b := make([]byte, n/8)
 82//         for i := 0; i < len(b); i++ {
 83//                 b[i] = 255
 84//         }
 85//         bi := new(big.Int).SetBytes(b[:])
 86//         return bi
 87// }
 88//
 89// func TestMinBigIntBytesLen(t *testing.T) {
 90//         k := big.NewInt(1)
 91//         sk := PrivateKey(*k)
 92//
 93//         mBlinded := newBigIntWithBitLen(MinBigIntBytesLen)
 94//         require.Equal(t, MinBigIntBytesLen, mBlinded.BitLen())
 95//         _, err := sk.BlindSign(mBlinded, k)
 96//         assert.Nil(t, err)
 97//
 98//         mBlinded = new(big.Int).Div(mBlinded, big.NewInt(2))
 99//         require.Equal(t, MinBigIntBytesLen-1, mBlinded.BitLen())
100//         _, err = sk.BlindSign(mBlinded, k)
101//         assert.Equal(t, "mBlinded too small", err.Error())
102// }
103
104func TestPointCompressDecompress(t *testing.T) {
105	p := G
106	b := p.Compress()
107	assert.Equal(t,
108		"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800",
109		hex.EncodeToString(b[:]))
110	p2, err := DecompressPoint(b)
111	require.Nil(t, err)
112	assert.Equal(t, p, p2)
113
114	for i := 2; i < 1000; i++ {
115		p := G.Mul(big.NewInt(int64(i)))
116		b := p.Compress()
117		assert.Equal(t, 33, len(b))
118
119		p2, err := DecompressPoint(b)
120		require.Nil(t, err)
121		assert.Equal(t, p, p2)
122	}
123}
124
125func TestSignatureCompressDecompress(t *testing.T) {
126	f := G
127	sig := &Signature{
128		S: big.NewInt(1),
129		F: f,
130	}
131	b := sig.Compress()
132	assert.Equal(t,
133		"01000000000000000000000000000000000000000000000000000000000000007"+
134			"9be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800",
135		hex.EncodeToString(b[:]))
136	sig2, err := DecompressSignature(b)
137	require.Nil(t, err)
138	assert.Equal(t, sig, sig2)
139
140	// Q = (P+1)/4
141	Q := new(big.Int).Div(new(big.Int).Add(P,
142		big.NewInt(1)), big.NewInt(4)) // nolint:gomnd
143	f = G
144
145	sig = &Signature{
146		S: Q,
147		F: f,
148	}
149	b = sig.Compress()
150	assert.Equal(t,
151		"0cffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff3f7"+
152			"9be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800",
153		hex.EncodeToString(b[:]))
154	sig2, err = DecompressSignature(b)
155	require.Nil(t, err)
156	require.Equal(t, sig, sig2)
157
158	for i := 2; i < 10; i++ {
159		s := new(big.Int).Mod(new(big.Int).Mul(Q, big.NewInt(int64(i))), P)
160		f := G.Mul(big.NewInt(int64(i)))
161		sig := &Signature{
162			S: s,
163			F: f,
164		}
165		b := sig.Compress()
166		assert.Equal(t, 65, len(b))
167
168		sig2, err := DecompressSignature(b)
169		require.Nil(t, err)
170		assert.Equal(t, sig, sig2)
171	}
172}
173
174func BenchmarkCompressDecompress(b *testing.B) {
175	const n = 256
176	var points [n]*Point
177	var compPoints [n][33]byte
178
179	for i := 0; i < n; i++ {
180		points[i] = G.Mul(big.NewInt(int64(i)))
181	}
182	for i := 0; i < n; i++ {
183		compPoints[i] = points[i].Compress()
184	}
185
186	b.Run("Compress", func(b *testing.B) {
187		for i := 0; i < b.N; i++ {
188			_ = points[i%n].Compress()
189		}
190	})
191	b.Run("DecompressPoint", func(b *testing.B) {
192		for i := 0; i < b.N; i++ {
193			_, _ = DecompressPoint(compPoints[i%n])
194		}
195	})
196}