Skip to content

Commit d087faf

Browse files
committed
m
1 parent a1814ee commit d087faf

File tree

3 files changed

+77
-13
lines changed

3 files changed

+77
-13
lines changed

DynamoDbEncryption/dafny/DynamoDbEncryption/src/DDBSupport.dfy

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ module DynamoDBSupport {
238238

239239
// If names[":aws_dbe_bucket"] holds S(N)' return (Some(names - {":aws_dbe_bucket"}), Some(N))
240240
// else return (None, None)
241-
function method ExtractBucketNumber(names : Option<DDB.ExpressionAttributeValueMap>) : Result<(Option<DDB.ExpressionAttributeValueMap>, Option<uint32>), Error>
241+
function method ExtractBucketNumber(names : Option<DDB.ExpressionAttributeValueMap>)
242+
: Result<(Option<DDB.ExpressionAttributeValueMap>, Option<uint32>), Error>
242243
{
243244
if names.None? then
244245
Success((None, None))
@@ -252,7 +253,8 @@ module DynamoDBSupport {
252253
Success((None, None))
253254
}
254255

255-
function method ExtractBucketQueries(names : Option<DDB.ExpressionAttributeValueMap>) : Result<(Option<DDB.ExpressionAttributeValueMap>, Option<uint32>), Error>
256+
function method ExtractBucketQueries(names : Option<DDB.ExpressionAttributeValueMap>)
257+
: Result<(Option<DDB.ExpressionAttributeValueMap>, Option<uint32>), Error>
256258
{
257259
if names.None? then
258260
Success((None, None))
@@ -268,7 +270,8 @@ module DynamoDBSupport {
268270

269271
// Extract aws_dbe_bucket = NN from filterExpr and return bucket
270272
method ExtractBucket(search : SearchableEncryptionInfo.BeaconVersion, keyExpr : Option<string>, filterExpr : Option<string>, names : Option<DDB.ExpressionAttributeNameMap>, values : Option<DDB.ExpressionAttributeValueMap>, actions : AttributeActions)
271-
returns (output : Result<(Option<DDB.ExpressionAttributeValueMap>, BucketNumber, Option<BucketNumber>), Error>)
273+
returns (output : Result<(Option<DDB.ExpressionAttributeValueMap>, BucketNumber, Option<BucketCount>), Error>)
274+
ensures output.Success? && output.value.2.Some? ==> output.value.1 < output.value.2.value
272275
{
273276
if search.numBuckets <= 1 {
274277
:- Need(values.None? || BucketName !in values.value, E(""));
@@ -277,12 +280,21 @@ module DynamoDBSupport {
277280
}
278281

279282
var foo :- ExtractBucketNumber(values);
280-
var (nValues, bucket) := foo;
283+
var (values2, bucket) := foo;
281284
if bucket.Some? {
282-
:- Need(bucket.value < search.numBuckets, E("Bucket number specified in FilterExpression was " + String.Base10Int2String(bucket.value as int) + "but it must be less than the number of buckets " + String.Base10Int2String(search.numBuckets as int)));
283-
:- Need(bucket.value < 255, E("Bucket must be less than 255")); // unreachable
284-
var nbucket := (bucket.value as nat) as BucketNumber;
285-
return Success((nValues, nbucket, None));
285+
:- Need(bucket.value < search.numBuckets as uint32, E(BucketName + " specified in FilterExpression was " + String.Base10Int2String(bucket.value as int) + " must be less than the number of buckets: " + String.Base10Int2String(search.numBuckets as int)));
286+
var nBucket := (bucket.value as nat) as BucketNumber;
287+
288+
var bar :- ExtractBucketQueries(values2);
289+
var (values3, queries) := bar;
290+
if queries.Some? {
291+
:- Need(0 < queries.value <= search.numBuckets as uint32, E(BucketQueriesName + " specified in FilterExpression was " + String.Base10Int2String(queries.value as int) + " must be greater than zero and less than or equal to the number of buckets: " + String.Base10Int2String(search.numBuckets as int)));
292+
:- Need(bucket.value < queries.value, E(BucketName + " value of " + String.Base10Int2String(bucket.value as int) + " should have been less than the " + BucketQueriesName + " value of " + String.Base10Int2String(queries.value as int)));
293+
var nQueries := (queries.value as nat) as BucketCount;
294+
return Success((values3, nBucket, Some(nQueries)));
295+
} else {
296+
return Success((values2, nBucket, None));
297+
}
286298
}
287299

288300
:- Need(values.None? || BucketQueriesName !in values.value, E(""));
@@ -317,7 +329,7 @@ module DynamoDBSupport {
317329
var foo :- ExtractBucket(search.value.curr(), req.FilterExpression, req.KeyConditionExpression, req.ExpressionAttributeNames, req.ExpressionAttributeValues, actions);
318330
var (newValues, bucket, bucket_queries) := foo;
319331
var oldContext := Filter.ExprContext(req.KeyConditionExpression, req.FilterExpression, newValues, req.ExpressionAttributeNames);
320-
var newContext :- Filter.Beaconize(search.value.curr(), oldContext, keyId, bucket);
332+
var newContext :- Filter.DoBeaconize(search.value.curr(), oldContext, keyId, bucket, bucket_queries);
321333
return Success(req.(
322334
KeyConditionExpression := newContext.keyExpr,
323335
FilterExpression := newContext.filterExpr,
@@ -390,7 +402,7 @@ module DynamoDBSupport {
390402
var foo :- ExtractBucket(search.value.curr(), req.FilterExpression, None, req.ExpressionAttributeNames, req.ExpressionAttributeValues, actions);
391403
var (newValues, bucket, bucket_queries) := foo;
392404
var context := Filter.ExprContext(None, req.FilterExpression, newValues, req.ExpressionAttributeNames);
393-
var newContext :- Filter.Beaconize(search.value.curr(), context, keyId, bucket);
405+
var newContext :- Filter.DoBeaconize(search.value.curr(), context, keyId, bucket, bucket_queries);
394406
return Success(req.(
395407
FilterExpression := newContext.filterExpr,
396408
ExpressionAttributeNames := newContext.names,

DynamoDbEncryption/dafny/DynamoDbEncryption/src/FilterExpr.dfy

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
• e.g. transform plain expression "A = B" into beacon expression "aws_dbe_b_A = beacon(B)"
1414
1515
datatype ExprContext = ExprContext (
16-
expr : Option<DDB.ConditionExpression>,
16+
keyExpr : Option<DDB.KeyExpression>,
17+
filterExpr : Option<DDB.ConditionExpression>,
1718
values: Option<DDB.ExpressionAttributeValueMap>,
1819
names : Option<DDB.ExpressionAttributeNameMap>
1920
)
@@ -1745,6 +1746,57 @@ module DynamoDBFilterExpr {
17451746
names : Option<DDB.ExpressionAttributeNameMap>
17461747
)
17471748

1749+
method DoBeaconize(
1750+
b : SI.BeaconVersion,
1751+
context : ExprContext,
1752+
keyId : MaybeKeyId,
1753+
bucket : BucketNumber,
1754+
queries : Option<BucketCount>
1755+
)
1756+
returns (output : Result<ExprContext, Error>)
1757+
requires b.ValidState()
1758+
requires bucket < b.numBuckets
1759+
requires queries.Some? ==> bucket < queries.value <= b.numBuckets
1760+
ensures b.ValidState()
1761+
modifies b.Modifies()
1762+
{
1763+
if queries.None? || queries.value == b.numBuckets || (b.numBuckets - bucket) <= queries.value {
1764+
output := Beaconize(b, context, keyId, bucket);
1765+
} else {
1766+
var curr_bucket : BucketNumber := bucket;
1767+
var exprs : seq<string> := [];
1768+
var tmpOutput : ExprContext := ExprContext(None, None, None, None);
1769+
while curr_bucket < b.numBuckets
1770+
invariant b.ValidState()
1771+
{
1772+
tmpOutput :- Beaconize(b, context, keyId, curr_bucket);
1773+
if tmpOutput.filterExpr.Some? {
1774+
if tmpOutput.filterExpr.value !in exprs {
1775+
exprs := exprs + [tmpOutput.filterExpr.value];
1776+
}
1777+
}
1778+
if (b.numBuckets - curr_bucket) <= queries.value {
1779+
break;
1780+
} else {
1781+
curr_bucket := curr_bucket + queries.value;
1782+
}
1783+
}
1784+
if |exprs| < 2 {
1785+
return Success(tmpOutput);
1786+
} else {
1787+
var new_filter : string := "";
1788+
SequenceIsSafeBecauseItIsInMemory(exprs);
1789+
for i : uint64 := 0 to |exprs| as uint64 {
1790+
if i != 0 {
1791+
new_filter := new_filter + " OR ";
1792+
}
1793+
new_filter := new_filter + "(" + exprs[i] + ")";
1794+
}
1795+
return Success(tmpOutput.(filterExpr := Some(new_filter)));
1796+
}
1797+
}
1798+
}
1799+
17481800
// transform plain expression "A = B" into beacon expression "aws_dbe_b_A = beacon(B)"
17491801
// if naked == true, it becomes "aws_dbe_b_A = B"
17501802
method Beaconize(

DynamoDbEncryption/dafny/DynamoDbEncryption/src/SearchInfo.dfy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ module SearchableEncryptionInfo {
722722
beacons : BeaconMap,
723723
virtualFields : VirtualFieldMap,
724724
actions : AttributeActions,
725-
numBuckets : uint32
725+
numBuckets : BucketCount
726726
)
727727
: (ret : Result<ValidBeaconVersion, Error>)
728728
requires version == 1
@@ -750,7 +750,7 @@ module SearchableEncryptionInfo {
750750
beaconNames : seq<string>,
751751
stdNames : seq<string>,
752752
encryptedFields : set<string>,
753-
numBuckets : uint32
753+
numBuckets : BucketCount
754754
) {
755755

756756
function Modifies() : set<object>

0 commit comments

Comments
 (0)