1package subprocess 2 3import ( 4 "encoding/hex" 5 "encoding/json" 6 "fmt" 7 "strings" 8) 9 10// Common top-level structure to parse mode 11type slhdsaTestVectorSet struct { 12 Algorithm string `json:"algorithm"` 13 Mode string `json:"mode"` 14 Revision string `json:"revision"` 15} 16 17type slhdsaKeyGenTestVectorSet struct { 18 Algorithm string `json:"algorithm"` 19 Mode string `json:"mode"` 20 Revision string `json:"revision"` 21 Groups []slhdsaKeyGenTestGroup `json:"testGroups"` 22} 23 24type slhdsaKeyGenTestGroup struct { 25 ID uint64 `json:"tgId"` 26 TestType string `json:"testType"` 27 ParameterSet string `json:"parameterSet"` 28 Tests []slhdsaKeyGenTest `json:"tests"` 29} 30 31type slhdsaKeyGenTest struct { 32 ID uint64 `json:"tcId"` 33 SKSeed string `json:"skSeed"` 34 SKPrf string `json:"skPrf"` 35 PKSeed string `json:"pkSeed"` 36} 37 38type slhdsaKeyGenTestGroupResponse struct { 39 ID uint64 `json:"tgId"` 40 Tests []slhdsaKeyGenTestResponse `json:"tests"` 41} 42 43type slhdsaKeyGenTestResponse struct { 44 ID uint64 `json:"tcId"` 45 PublicKey string `json:"pk"` 46 PrivateKey string `json:"sk"` 47} 48 49type slhdsaSigGenTestVectorSet struct { 50 Algorithm string `json:"algorithm"` 51 Mode string `json:"mode"` 52 Revision string `json:"revision"` 53 Groups []slhdsaSigGenTestGroup `json:"testGroups"` 54} 55 56type slhdsaSigGenTestGroup struct { 57 ID uint64 `json:"tgId"` 58 TestType string `json:"testType"` 59 ParameterSet string `json:"parameterSet"` 60 Deterministic bool `json:"deterministic"` 61 Tests []slhdsaSigGenTest `json:"tests"` 62} 63 64type slhdsaSigGenTest struct { 65 ID uint64 `json:"tcId"` 66 Message string `json:"message"` 67 PrivateKey string `json:"sk"` 68 AdditionalRandomness string `json:"additionalRandomness,omitempty"` 69} 70 71type slhdsaSigGenTestGroupResponse struct { 72 ID uint64 `json:"tgId"` 73 Tests []slhdsaSigGenTestResponse `json:"tests"` 74} 75 76type slhdsaSigGenTestResponse struct { 77 ID uint64 `json:"tcId"` 78 Signature string `json:"signature"` 79} 80 81type slhdsaSigVerTestVectorSet struct { 82 Algorithm string `json:"algorithm"` 83 Mode string `json:"mode"` 84 Revision string `json:"revision"` 85 Groups []slhdsaSigVerTestGroup `json:"testGroups"` 86} 87 88type slhdsaSigVerTestGroup struct { 89 ID uint64 `json:"tgId"` 90 TestType string `json:"testType"` 91 ParameterSet string `json:"parameterSet"` 92 Tests []slhdsaSigVerTest `json:"tests"` 93} 94 95type slhdsaSigVerTest struct { 96 ID uint64 `json:"tcId"` 97 Message string `json:"message"` 98 Signature string `json:"signature"` 99 PublicKey string `json:"pk"` 100} 101 102type slhdsaSigVerTestGroupResponse struct { 103 ID uint64 `json:"tgId"` 104 Tests []slhdsaSigVerTestResponse `json:"tests"` 105} 106 107type slhdsaSigVerTestResponse struct { 108 ID uint64 `json:"tcId"` 109 TestPassed bool `json:"testPassed"` 110} 111 112type slhdsa struct{} 113 114func (s *slhdsa) Process(vectorSet []byte, t Transactable) (any, error) { 115 var common slhdsaTestVectorSet 116 if err := json.Unmarshal(vectorSet, &common); err != nil { 117 return nil, fmt.Errorf("failed to unmarshal vector set: %v", err) 118 } 119 120 switch common.Mode { 121 case "keyGen": 122 return s.processKeyGen(vectorSet, t) 123 case "sigGen": 124 return s.processSigGen(vectorSet, t) 125 case "sigVer": 126 return s.processSigVer(vectorSet, t) 127 default: 128 return nil, fmt.Errorf("unsupported SLH-DSA mode: %s", common.Mode) 129 } 130} 131 132func (s *slhdsa) processKeyGen(vectorSet []byte, t Transactable) (any, error) { 133 var parsed slhdsaKeyGenTestVectorSet 134 if err := json.Unmarshal(vectorSet, &parsed); err != nil { 135 return nil, fmt.Errorf("failed to unmarshal keyGen vector set: %v", err) 136 } 137 138 var ret []slhdsaKeyGenTestGroupResponse 139 140 for _, group := range parsed.Groups { 141 response := slhdsaKeyGenTestGroupResponse{ 142 ID: group.ID, 143 } 144 145 if !strings.HasPrefix(group.ParameterSet, "SLH-DSA-") { 146 return nil, fmt.Errorf("invalid parameter set: %s", group.ParameterSet) 147 } 148 cmdName := group.ParameterSet + "/keyGen" 149 150 for _, test := range group.Tests { 151 skSeed, err := hex.DecodeString(test.SKSeed) 152 if err != nil { 153 return nil, fmt.Errorf("failed to decode skSeed in test case %d/%d: %s", 154 group.ID, test.ID, err) 155 } 156 157 skPrf, err := hex.DecodeString(test.SKPrf) 158 if err != nil { 159 return nil, fmt.Errorf("failed to decode skPrf in test case %d/%d: %s", 160 group.ID, test.ID, err) 161 } 162 163 pkSeed, err := hex.DecodeString(test.PKSeed) 164 if err != nil { 165 return nil, fmt.Errorf("failed to decode pkSeed in test case %d/%d: %s", 166 group.ID, test.ID, err) 167 } 168 169 var seed []byte 170 seed = append(seed, skSeed...) 171 seed = append(seed, skPrf...) 172 seed = append(seed, pkSeed...) 173 174 result, err := t.Transact(cmdName, 2, seed) 175 if err != nil { 176 return nil, fmt.Errorf("key generation failed for test case %d/%d: %s", 177 group.ID, test.ID, err) 178 } 179 180 response.Tests = append(response.Tests, slhdsaKeyGenTestResponse{ 181 ID: test.ID, 182 PrivateKey: hex.EncodeToString(result[0]), 183 PublicKey: hex.EncodeToString(result[1]), 184 }) 185 } 186 187 ret = append(ret, response) 188 } 189 190 return ret, nil 191} 192 193func (s *slhdsa) processSigGen(vectorSet []byte, t Transactable) (any, error) { 194 var parsed slhdsaSigGenTestVectorSet 195 if err := json.Unmarshal(vectorSet, &parsed); err != nil { 196 return nil, fmt.Errorf("failed to unmarshal sigGen vector set: %v", err) 197 } 198 199 var ret []slhdsaSigGenTestGroupResponse 200 201 for _, group := range parsed.Groups { 202 response := slhdsaSigGenTestGroupResponse{ 203 ID: group.ID, 204 } 205 206 if !strings.HasPrefix(group.ParameterSet, "SLH-DSA-") { 207 return nil, fmt.Errorf("invalid parameter set: %s", group.ParameterSet) 208 } 209 cmdName := group.ParameterSet + "/sigGen" 210 211 for _, test := range group.Tests { 212 sk, err := hex.DecodeString(test.PrivateKey) 213 if err != nil { 214 return nil, fmt.Errorf("failed to decode private key in test case %d/%d: %s", 215 group.ID, test.ID, err) 216 } 217 218 msg, err := hex.DecodeString(test.Message) 219 if err != nil { 220 return nil, fmt.Errorf("failed to decode message in test case %d/%d: %s", 221 group.ID, test.ID, err) 222 } 223 224 var randomness []byte 225 if !group.Deterministic { 226 randomness, err = hex.DecodeString(test.AdditionalRandomness) 227 if err != nil { 228 return nil, fmt.Errorf("failed to decode randomness in test case %d/%d: %s", 229 group.ID, test.ID, err) 230 } 231 } 232 233 result, err := t.Transact(cmdName, 1, sk, msg, randomness) 234 if err != nil { 235 return nil, fmt.Errorf("signature generation failed for test case %d/%d: %s", 236 group.ID, test.ID, err) 237 } 238 239 response.Tests = append(response.Tests, slhdsaSigGenTestResponse{ 240 ID: test.ID, 241 Signature: hex.EncodeToString(result[0]), 242 }) 243 } 244 245 ret = append(ret, response) 246 } 247 248 return ret, nil 249} 250 251func (s *slhdsa) processSigVer(vectorSet []byte, t Transactable) (any, error) { 252 var parsed slhdsaSigVerTestVectorSet 253 if err := json.Unmarshal(vectorSet, &parsed); err != nil { 254 return nil, fmt.Errorf("failed to unmarshal sigVer vector set: %v", err) 255 } 256 257 var ret []slhdsaSigVerTestGroupResponse 258 259 for _, group := range parsed.Groups { 260 response := slhdsaSigVerTestGroupResponse{ 261 ID: group.ID, 262 } 263 264 if !strings.HasPrefix(group.ParameterSet, "SLH-DSA-") { 265 return nil, fmt.Errorf("invalid parameter set: %s", group.ParameterSet) 266 } 267 cmdName := group.ParameterSet + "/sigVer" 268 269 for _, test := range group.Tests { 270 pk, err := hex.DecodeString(test.PublicKey) 271 if err != nil { 272 return nil, fmt.Errorf("failed to decode public key in test case %d/%d: %s", 273 group.ID, test.ID, err) 274 } 275 276 msg, err := hex.DecodeString(test.Message) 277 if err != nil { 278 return nil, fmt.Errorf("failed to decode message in test case %d/%d: %s", 279 group.ID, test.ID, err) 280 } 281 282 sig, err := hex.DecodeString(test.Signature) 283 if err != nil { 284 return nil, fmt.Errorf("failed to decode signature in test case %d/%d: %s", 285 group.ID, test.ID, err) 286 } 287 288 result, err := t.Transact(cmdName, 1, pk, msg, sig) 289 if err != nil { 290 return nil, fmt.Errorf("signature verification failed for test case %d/%d: %s", 291 group.ID, test.ID, err) 292 } 293 294 testPassed := result[0][0] != 0 295 response.Tests = append(response.Tests, slhdsaSigVerTestResponse{ 296 ID: test.ID, 297 TestPassed: testPassed, 298 }) 299 } 300 301 ret = append(ret, response) 302 } 303 304 return ret, nil 305} 306