Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verification Failure Test with SignDecode_h #115

Merged
merged 9 commits into from
Mar 4, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ package mldsa_sequences_pkg;
`include "src/ML_DSA_randomized_sign_gen_sequence.svh"
`include "src/ML_DSA_randomized_verif_sequence.svh"
`include "src/ML_DSA_randomized_verif_fail_sequence.svh"
`include "src/ML_DSA_randomized_h_decode_fail_sequence.svh"
`include "src/ML_DSA_randomized_reset_sequence.svh"
`include "src/ML_DSA_randomized_all_sequence.svh"
`include "src/ML_DSA_keygen_KATs_sequence.svh"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
//----------------------------------------------------------------------
// Created with uvmf_gen version 2022.3
//----------------------------------------------------------------------
// pragma uvmf custom header begin
// pragma uvmf custom header end
//----------------------------------------------------------------------
//
//----------------------------------------------------------------------
//
// DESCRIPTION: This file contains the top level sequence used in example_derived_test.
// It is an example of a sequence that is extended from %(benchName)_bench_sequence_base
// and can override %(benchName)_bench_sequence_base.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//

class ML_DSA_randomized_h_decode_fail_sequence extends mldsa_bench_sequence_base;

`uvm_object_utils(ML_DSA_randomized_h_decode_fail_sequence);

// Members to control randomized failure
int fail_index; // Index of the word to modify
int fail_bit; // Bit position to modify

function new(string name = "");
super.new(name);
endfunction

virtual task body();
bit ready;
bit valid;
string output_file = "./keygen_input_for_test.hex";
string input_file = "./keygen_output_for_test.hex";
int fd;
string line;
int value;
reg_model.reset();
data =0;
ready =0;
valid = 0;
#400;

// Randomize the failure parameters
if (!randomize(fail_index, fail_bit) with {
fail_index inside {[0:20]}; // Randomly select a word in h
fail_bit inside {[0:31]}; // Bit position (0 to 31)
}) begin
`uvm_error("RANDOMIZE_FAIL", "Failed to randomize failure parameters");
end else begin
`uvm_info("FAIL_TEST_SEQ", $sformatf("Failing index: %0d", fail_index), UVM_LOW);
if (fail_index==0 && fail_bit > 23) begin
if (!randomize(fail_bit) with {
fail_bit inside {[0:23]}; // Bit position (0 to 23) because the first word of the last by is unused
}) begin
`uvm_error("RANDOMIZE_FAIL", "Failed to randomize Failing register");
end else begin
`uvm_info("FAIL_TEST_SEQ", $sformatf("Failing register: bit: %0d", fail_bit), UVM_LOW);
end
end
else begin
`uvm_info("FAIL_TEST_SEQ", $sformatf("Failing register: bit: %0d", fail_bit), UVM_LOW);
end
end


if (reg_model.default_map == null) begin
`uvm_fatal("MAP_ERROR", "mldsa_uvm_rm.default_map map is not initialized");
end else begin
`uvm_info("MAP_INIT", "mldsa_uvm_rm.default_map is initialized", UVM_LOW);
end
// ----------------------------------------------------------------------------
// Verification Failure TEST with SignDecode H
// ----------------------------------------------------------------------------

while(!ready) begin
reg_model.MLDSA_STATUS.read(status, data, UVM_FRONTDOOR, reg_model.default_map, this);
if (status != UVM_IS_OK) begin
`uvm_error("REG_READ", $sformatf("Failed to read MLDSA_STATUS"));
end else begin
`uvm_info("REG_READ", $sformatf("MLDSA_STATUS: %0h", data), UVM_HIGH);
end
ready = data[0];
end

//=========================================================

// Open the file for writing
fd = $fopen(output_file, "w");
if (fd == 0) begin
$display("ERROR: Failed to open file: %s", output_file);
return;
end
// Generate a random SEED array
foreach (SEED[i]) begin
if (!this.randomize(data)) begin
`uvm_error("RANDOMIZE_FAIL", "Failed to randomize SEED data");
end
SEED[i] = data;
end
// Write the KeyGen command and the SEED array to the file
$fwrite(fd, "%02X\n", 0); // KeyGen command
write_file(fd, 32/4, SEED); // Write 32-byte SEED to the file
$fclose(fd);
// Execute the key generation process
$system("./test_dilithium5 keygen_input_for_test.hex keygen_output_for_test.hex");

// Open the generated file for reading
fd = $fopen(input_file, "r");
if (fd == 0) begin
`uvm_error("PRED", $sformatf("Failed to open input_file: %s", input_file));
return;
end
// Skip the two lines (KeyGen command and PK in output)
void'($fgets(line, fd));
void'($sscanf(line, "%02x\n", value));
read_line(fd, 648, PK); // Read 2592-byte Public Key to the file
// Read the secret key (SK) from the file into the SK array
read_line(fd, 1224, SK);
$fclose(fd);

// Writing the SK into the MLDSA_PUBKEY register array
for (int i = 0; i < reg_model.MLDSA_PUBKEY.m_mem.get_size(); i++) begin
reg_model.MLDSA_PUBKEY.m_mem.write(status, i, PK[i], UVM_FRONTDOOR, reg_model.default_map, this);
if (status != UVM_IS_OK) begin
`uvm_error("REG_WRITE", $sformatf("Failed to write MLDSA_PUBKEY[%0d]", i));
end else begin
`uvm_info("REG_WRITE", $sformatf("MLDSA_PUBKEY[%0d] written with %0h", i, PK[i]), UVM_LOW);
end
end

//=========================================================
output_file = "./signing_input_for_test.hex";
input_file = "./signing_ouput_for_test.hex";
// Open the file for writing
fd = $fopen(output_file, "w");
if (fd == 0) begin
$display("ERROR: Failed to open file: %s", output_file);
return;
end
$fwrite(fd, "%02X\n", 1); // Signature generation cmd
// Generate a random SEED array
foreach (MSG[i]) begin
if (!this.randomize(data)) begin
`uvm_error("RANDOMIZE_FAIL", "Failed to randomize MSG data");
end
MSG[i] = data;
end
write_file(fd, 16, MSG); // Write 64-byte Message to the file
write_file(fd, 1224, SK); // Write 4864-byte Secret Key to the file
$fclose(fd);
$system("./test_dilithium5 signing_input_for_test.hex signing_ouput_for_test.hex");
// Open the file for reading
fd = $fopen(input_file, "r");
if (fd == 0) begin
`uvm_error("PRED", $sformatf("Failed to open input_file: %s", input_file));
return;
end
else begin
// Skip the first line
void'($fgets(line, fd)); // Read a line from the file
void'($sscanf(line, "%02x\n", value));
end
// Skip the second line
void'($fgets(line, fd)); // Read a line from the file
void'($sscanf(line, "%08x\n", value));
read_line(fd, 1157, SIG);// Read 4864-byte Signature to the file
SIG[0] = SIG[0] >> 8;
$fclose(fd);

// This is a new file writes with the correct input sets for the predictor

output_file = "./verif_failure_input_test.hex";
fd = $fopen(output_file, "w");
if (fd == 0) begin
$display("ERROR: Failed to open file: %s", output_file);
return;
end
$fwrite(fd, "%02X\n", 2); // Signature generation cmd
write_file_without_newline(fd, 1157, SIG);
$fwrite(fd, "%02X%02X%02X", SIG[0][7:0],SIG[0][15:8],SIG[0][23:16]);
write_file(fd, 16, MSG); // Write 64-byte message to the file
write_file(fd, 648, PK); // Write 2592-byte Public Key to the file
$fclose(fd);

// Writing MLDSA_MSG register
foreach (reg_model.MLDSA_MSG[i]) begin
reg_model.MLDSA_MSG[i].write(status, MSG[i], UVM_FRONTDOOR, reg_model.default_map, this);
if (status != UVM_IS_OK) begin
`uvm_error("REG_WRITE", $sformatf("Failed to write MLDSA_MSG[%0d]", i));
end else begin
`uvm_info("REG_WRITE", $sformatf("MLDSA_MSG[%0d] written with %0h", i, MSG[i]), UVM_LOW);
end
end

// Writing the SIGNATURE into the MLDSA_SIGNATURE register array
for (int i = 0; i < reg_model.MLDSA_SIGNATURE.m_mem.get_size(); i++) begin
if (i == fail_index) begin
SIG[i] ^= (1 << fail_bit); // Flip the selected bit
end
reg_model.MLDSA_SIGNATURE.m_mem.write(status, i, SIG[i], UVM_FRONTDOOR, reg_model.default_map, this);
if (status != UVM_IS_OK) begin
`uvm_error("REG_WRITE", $sformatf("Failed to write MLDSA_SIGNATURE[%0d]", i));
end else begin
if (i == fail_index) begin
`uvm_info("REG_WRITE", $sformatf("Failure injected to MLDSA_SIGNATURE[%0d] with %0h", i, SIG[i]), UVM_LOW);
end else begin
`uvm_info("REG_WRITE", $sformatf("MLDSA_SIGNATURE[%0d] written with %0h", i, SIG[i]), UVM_LOW);
end
end
end


//=========================================================



data = 'h0000_0003; // verify singature
reg_model.MLDSA_CTRL.write(status, data, UVM_FRONTDOOR, reg_model.default_map, this);
if (status != UVM_IS_OK) begin
`uvm_error("REG_WRITE", $sformatf("Failed to write MLDSA_CTRL"));
end else begin
`uvm_info("REG_WRITE", $sformatf("MLDSA_CTRL written with %0h", data), UVM_LOW);
end

while(!valid) begin
reg_model.MLDSA_STATUS.read(status, data, UVM_FRONTDOOR, reg_model.default_map, this);
if (status != UVM_IS_OK) begin
`uvm_error("REG_READ", $sformatf("Failed to read MLDSA_STATUS"));
end else begin
`uvm_info("REG_READ", $sformatf("MLDSA_STATUS: %0h", data), UVM_HIGH);
end
valid = data[1];
end

// Reading MLDSA_VERIFY_RES register
foreach (reg_model.MLDSA_VERIFY_RES[i]) begin
reg_model.MLDSA_VERIFY_RES[i].read(status, data, UVM_FRONTDOOR, reg_model.default_map, this);
if (status != UVM_IS_OK) begin
`uvm_error("REG_READ", $sformatf("Failed to read MLDSA_VERIFY_RES[%0d]", i));
end else begin
`uvm_info("REG_READ", $sformatf("MLDSA_VERIFY_RES[%0d]: %0h", i, data), UVM_LOW);
end
end
// ---------------------------------------------------------
// Verification Failure TEST with SignDecode H IS DONE
// ---------------------------------------------------------

endtask
endclass


// pragma uvmf custom external begin
// pragma uvmf custom external end



Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ class ML_DSA_randomized_verif_fail_sequence extends mldsa_bench_sequence_base;
`uvm_error("RANDOMIZE_FAIL", "Failed to randomize failure fail_index parameter for MSG");
end
else if (fail_register == 2 && !randomize(fail_index) with {
fail_index inside {[0:1156]}; // Assuming max index is 1156 for PUBKEY
fail_index inside {[0:1155]}; // Assuming max index is 1156 for PUBKEY 1157th word is tested with decode_h_fail test
}) begin
`uvm_error("RANDOMIZE_FAIL", "Failed to randomize failure fail_index parameter for MSG");
end
`uvm_info("MAP_INIT", "mldsa_uvm_rm.default_map is initialized", UVM_LOW);
`uvm_info("FAIL_TEST_SEQ", $sformatf("Failing index: %0d", fail_index), UVM_LOW);
end


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ package mldsa_tests_pkg;
`include "src/ML_DSA_verif_KATs_test.svh"
`include "src/ML_DSA_randomized_verif_test.svh"
`include "src/ML_DSA_randomized_verif_fail_test.svh"
`include "src/ML_DSA_randomized_h_decode_fail_test.svh"
`include "src/ML_DSA_randomized_all_test.svh"

// pragma uvmf custom package_item_additional begin
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//----------------------------------------------------------------------
// Created with uvmf_gen version 2022.3
//----------------------------------------------------------------------
// pragma uvmf custom header begin
// pragma uvmf custom header end
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// DESCRIPTION: This test extends test_top and makes
// changes to test_top using the UVM factory type_override:
//
// Test scenario:
// This is a template test that can be used to create future tests.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//

class ML_DSA_randomized_h_decode_fail_test extends test_top;

`uvm_component_utils(ML_DSA_randomized_h_decode_fail_test);


bit expect_verif_failure;
bit expect_predictor_verif_failure;

function new(string name = "", uvm_component parent = null);
super.new(name, parent);
endfunction

virtual function void build_phase(uvm_phase phase);
// The factory override below is an example of how to replace the mldsa_bench_sequence_base
// sequence with the ML_DSA_randomized_h_decode_fail_sequence.
mldsa_bench_sequence_base::type_id::set_type_override(ML_DSA_randomized_h_decode_fail_sequence::get_type());
// Execute the build_phase of test_top AFTER all factory overrides have been created.
super.build_phase(phase);
// pragma uvmf custom configuration_settings_post_randomize begin
// UVMF_CHANGE_ME Test specific configuration values can be set here.

expect_verif_failure = 1;
expect_predictor_verif_failure = 1;

uvm_config_db#(bit)::set(null, "*", "expect_verif_failure", expect_verif_failure);
uvm_config_db#(bit)::set(null, "*", "expect_predictor_verif_failure", expect_predictor_verif_failure);
// The configuration structure has already been randomized.
// pragma uvmf custom configuration_settings_post_randomize end
endfunction

virtual task main_phase(uvm_phase phase);
// Start the ML_DSA_randomized_h_decode_fail_sequence
ML_DSA_randomized_h_decode_fail_sequence seq;
seq = ML_DSA_randomized_h_decode_fail_sequence::type_id::create("ML_DSA_randomized_h_decode_fail_sequence");
seq.start(null); // You may need to specify a sequencer if your environment requires it
endtask

endclass

// pragma uvmf custom external begin
// pragma uvmf custom external end


Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Random seed desired...
# seed: 4098270334
plusargs:
- '+UVM_TESTNAME=ML_DSA_randomized_h_decode_fail_test'
testname: ML_DSA_randomized_h_decode_fail_test
parameters:
dilithium_command: "test_dilithium5"
Loading