go port
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package secp256k1
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func mustDecodeHex(t *testing.T, s string) []byte {
|
||||
t.Helper()
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
t.Fatalf("decode hex: %v", err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// TestBasePointOnCurve confirms the generator satisfies y^2 = x^3 + 7.
|
||||
func TestBasePointOnCurve(t *testing.T) {
|
||||
if !IsOnCurve(&Point{X: Gx, Y: Gy}) {
|
||||
t.Fatalf("generator is not on the curve")
|
||||
}
|
||||
}
|
||||
|
||||
// TestPointDoublingMatchesScalarMult verifies group consistency: 2*G computed
|
||||
// via point doubling equals k*G for k=2.
|
||||
func TestPointDoublingMatchesScalarMult(t *testing.T) {
|
||||
g := &Point{X: Gx, Y: Gy}
|
||||
viaDouble := Add(g, g)
|
||||
viaScalar := ScalarBaseMult(big.NewInt(2))
|
||||
if viaDouble.X.Cmp(viaScalar.X) != 0 || viaDouble.Y.Cmp(viaScalar.Y) != 0 {
|
||||
t.Fatalf("2G mismatch: double=%v scalar=%v", viaDouble, viaScalar)
|
||||
}
|
||||
if !IsOnCurve(viaScalar) {
|
||||
t.Fatalf("2G not on curve")
|
||||
}
|
||||
}
|
||||
|
||||
// TestScalarMultDistributes checks (a+b)G == aG + bG.
|
||||
func TestScalarMultDistributes(t *testing.T) {
|
||||
a := big.NewInt(12345)
|
||||
b := big.NewInt(67890)
|
||||
sum := new(big.Int).Add(a, b)
|
||||
left := ScalarBaseMult(sum)
|
||||
right := Add(ScalarBaseMult(a), ScalarBaseMult(b))
|
||||
if left.X.Cmp(right.X) != 0 || left.Y.Cmp(right.Y) != 0 {
|
||||
t.Fatalf("(a+b)G != aG + bG")
|
||||
}
|
||||
}
|
||||
|
||||
// TestPublicKeyKnownValues locks the uncompressed public key for the t3 key.
|
||||
func TestPublicKeyKnownValues(t *testing.T) {
|
||||
priv := mustDecodeHex(t, "a96135266ba58bb5b3a450b8fe7a9d59ea3e6cb0cdb2300e8138d2d2d48e61a8")
|
||||
point, err := PublicKey(priv)
|
||||
if err != nil {
|
||||
t.Fatalf("PublicKey: %v", err)
|
||||
}
|
||||
raw := make([]byte, 64)
|
||||
point.X.FillBytes(raw[0:32])
|
||||
point.Y.FillBytes(raw[32:64])
|
||||
want := "076e3db946fcb53d575c4e742a9f8ff8c4b57ded53776b2a80d13022e1647adaa1641f3e2210f5f6a3bdd73d073ac029ba79d576093d8a92dd148e448a8e63cb"
|
||||
if got := hex.EncodeToString(raw); got != want {
|
||||
t.Fatalf("pubkey = %s, want %s", got, want)
|
||||
}
|
||||
if !IsOnCurve(point) {
|
||||
t.Fatalf("derived public key not on curve")
|
||||
}
|
||||
}
|
||||
|
||||
// TestSignRecoverRoundTrip signs and recovers for several keys and hashes.
|
||||
func TestSignRecoverRoundTrip(t *testing.T) {
|
||||
privs := []string{
|
||||
"a96135266ba58bb5b3a450b8fe7a9d59ea3e6cb0cdb2300e8138d2d2d48e61a8",
|
||||
"3252a4cb9b3865c94dbb7d6f50107ca704c1c2b9e3d1eb81753e221c7db8fa25",
|
||||
"993638df18a38ef2be9f8c915eb9063647d015edc8fb70e3bcb32469bee39c21",
|
||||
}
|
||||
hashes := []string{
|
||||
"e93945efde601eed484553338e58218f4e81c51261dfda72db2d874f75378fe8",
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
}
|
||||
for _, p := range privs {
|
||||
priv := mustDecodeHex(t, p)
|
||||
wantPoint, _ := PublicKey(priv)
|
||||
for _, h := range hashes {
|
||||
hash := mustDecodeHex(t, h)
|
||||
sig, err := Sign(priv, hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Sign: %v", err)
|
||||
}
|
||||
// low-s enforcement
|
||||
if sig.S.Cmp(halfN) > 0 {
|
||||
t.Fatalf("signature s is not low-s")
|
||||
}
|
||||
recovered, err := RecoverPublicKey(hash, sig)
|
||||
if err != nil {
|
||||
t.Fatalf("RecoverPublicKey: %v", err)
|
||||
}
|
||||
if recovered.X.Cmp(wantPoint.X) != 0 || recovered.Y.Cmp(wantPoint.Y) != 0 {
|
||||
t.Fatalf("recovered key differs for priv=%s hash=%s", p, h)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestSignIsDeterministic confirms RFC6979-style reproducibility.
|
||||
func TestSignIsDeterministic(t *testing.T) {
|
||||
priv := mustDecodeHex(t, "a96135266ba58bb5b3a450b8fe7a9d59ea3e6cb0cdb2300e8138d2d2d48e61a8")
|
||||
hash := mustDecodeHex(t, "e93945efde601eed484553338e58218f4e81c51261dfda72db2d874f75378fe8")
|
||||
a, err := Sign(priv, hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Sign: %v", err)
|
||||
}
|
||||
b, err := Sign(priv, hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Sign: %v", err)
|
||||
}
|
||||
if hex.EncodeToString(a.Bytes()) != hex.EncodeToString(b.Bytes()) {
|
||||
t.Fatalf("signatures differ for identical inputs")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicKeyRejectsInvalid(t *testing.T) {
|
||||
if _, err := PublicKey(make([]byte, 31)); err == nil {
|
||||
t.Fatalf("expected error for short key")
|
||||
}
|
||||
if _, err := PublicKey(make([]byte, 32)); err == nil {
|
||||
t.Fatalf("expected error for zero key")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user