Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion schemas/mlkem_semi_expanded_decaps_test_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,21 @@
"format": "HexBytes",
"description": "The full decapsulation key"
},
"ek": {
"type": "string",
"format": "HexBytes",
"description": "The encapsulation key bytes of dk."
},
"c": {
"type": "string",
"format": "HexBytes",
"description": "An input ciphertext"
},
"K": {
"type": "string",
"format": "HexBytes",
"description": "If present, the shared key the implementation MUST return on a successful Decapsulate call."
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this required for result: valid?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

As a side-note, adding these sort of conditional schema rules seems to interact badly with some code generators. As a concrete example the one I've been using for JSON Schema -> Go will stop emitting a typed structure for anything that has a conditional rule, instead spitting out an interface{} that we have to cast to a manually defined structure.

I'm operating on the assumption we care more about vector accuracy vs fidelity of code generation so adding this kind of conditional validation is the right call and we'll deal with the less useful code generation downstream, but I wanted to mention it as an explicit trade-off. (It's also possible other JSON schema tools handle it better, I haven't done an exhaustive survey).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's unfortunate, but yeah not having to manually notice missing fields feels more important.

This sounds very fixable, btw. Want me to point @filippo-claude at it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds very fixable, btw. Want me to point @filippo-claude at it?

Sure! If you want to take a crack at it I've been using https://github.com/omissis/go-jsonschema Maybe there's an easy fix.

tools/schemagen.go in this repo is already setup and just needs a small diff to output the generated code instead of just checking that it builds:
diff --git a/tools/schemagen/schemagen.go b/tools/schemagen/schemagen.go
index 5b656c8..3c8fd4f 100644
--- a/tools/schemagen/schemagen.go
+++ b/tools/schemagen/schemagen.go
@@ -17,7 +17,10 @@ import (
        "github.com/atombender/go-jsonschema/pkg/generator"
 )

-var schemaDirectory = flag.String("schemas-dir", "schemas", "directory containing schema files")
+var (
+       schemaDirectory = flag.String("schemas-dir", "schemas", "directory containing schema files")
+       dumpStdout      = flag.Bool("stdout", false, "write the generated source to stdout")
+)

 func main() {
        flag.Parse()
@@ -61,11 +64,17 @@ func main() {
        if sourceCount := len(sources); sourceCount != 1 {
                log.Fatalf("expected to generate 1 source file, got %d\n", sourceCount)
        }
-       _, ok := sources[ouputName]
+       source, ok := sources[ouputName]
        if !ok {
                log.Fatalf("missing generated %q output file source", ouputName)
        }

+       if *dumpStdout {
+               if _, err := os.Stdout.Write(source); err != nil {
+                       log.Fatalf("writing source to stdout: %v", err)
+               }
+       }
+
        for _, warning := range warnings {
                log.Printf("⚠ Warning: %s", warning)
        }

If you apply that you can get a nice loop going by deleting schemas/mlkem_semi_expanded_decaps_test_schema.json#L116-L129, running tools/schemagen.go --stdout > before.go, then reverting the schema back and running it again. You'll see the nice structure drop-out of the generated code and get replaced with interface{}.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"result": {
"$ref": "common.json#/definitions/Result"
},
Expand All @@ -98,10 +108,25 @@
"tcId",
"flags",
"dk",
"ek",
"c",
"result"
],
"additionalProperties": false
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"result": {
"const": "valid"
}
}
},
"then": {
"required": ["K"]
}
}
]
}
}
},
Expand Down
Loading