///| test the Dilithium by KAT files
priv struct KAT {
id : Int
seed : Array[Byte]
mlen : Int // message length
msg : Array[Byte]
pk : Array[Byte]
sk : Array[Byte]
smlen : Int // signature length
sm : Array[Byte] // signature
}
///|
fn string_view_to_bytes(s : @string.View) -> Array[Byte] {
let bytes : Array[Byte] = Array::new()
let char_length = s.char_length()
if (char_length & 1) != 0 {
abort("String length must be even for hex conversion")
}
for i in 0..<(char_length / 2) {
let byte : Byte = (hex_char_to_int(s.char_at(i * 2)) * 16 +
hex_char_to_int(s.char_at(i * 2 + 1))).to_byte()
bytes.push(byte)
}
bytes
}
///|
fn load_seed() -> Array[Array[Byte]] {
let file_path = "kat/SeedBuffer_Dilithium"
let content = @fs.read_file_to_string(file_path) catch {
err => abort(err.to_string())
}
content
.split("\n")
.to_array()
.map(line => line.to_string())
.map(hex_str_to_bytes)
}
///|
fn load_kat_file(level : SecurityLevel) -> Array[KAT] {
let file_name = match level {
SecurityLevel::Dilithium2 => "PQCsignKAT_Dilithium2.rsp"
SecurityLevel::Dilithium3 => "PQCsignKAT_Dilithium3.rsp"
SecurityLevel::Dilithium5 => "PQCsignKAT_Dilithium5.rsp"
}
let file_path = "kat/" + file_name
let content = @fs.read_file_to_string(file_path) catch {
err => abort(err.to_string())
}
fn extract_value_to_bytes(line : String) -> Array[Byte] {
let value = line.split("=").last().unwrap().to_string()
let bytes = string_view_to_bytes(value.trim_space())
bytes
}
fn extract_value_to_int(line : String) -> Int {
let value = line.split("=").last().unwrap().to_string()
let int_value = try? @strconv.parse_int(value.trim_space().to_string())
int_value.unwrap()
}
let lines = content
.split("\n")
.filter(line => not(line.is_empty()))
.map(line => line.to_string())
// count, seed, mlen, msg, pk, sk, smlen, sm
let count = lines
.filter(line => line.has_prefix("count"))
.map(line => line.split("=").last().unwrap().to_string())
.map(extract_value_to_int)
.collect()
let seed = lines
.filter(line => line.has_prefix("seed"))
.map(extract_value_to_bytes)
.collect()
let mlen = lines
.filter(line => line.has_prefix("mlen"))
.map(extract_value_to_int)
.collect()
let msg = lines
.filter(line => line.has_prefix("msg"))
.map(extract_value_to_bytes)
.collect()
let pk = lines
.filter(line => line.has_prefix("pk"))
.map(extract_value_to_bytes)
.collect()
let sk = lines
.filter(line => line.has_prefix("sk"))
.map(extract_value_to_bytes)
.collect()
let smlen = lines
.filter(line => line.has_prefix("smlen"))
.map(extract_value_to_int)
.collect()
let sm = lines
.filter(line => line.has_prefix("sm "))
.map(extract_value_to_bytes)
.collect()
let kats = []
for i in 0..