package integration_test import ( "crypto/ecdsa" "crypto/sha256" "fmt" "testing" "github.com/rwadurian/mpc-system/pkg/tss" "github.com/stretchr/testify/require" ) // TestVariousThresholds tests different threshold configurations func TestVariousThresholds(t *testing.T) { testCases := []struct { name string threshold int // t in tss-lib (t+1 signers required) totalParties int signersNeeded int // actual signers needed = threshold + 1 }{ { name: "2-of-3 (t=1, n=3)", threshold: 1, totalParties: 3, signersNeeded: 2, }, { name: "3-of-5 (t=2, n=5)", threshold: 2, totalParties: 5, signersNeeded: 3, }, { name: "4-of-7 (t=3, n=7)", threshold: 3, totalParties: 7, signersNeeded: 4, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { fmt.Printf("\n========================================\n") fmt.Printf(" Testing %s\n", tc.name) fmt.Printf("========================================\n") // Step 1: Key Generation fmt.Printf("\n[Step 1] Running Distributed Key Generation...\n") fmt.Printf(" - Threshold (t): %d (meaning t+1=%d signers required)\n", tc.threshold, tc.signersNeeded) fmt.Printf(" - Total Parties (n): %d\n", tc.totalParties) keygenResults, err := tss.RunLocalKeygen(tc.threshold, tc.totalParties) require.NoError(t, err, "Keygen should succeed") require.Len(t, keygenResults, tc.totalParties, "Should have correct number of key shares") publicKey := keygenResults[0].PublicKey require.NotNil(t, publicKey, "Public key should not be nil") fmt.Printf(" [OK] Key generation completed with %d parties!\n", tc.totalParties) fmt.Printf(" Public Key X: %s...\n", publicKey.X.Text(16)[:32]) // Verify all parties have the same public key for i, result := range keygenResults { require.Equal(t, publicKey.X, result.PublicKey.X, "Party %d should have same X", i) require.Equal(t, publicKey.Y, result.PublicKey.Y, "Party %d should have same Y", i) } fmt.Println(" All parties have consistent public key") // Step 2: Test signing with exactly threshold+1 parties fmt.Printf("\n[Step 2] Testing threshold signing with %d-of-%d...\n", tc.signersNeeded, tc.totalParties) message := []byte(fmt.Sprintf("Test message for %s", tc.name)) messageHash := sha256.Sum256(message) // Use first signersNeeded parties signers := keygenResults[:tc.signersNeeded] signResult, err := tss.RunLocalSigning(tc.threshold, signers, messageHash[:]) require.NoError(t, err, "Signing should succeed") require.NotNil(t, signResult.R, "R should not be nil") require.NotNil(t, signResult.S, "S should not be nil") // Verify signature valid := ecdsa.Verify(publicKey, messageHash[:], signResult.R, signResult.S) require.True(t, valid, "Signature should verify") fmt.Printf(" [OK] Signature with %d parties verified!\n", tc.signersNeeded) // Step 3: Verify fewer than threshold parties cannot sign if tc.signersNeeded > 2 { fmt.Printf("\n[Step 3] Verifying %d parties cannot sign (need %d)...\n", tc.signersNeeded-1, tc.signersNeeded) insufficientSigners := keygenResults[:tc.signersNeeded-1] _, err = tss.RunLocalSigning(tc.threshold, insufficientSigners, messageHash[:]) require.Error(t, err, "Signing with insufficient parties should fail") fmt.Printf(" [OK] Correctly rejected signing with insufficient parties\n") } fmt.Printf("\n========================================\n") fmt.Printf(" %s: PASSED\n", tc.name) fmt.Printf("========================================\n") }) } } // Test3of5Flow tests 3-of-5 specifically with multiple combinations func Test3of5Flow(t *testing.T) { fmt.Println("\n========================================") fmt.Println(" 3-of-5 MPC Full Flow Test") fmt.Println("========================================") threshold := 2 // t=2 means t+1=3 signers required totalParties := 5 // Key Generation fmt.Println("\n[Keygen] Generating keys for 5 parties...") keygenResults, err := tss.RunLocalKeygen(threshold, totalParties) require.NoError(t, err) require.Len(t, keygenResults, 5) publicKey := keygenResults[0].PublicKey fmt.Printf(" [OK] 5 key shares generated\n") fmt.Printf(" Public Key: %s...\n", publicKey.X.Text(16)[:32]) message := []byte("3-of-5 threshold signing test") messageHash := sha256.Sum256(message) // Test multiple 3-party combinations combinations := [][]int{ {0, 1, 2}, {0, 1, 3}, {0, 2, 4}, {1, 3, 4}, {2, 3, 4}, } fmt.Println("\n[Signing] Testing various 3-party combinations...") for _, combo := range combinations { signers := []*tss.LocalKeygenResult{ keygenResults[combo[0]], keygenResults[combo[1]], keygenResults[combo[2]], } signResult, err := tss.RunLocalSigning(threshold, signers, messageHash[:]) require.NoError(t, err, "Signing with parties %v should succeed", combo) valid := ecdsa.Verify(publicKey, messageHash[:], signResult.R, signResult.S) require.True(t, valid, "Signature from parties %v should verify", combo) fmt.Printf(" [OK] Parties %v: signature verified\n", combo) } fmt.Println("\n========================================") fmt.Println(" 3-of-5 Flow: ALL PASSED") fmt.Println("========================================") } // Test4of7Flow tests 4-of-7 specifically func Test4of7Flow(t *testing.T) { fmt.Println("\n========================================") fmt.Println(" 4-of-7 MPC Full Flow Test") fmt.Println("========================================") threshold := 3 // t=3 means t+1=4 signers required totalParties := 7 // Key Generation fmt.Println("\n[Keygen] Generating keys for 7 parties...") keygenResults, err := tss.RunLocalKeygen(threshold, totalParties) require.NoError(t, err) require.Len(t, keygenResults, 7) publicKey := keygenResults[0].PublicKey fmt.Printf(" [OK] 7 key shares generated\n") fmt.Printf(" Public Key: %s...\n", publicKey.X.Text(16)[:32]) message := []byte("4-of-7 threshold signing test") messageHash := sha256.Sum256(message) // Test a few 4-party combinations combinations := [][]int{ {0, 1, 2, 3}, {0, 2, 4, 6}, {1, 3, 5, 6}, {3, 4, 5, 6}, } fmt.Println("\n[Signing] Testing various 4-party combinations...") for _, combo := range combinations { signers := []*tss.LocalKeygenResult{ keygenResults[combo[0]], keygenResults[combo[1]], keygenResults[combo[2]], keygenResults[combo[3]], } signResult, err := tss.RunLocalSigning(threshold, signers, messageHash[:]) require.NoError(t, err, "Signing with parties %v should succeed", combo) valid := ecdsa.Verify(publicKey, messageHash[:], signResult.R, signResult.S) require.True(t, valid, "Signature from parties %v should verify", combo) fmt.Printf(" [OK] Parties %v: signature verified\n", combo) } // Verify 3 parties cannot sign fmt.Println("\n[Security] Verifying 3 parties cannot sign...") insufficientSigners := keygenResults[:3] _, err = tss.RunLocalSigning(threshold, insufficientSigners, messageHash[:]) require.Error(t, err, "3 parties should not be able to sign in 4-of-7") fmt.Println(" [OK] Correctly rejected 3-party signing") fmt.Println("\n========================================") fmt.Println(" 4-of-7 Flow: ALL PASSED") fmt.Println("========================================") }