github.com/cloudflare/circl@v1.5.0/sign/mldsa/mldsa65/acvp_test.go (about)

     1  // Code generated from acvp.templ.go. DO NOT EDIT.
     2  
     3  package mldsa65
     4  
     5  import (
     6  	"bytes"
     7  	"compress/gzip"
     8  	"encoding/hex"
     9  	"encoding/json"
    10  	"io"
    11  	"os"
    12  	"testing"
    13  )
    14  
    15  // []byte but is encoded in hex for JSON
    16  type HexBytes []byte
    17  
    18  func (b HexBytes) MarshalJSON() ([]byte, error) {
    19  	return json.Marshal(hex.EncodeToString(b))
    20  }
    21  
    22  func (b *HexBytes) UnmarshalJSON(data []byte) (err error) {
    23  	var s string
    24  	if err = json.Unmarshal(data, &s); err != nil {
    25  		return err
    26  	}
    27  	*b, err = hex.DecodeString(s)
    28  	return err
    29  }
    30  
    31  func gunzip(in []byte) ([]byte, error) {
    32  	buf := bytes.NewBuffer(in)
    33  	r, err := gzip.NewReader(buf)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	return io.ReadAll(r)
    38  }
    39  
    40  func readGzip(path string) ([]byte, error) {
    41  	buf, err := os.ReadFile(path)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	return gunzip(buf)
    46  }
    47  
    48  func TestACVP(t *testing.T) {
    49  	for _, sub := range []string{
    50  		"keyGen",
    51  		"sigGen",
    52  		"sigVer",
    53  	} {
    54  		t.Run(sub, func(t *testing.T) {
    55  			testACVP(t, sub)
    56  		})
    57  	}
    58  }
    59  
    60  // nolint:funlen,gocyclo
    61  func testACVP(t *testing.T, sub string) {
    62  	buf, err := readGzip("../testdata/ML-DSA-" + sub + "-FIPS204/prompt.json.gz")
    63  	if err != nil {
    64  		t.Fatal(err)
    65  	}
    66  
    67  	var prompt struct {
    68  		TestGroups []json.RawMessage `json:"testGroups"`
    69  	}
    70  
    71  	if err = json.Unmarshal(buf, &prompt); err != nil {
    72  		t.Fatal(err)
    73  	}
    74  
    75  	buf, err = readGzip("../testdata/ML-DSA-" + sub + "-FIPS204/expectedResults.json.gz")
    76  	if err != nil {
    77  		t.Fatal(err)
    78  	}
    79  
    80  	var results struct {
    81  		TestGroups []json.RawMessage `json:"testGroups"`
    82  	}
    83  
    84  	if err := json.Unmarshal(buf, &results); err != nil {
    85  		t.Fatal(err)
    86  	}
    87  
    88  	rawResults := make(map[int]json.RawMessage)
    89  
    90  	for _, rawGroup := range results.TestGroups {
    91  		var abstractGroup struct {
    92  			Tests []json.RawMessage `json:"tests"`
    93  		}
    94  		if err := json.Unmarshal(rawGroup, &abstractGroup); err != nil {
    95  			t.Fatal(err)
    96  		}
    97  		for _, rawTest := range abstractGroup.Tests {
    98  			var abstractTest struct {
    99  				TcID int `json:"tcId"`
   100  			}
   101  			if err := json.Unmarshal(rawTest, &abstractTest); err != nil {
   102  				t.Fatal(err)
   103  			}
   104  			if _, exists := rawResults[abstractTest.TcID]; exists {
   105  				t.Fatalf("Duplicate test id: %d", abstractTest.TcID)
   106  			}
   107  			rawResults[abstractTest.TcID] = rawTest
   108  		}
   109  	}
   110  
   111  	scheme := Scheme()
   112  
   113  	for _, rawGroup := range prompt.TestGroups {
   114  		var abstractGroup struct {
   115  			TestType string `json:"testType"`
   116  		}
   117  		if err := json.Unmarshal(rawGroup, &abstractGroup); err != nil {
   118  			t.Fatal(err)
   119  		}
   120  		switch {
   121  		case abstractGroup.TestType == "AFT" && sub == "keyGen":
   122  			var group struct {
   123  				TgID         int    `json:"tgId"`
   124  				ParameterSet string `json:"parameterSet"`
   125  				Tests        []struct {
   126  					TcID int      `json:"tcId"`
   127  					Seed HexBytes `json:"seed"`
   128  				}
   129  			}
   130  			if err := json.Unmarshal(rawGroup, &group); err != nil {
   131  				t.Fatal(err)
   132  			}
   133  
   134  			if group.ParameterSet != scheme.Name() {
   135  				continue
   136  			}
   137  
   138  			for _, test := range group.Tests {
   139  				var result struct {
   140  					Pk HexBytes `json:"pk"`
   141  					Sk HexBytes `json:"sk"`
   142  				}
   143  				rawResult, ok := rawResults[test.TcID]
   144  				if !ok {
   145  					t.Fatalf("Missing result: %d", test.TcID)
   146  				}
   147  				if err := json.Unmarshal(rawResult, &result); err != nil {
   148  					t.Fatal(err)
   149  				}
   150  
   151  				pk, sk := scheme.DeriveKey(test.Seed)
   152  
   153  				pk2, err := scheme.UnmarshalBinaryPublicKey(result.Pk)
   154  				if err != nil {
   155  					t.Fatalf("tc=%d: %v", test.TcID, err)
   156  				}
   157  				sk2, err := scheme.UnmarshalBinaryPrivateKey(result.Sk)
   158  				if err != nil {
   159  					t.Fatal(err)
   160  				}
   161  
   162  				if !pk.Equal(pk2) {
   163  					t.Fatal("pk does not match")
   164  				}
   165  				if !sk.Equal(sk2) {
   166  					t.Fatal("sk does not match")
   167  				}
   168  			}
   169  		case abstractGroup.TestType == "AFT" && sub == "sigGen":
   170  			var group struct {
   171  				TgID          int    `json:"tgId"`
   172  				ParameterSet  string `json:"parameterSet"`
   173  				Deterministic bool   `json:"deterministic"`
   174  				Tests         []struct {
   175  					TcID    int      `json:"tcId"`
   176  					Sk      HexBytes `json:"sk"`
   177  					Message HexBytes `json:"message"`
   178  					Rnd     HexBytes `json:"rnd"`
   179  				}
   180  			}
   181  			if err := json.Unmarshal(rawGroup, &group); err != nil {
   182  				t.Fatal(err)
   183  			}
   184  
   185  			if group.ParameterSet != scheme.Name() {
   186  				continue
   187  			}
   188  
   189  			for _, test := range group.Tests {
   190  				var result struct {
   191  					Signature HexBytes `json:"signature"`
   192  				}
   193  				rawResult, ok := rawResults[test.TcID]
   194  				if !ok {
   195  					t.Fatalf("Missing result: %d", test.TcID)
   196  				}
   197  				if err := json.Unmarshal(rawResult, &result); err != nil {
   198  					t.Fatal(err)
   199  				}
   200  
   201  				sk, err := scheme.UnmarshalBinaryPrivateKey(test.Sk)
   202  				if err != nil {
   203  					t.Fatal(err)
   204  				}
   205  
   206  				var rnd [32]byte
   207  				if !group.Deterministic {
   208  					copy(rnd[:], test.Rnd)
   209  				}
   210  
   211  				sig2 := sk.(*PrivateKey).unsafeSignInternal(test.Message, rnd)
   212  
   213  				if !bytes.Equal(sig2, result.Signature) {
   214  					t.Fatalf("signature doesn't match: %x ≠ %x",
   215  						sig2, result.Signature)
   216  				}
   217  			}
   218  		case abstractGroup.TestType == "AFT" && sub == "sigVer":
   219  			var group struct {
   220  				TgID         int      `json:"tgId"`
   221  				ParameterSet string   `json:"parameterSet"`
   222  				Pk           HexBytes `json:"pk"`
   223  				Tests        []struct {
   224  					TcID      int      `json:"tcId"`
   225  					Message   HexBytes `json:"message"`
   226  					Signature HexBytes `json:"signature"`
   227  				}
   228  			}
   229  			if err := json.Unmarshal(rawGroup, &group); err != nil {
   230  				t.Fatal(err)
   231  			}
   232  
   233  			if group.ParameterSet != scheme.Name() {
   234  				continue
   235  			}
   236  
   237  			pk, err := scheme.UnmarshalBinaryPublicKey(group.Pk)
   238  			if err != nil {
   239  				t.Fatal(err)
   240  			}
   241  
   242  			for _, test := range group.Tests {
   243  				var result struct {
   244  					TestPassed bool `json:"testPassed"`
   245  				}
   246  				rawResult, ok := rawResults[test.TcID]
   247  				if !ok {
   248  					t.Fatalf("Missing result: %d", test.TcID)
   249  				}
   250  				if err := json.Unmarshal(rawResult, &result); err != nil {
   251  					t.Fatal(err)
   252  				}
   253  
   254  				passed2 := unsafeVerifyInternal(pk.(*PublicKey), test.Message, test.Signature)
   255  				if passed2 != result.TestPassed {
   256  					t.Fatalf("verification %v ≠ %v", passed2, result.TestPassed)
   257  				}
   258  			}
   259  		default:
   260  			t.Fatalf("unknown type %s for %s", abstractGroup.TestType, sub)
   261  		}
   262  	}
   263  }