// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dsa

import (
	"crypto/rand"
	"math/big"
	"testing"
)

func testSignAndVerify(t *testing.T, i int, priv *PrivateKey) {
	hashed := []byte("testing")
	r, s, err := Sign(rand.Reader, priv, hashed)
	if err != nil {
		t.Errorf("%d: error signing: %s", i, err)
		return
	}

	if !Verify(&priv.PublicKey, hashed, r, s) {
		t.Errorf("%d: Verify failed", i)
	}
}

func testParameterGeneration(t *testing.T, sizes ParameterSizes, L, N int) {
	var priv PrivateKey
	params := &priv.Parameters

	err := GenerateParameters(params, rand.Reader, sizes)
	if err != nil {
		t.Errorf("%d: %s", int(sizes), err)
		return
	}

	if params.P.BitLen() != L {
		t.Errorf("%d: params.BitLen got:%d want:%d", int(sizes), params.P.BitLen(), L)
	}

	if params.Q.BitLen() != N {
		t.Errorf("%d: q.BitLen got:%d want:%d", int(sizes), params.Q.BitLen(), L)
	}

	one := new(big.Int)
	one.SetInt64(1)
	pm1 := new(big.Int).Sub(params.P, one)
	quo, rem := new(big.Int).DivMod(pm1, params.Q, new(big.Int))
	if rem.Sign() != 0 {
		t.Errorf("%d: p-1 mod q != 0", int(sizes))
	}
	x := new(big.Int).Exp(params.G, quo, params.P)
	if x.Cmp(one) == 0 {
		t.Errorf("%d: invalid generator", int(sizes))
	}

	err = GenerateKey(&priv, rand.Reader)
	if err != nil {
		t.Errorf("error generating key: %s", err)
		return
	}

	testSignAndVerify(t, int(sizes), &priv)
}

func TestParameterGeneration(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping parameter generation test in short mode")
	}

	testParameterGeneration(t, L1024N160, 1024, 160)
	testParameterGeneration(t, L2048N224, 2048, 224)
	testParameterGeneration(t, L2048N256, 2048, 256)
	testParameterGeneration(t, L3072N256, 3072, 256)
}

func fromHex(s string) *big.Int {
	result, ok := new(big.Int).SetString(s, 16)
	if !ok {
		panic(s)
	}
	return result
}

func TestSignAndVerify(t *testing.T) {
	priv := PrivateKey{
		PublicKey: PublicKey {
			Parameters: Parameters{
				P: fromHex("A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF"),
				Q: fromHex("E1D3391245933D68A0714ED34BBCB7A1F422B9C1"),
				G: fromHex("634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA"),
			},
			Y: fromHex("32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2"),
		},
		X: fromHex("5078D4D29795CBE76D3AACFE48C9AF0BCDBEE91A"),
	}

	testSignAndVerify(t, 0, &priv)
}

func TestSigningWithDegenerateKeys(t *testing.T) {
	// Signing with degenerate private keys should not cause an infinite
	// loop.
	badKeys := []struct {
		p, q, g, y, x string
	}{
		{"00", "01", "00", "00", "00"},
		{"01", "ff", "00", "00", "00"},
	}

	for i, test := range badKeys {
		priv := PrivateKey{
			PublicKey: PublicKey{
				Parameters: Parameters{
					P: fromHex(test.p),
					Q: fromHex(test.q),
					G: fromHex(test.g),
				},
				Y: fromHex(test.y),
			},
			X: fromHex(test.x),
		}

		hashed := []byte("testing")
		if _, _, err := Sign(rand.Reader, &priv, hashed); err == nil {
			t.Errorf("#%d: unexpected success", i)
		}
	}
}
