Skip to content

chore(TestVectors): Reuse single KeyVectors client across TestVectors #1577

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

Merged
merged 11 commits into from
Feb 5, 2025
35 changes: 26 additions & 9 deletions TestVectors/dafny/DDBEncryption/src/DecryptManifest.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ module {:options "-functionSyntax:4"} DecryptManifest {
import opened JSONHelpers
import JsonConfig
import ENC = AwsCryptographyDbEncryptionSdkDynamoDbItemEncryptorTypes
import KeyVectors

method OnePositiveTest(name : string, config : JSON, encrypted : JSON, plaintext : JSON) returns (output : Result<bool, string>)
method OnePositiveTest(name : string, config : JSON, encrypted : JSON, plaintext : JSON, keys : KeyVectors.KeyVectorsClient)
returns (output : Result<bool, string>)
requires keys.ValidState()
modifies keys.Modifies
ensures keys.ValidState()
{
var enc :- JsonConfig.GetRecord(encrypted);
var plain :- JsonConfig.GetRecord(plaintext);
var encryptor :- JsonConfig.GetItemEncryptor(name, config);
var encryptor :- JsonConfig.GetItemEncryptor(name, config, keys);
var decrypted :- expect encryptor.DecryptItem(
ENC.DecryptItemInput(
encryptedItem:=enc.item
Expand All @@ -36,10 +41,14 @@ module {:options "-functionSyntax:4"} DecryptManifest {
return Success(true);
}

method OneNegativeTest(name : string, config : JSON, encrypted : JSON) returns (output : Result<bool, string>)
method OneNegativeTest(name : string, config : JSON, encrypted : JSON, keys: KeyVectors.KeyVectorsClient)
returns (output : Result<bool, string>)
requires keys.ValidState()
modifies keys.Modifies
ensures keys.ValidState()
{
var enc :- JsonConfig.GetRecord(encrypted);
var encryptor :- JsonConfig.GetItemEncryptor(name, config);
var encryptor :- JsonConfig.GetItemEncryptor(name, config, keys);
var decrypted := encryptor.DecryptItem(
ENC.DecryptItemInput(
encryptedItem:=enc.item
Expand All @@ -51,7 +60,11 @@ module {:options "-functionSyntax:4"} DecryptManifest {
return Success(true);
}

method OneTest(name : string, value : JSON) returns (output : Result<bool, string>)
method OneTest(name : string, value : JSON, keys: KeyVectors.KeyVectorsClient)
returns (output : Result<bool, string>)
requires keys.ValidState()
modifies keys.Modifies
ensures keys.ValidState()
{
:- Need(value.Object?, "Test must be an object");

Expand Down Expand Up @@ -89,15 +102,19 @@ module {:options "-functionSyntax:4"} DecryptManifest {

if types.value == "positive-decrypt" {
:- Need(plaintext.Some?, "positive-decrypt Test requires a 'plaintext' member.");
output := OnePositiveTest(name, config.value, encrypted.value, plaintext.value);
output := OnePositiveTest(name, config.value, encrypted.value, plaintext.value, keys);
} else if types.value == "negative-decrypt" {
output := OneNegativeTest(name, config.value, encrypted.value);
output := OneNegativeTest(name, config.value, encrypted.value, keys);
} else {
return Failure("Invalid encrypt type : '" + types.value + "'.");
}
}

method Decrypt(inFile : string) returns (output : Result<bool, string>)
method Decrypt(inFile : string, keyVectors: KeyVectors.KeyVectorsClient)
returns (output : Result<bool, string>)
requires keyVectors.ValidState()
modifies keyVectors.Modifies
ensures keyVectors.ValidState()
{
var timeStamp :- expect Time.GetCurrentTimeStamp();
print timeStamp + " Decrypt : ", inFile, "\n";
Expand Down Expand Up @@ -154,7 +171,7 @@ module {:options "-functionSyntax:4"} DecryptManifest {
for i := 0 to |tests.value| {
var obj := tests.value[i];
:- Need(obj.1.Object?, "Value of test '" + obj.0 + "' must be an Object.");
var _ :- OneTest(obj.0, obj.1);
var _ :- OneTest(obj.0, obj.1, keyVectors);
}

timeStamp :- expect Time.GetCurrentTimeStamp();
Expand Down
37 changes: 27 additions & 10 deletions TestVectors/dafny/DDBEncryption/src/EncryptManifest.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module {:options "-functionSyntax:4"} EncryptManifest {
import opened JSONHelpers
import JsonConfig
import ENC = AwsCryptographyDbEncryptionSdkDynamoDbItemEncryptorTypes
import KeyVectors

function Manifest() : (string, JSON)
{
Expand All @@ -42,10 +43,14 @@ module {:options "-functionSyntax:4"} EncryptManifest {
("client", Object(result))
}

method OnePositiveTest(name : string, theType : string, desc : string, config : JSON, decryptConfig : Option<JSON>, record : JSON) returns (output : Result<(string, JSON), string>)
method OnePositiveTest(name : string, theType : string, desc : string, config : JSON, decryptConfig : Option<JSON>, record : JSON, keys: KeyVectors.KeyVectorsClient)
returns (output : Result<(string, JSON), string>)
requires keys.ValidState()
modifies keys.Modifies
ensures keys.ValidState()
{
var rec :- JsonConfig.GetRecord(record);
var encryptor :- JsonConfig.GetItemEncryptor(name, config);
var encryptor :- JsonConfig.GetItemEncryptor(name, config, keys);
var encrypted :- expect encryptor.EncryptItem(
ENC.EncryptItemInput(
plaintextItem:=rec.item
Expand All @@ -64,10 +69,14 @@ module {:options "-functionSyntax:4"} EncryptManifest {
return Success((name, Object(result)));
}

method OneNegativeTest(name : string, config : JSON, record : JSON) returns (output : Result<bool, string>)
method OneNegativeTest(name : string, config : JSON, record : JSON, keys: KeyVectors.KeyVectorsClient)
returns (output : Result<bool, string>)
requires keys.ValidState()
modifies keys.Modifies
ensures keys.ValidState()
{
var rec :- JsonConfig.GetRecord(record);
var encryptor :- JsonConfig.GetItemEncryptor(name, config);
var encryptor :- JsonConfig.GetItemEncryptor(name, config, keys);
var encrypted := encryptor.EncryptItem(
ENC.EncryptItemInput(
plaintextItem:=rec.item
Expand All @@ -80,7 +89,11 @@ module {:options "-functionSyntax:4"} EncryptManifest {
}


method OneTest(name : string, value : JSON) returns (output : Result<Option<(string, JSON)>, string>)
method OneTest(name : string, value : JSON, keys: KeyVectors.KeyVectorsClient)
returns (output : Result<Option<(string, JSON)>, string>)
requires keys.ValidState()
modifies keys.Modifies
ensures keys.ValidState()
{
:- Need(value.Object?, "Test must be an object");

Expand Down Expand Up @@ -117,20 +130,24 @@ module {:options "-functionSyntax:4"} EncryptManifest {
:- Need(record.Some?, "Test requires a 'record' member.");

if types.value == "positive-encrypt" {
var x :- OnePositiveTest(name, "positive-decrypt", description.value, config.value, decryptConfig, record.value);
var x :- OnePositiveTest(name, "positive-decrypt", description.value, config.value, decryptConfig, record.value, keys);
return Success(Some(x));
} else if types.value == "negative-decrypt" {
var x :- OnePositiveTest(name, "negative-decrypt", description.value, config.value, decryptConfig, record.value);
var x :- OnePositiveTest(name, "negative-decrypt", description.value, config.value, decryptConfig, record.value, keys);
return Success(Some(x));
} else if types.value == "negative-encrypt" {
var _ := OneNegativeTest(name, config.value, record.value);
var _ := OneNegativeTest(name, config.value, record.value, keys);
return Success(None);
} else {
return Failure("Invalid encrypt type : '" + types.value + "'.");
}
}

method Encrypt(inFile : string, outFile : string, lang : string, version : string) returns (output : Result<bool, string>)
method Encrypt(inFile : string, outFile : string, lang : string, version : string, keyVectors: KeyVectors.KeyVectorsClient)
returns (output : Result<bool, string>)
requires keyVectors.ValidState()
modifies keyVectors.Modifies
ensures keyVectors.ValidState()
{
var timeStamp :- expect Time.GetCurrentTimeStamp();
print timeStamp + " Encrypt : ", inFile, "\n";
Expand Down Expand Up @@ -187,7 +204,7 @@ module {:options "-functionSyntax:4"} EncryptManifest {
for i := 0 to |tests.value| {
var obj := tests.value[i];
:- Need(obj.1.Object?, "Value of test '" + obj.0 + "' must be an Object.");
var newTest :- OneTest(obj.0, obj.1);
var newTest :- OneTest(obj.0, obj.1, keyVectors);
if newTest.Some? {
test := test + [newTest.value];
}
Expand Down
42 changes: 33 additions & 9 deletions TestVectors/dafny/DDBEncryption/src/Index.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@ module WrappedDDBEncryptionMain {
import FileIO
import JSON.API
import opened JSONHelpers
import KeyVectors
import KeyVectorsTypes = AwsCryptographyMaterialProvidersTestVectorKeysTypes

method AddJson(prev : TestVectorConfig, file : string) returns (output : Result<TestVectorConfig, string>)

const DEFAULT_KEYS : string := "../../../submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/test/keys.json"

method AddJson(prev : TestVectorConfig, file : string, keyVectors: KeyVectors.KeyVectorsClient)
returns (output : Result<TestVectorConfig, string>)
requires keyVectors.ValidState()
modifies keyVectors.Modifies
ensures keyVectors.ValidState()
{
var configBv := FileIO.ReadBytesFromFile(file);
if configBv.Failure? {
Expand All @@ -24,20 +33,35 @@ module WrappedDDBEncryptionMain {
}
var configBytes := BvToBytes(configBv.value);
var json :- expect API.Deserialize(configBytes);
output := ParseTestVector(json, prev);
output := ParseTestVector(json, prev, keyVectors);
if output.Failure? {
print output.error, "\n";
}
}

method ASDF() {
method ASDF()
{
// KeyVectors client passed to every test.
// All test vectors currently use the same keys manifest, located at DEFAULT_KEYS.
// All test vectors can share this same KeyVectors client.

// To use a different keys manifest, create a new KeyVectors client.
// If you need to create a new KeyVectors client, create it as infrequently as possible.
// Creating this client frequently means JSON is parsed frequently.
// Parsing JSON is very slow in Python. Parse JSON as infrequently as possible.
var keyVectors :- expect KeyVectors.KeyVectors(
KeyVectorsTypes.KeyVectorsConfig(
keyManifestPath := DEFAULT_KEYS
)
);

WriteSetPermutations.WriteSetPermutations();
var config := MakeEmptyTestVector();
config :- expect AddJson(config, "records.json");
config :- expect AddJson(config, "configs.json");
config :- expect AddJson(config, "data.json");
config :- expect AddJson(config, "iotest.json");
config :- expect AddJson(config, "PermTest.json");
config.RunAllTests();
config :- expect AddJson(config, "records.json", keyVectors);
config :- expect AddJson(config, "configs.json", keyVectors);
config :- expect AddJson(config, "data.json", keyVectors);
config :- expect AddJson(config, "iotest.json", keyVectors);
config :- expect AddJson(config, "PermTest.json", keyVectors);
config.RunAllTests(keyVectors);
}
}
Loading
Loading