@@ -42,16 +42,16 @@ module BaseBeacon {
42
42
// = specification/searchable-encryption/beacons.md#basichash
43
43
// = type=implication
44
44
// # * basicHash MUST take an [hmac key](./search-config.md#hmac-key-generation), a [beacon length](#beacon-length) and a sequence of bytes as input.
45
- function method {:opaque} hash (val : Bytes , key : Bytes , length : BeaconLength )
45
+ function method {:opaque} hash (val : Bytes , key : Bytes , length : BeaconLength , bucket : Bytes )
46
46
: (ret : Result< string , Error> )
47
47
ensures ret. Success? ==>
48
48
// = specification/searchable-encryption/beacons.md#basichash
49
49
// = type=implication
50
50
// # * basicHash MUST produce a non-empty string as output.
51
51
&& |ret. value| > 0
52
52
53
- && getHmac (val, key). Success?
54
- && var hash := getHmac (val, key). value;
53
+ && getHmac (val+bucket , key). Success?
54
+ && var hash := getHmac (val+bucket , key). value;
55
55
56
56
// = specification/searchable-encryption/beacons.md#basichash
57
57
// = type=implication
@@ -64,19 +64,19 @@ module BaseBeacon {
64
64
&& |ret. value| == (((length as uint8) + 3) / 4) as nat
65
65
66
66
{
67
- var hash :- getHmac (val, key);
67
+ var hash :- getHmac (val + bucket , key);
68
68
Success (BytesToHex(hash, length))
69
69
}
70
70
71
71
// Get the standard hash for the UTF8 encoded representation of this string.
72
- function method {:opaque} hashStr (val : string , key : Bytes , length : BeaconLength ) : (res : Result< string , Error> )
72
+ function method {:opaque} hashStr (val : string , key : Bytes , length : BeaconLength , bucket : Bytes ) : (res : Result< string , Error> )
73
73
ensures res. Success? ==> |res. value| > 0
74
74
{
75
75
var str := UTF8. Encode (val);
76
76
if str. Failure? then
77
77
Failure (E(str.error))
78
78
else
79
- hash (str.value, key, length)
79
+ hash (str.value, key, length, bucket )
80
80
}
81
81
82
82
// calculate the HMAC for some bytes
@@ -142,16 +142,16 @@ module BaseBeacon {
142
142
asSet : bool ,
143
143
share : Option <string >
144
144
) {
145
- function method {:opaque} hash (val : Bytes , key : Bytes )
145
+ function method {:opaque} hash (val : Bytes , key : Bytes , bucket : Bytes )
146
146
: (ret : Result< string , Error> )
147
147
ensures ret. Success? ==>
148
148
&& |ret. value| > 0
149
- && base. hash (val, key, length). Success?
150
- && ret. value == base. hash (val, key, length). value
149
+ && base. hash (val, key, length, bucket ). Success?
150
+ && ret. value == base. hash (val, key, length, bucket ). value
151
151
152
152
&& |ret. value| == (((length as uint8) + 3) / 4) as nat
153
153
{
154
- base. hash (val, key, length)
154
+ base. hash (val, key, length, bucket )
155
155
}
156
156
157
157
// return the name of the hmac key to use
@@ -170,7 +170,7 @@ module BaseBeacon {
170
170
// = type=implication
171
171
// # * string hash MUST take a string and some [key materials](./search-config.md#get-beacon-key-materials)
172
172
// # as input, and produce a string as output.
173
- function method {:opaque} hashStr (val : string , keys : HmacKeyMap ) : (res : Result< string , Error> )
173
+ function method {:opaque} hashStr (val : string , keys : HmacKeyMap , bucket : Bytes ) : (res : Result< string , Error> )
174
174
ensures res. Success? ==> |res. value| > 0
175
175
176
176
// = specification/searchable-encryption/beacons.md#string-hash
@@ -182,28 +182,28 @@ module BaseBeacon {
182
182
&& keyName () in keys
183
183
&& UTF8. Encode (val). Success?
184
184
&& var str := UTF8. Encode (val). value;
185
- && hash (str, keys[keyName()]). Success?
186
- && res. value == hash (str, keys[keyName()]). value
185
+ && hash (str, keys[keyName()], bucket ). Success?
186
+ && res. value == hash (str, keys[keyName()], bucket ). value
187
187
{
188
188
:- Need (keyName() in keys, E ("Internal Error, no key for " + keyName()));
189
189
var str := UTF8. Encode (val);
190
190
if str. Failure? then
191
191
Failure (E(str.error))
192
192
else
193
- hash (str.value, keys[keyName()])
193
+ hash (str.value, keys[keyName()], bucket )
194
194
}
195
195
196
- function method {:opaque} ValueToSet (value : DDB .AttributeValue, key : Bytes ) : (ret : Result< DDB. AttributeValue, Error> )
196
+ function method {:opaque} ValueToSet (value : DDB .AttributeValue, key : Bytes , bucket : Bytes ) : (ret : Result< DDB. AttributeValue, Error> )
197
197
ensures ret. Success? ==> ret. value. SS?
198
198
ensures ! value. SS? && ! value. NS? && ! value. BS? ==> ret. Failure?
199
199
ensures ret. Success? ==> HasNoDuplicates (ret.value.SS)
200
200
{
201
201
reveal HasNoDuplicates ();
202
202
assert HasNoDuplicates< string > ([]);
203
203
var beaconSeq :- match value {
204
- case SS (n) => BeaconizeStringSet (n, key)
205
- case NS (n) => BeaconizeNumberSet (n, key)
206
- case BS (n) => BeaconizeBinarySet (n, key)
204
+ case SS (n) => BeaconizeStringSet (n, key, bucket )
205
+ case NS (n) => BeaconizeNumberSet (n, key, bucket )
206
+ case BS (n) => BeaconizeBinarySet (n, key, bucket )
207
207
case _ => Failure (E("Beacon " + base.name + " has style AsSet, but attribute has type " + AttrTypeToStr(value) + ". "))
208
208
};
209
209
Success (DDB.AttributeValue.SS(beaconSeq))
@@ -212,22 +212,22 @@ module BaseBeacon {
212
212
// = specification/searchable-encryption/beacons.md#value-for-a-standard-beacon
213
213
// = type=implication
214
214
// # * This operation MUST take an [hmac key](./search-config.md#hmac-key-generation), a record as input, and produce an optional [AttributeValue](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html).
215
- function method {:opaque} getHash (item : DDB .AttributeMap, vf : VirtualFieldMap , key : Bytes ) : (ret : Result< Option< DDB. AttributeValue> , Error> )
215
+ function method {:opaque} getHash (item : DDB .AttributeMap, vf : VirtualFieldMap , key : Bytes , bucket : Bytes ) : (ret : Result< Option< DDB. AttributeValue> , Error> )
216
216
// = specification/searchable-encryption/beacons.md#value-for-a-standard-beacon
217
217
// = type=implication
218
218
// # * If this beacon is marked AsSet then this operation MUST return the
219
219
// # [set value](#value-for-a-set-standard-beacon),
220
220
// # otherwise it MUST return the [non-set value](#value-for-a-non-set-standard-beacon)
221
- ensures asSet ==> ret == getHashSet (item, key)
222
- ensures ! asSet ==> ret == getHashNonSet (item, vf, key)
221
+ ensures asSet ==> ret == getHashSet (item, key, bucket )
222
+ ensures ! asSet ==> ret == getHashNonSet (item, vf, key, bucket )
223
223
{
224
224
if asSet then
225
- getHashSet (item, key)
225
+ getHashSet (item, key, bucket )
226
226
else
227
- getHashNonSet (item, vf, key)
227
+ getHashNonSet (item, vf, key, bucket )
228
228
}
229
229
230
- function method {:opaque} getHashSet (item : DDB .AttributeMap, key : Bytes ) : (ret : Result< Option< DDB. AttributeValue> , Error> )
230
+ function method {:opaque} getHashSet (item : DDB .AttributeMap, key : Bytes , bucket : Bytes ) : (ret : Result< Option< DDB. AttributeValue> , Error> )
231
231
requires asSet
232
232
ensures ret. Success? ==>
233
233
// = specification/searchable-encryption/beacons.md#value-for-a-set-standard-beacon
@@ -254,10 +254,10 @@ module BaseBeacon {
254
254
// = specification/searchable-encryption/beacons.md#asset-initialization
255
255
// # * The Standard Beacon MUST be stored in the item as a Set,
256
256
// # comprised of the [beacon values](#beacon-value) of all the elements in the original Set.
257
- var setValue :- ValueToSet (value.value, key);
257
+ var setValue :- ValueToSet (value.value, key, bucket );
258
258
Success (Some(setValue))
259
259
}
260
- function method {:opaque} getHashNonSet (item : DDB .AttributeMap, vf : VirtualFieldMap , key : Bytes ) : (ret : Result< Option< DDB. AttributeValue> , Error> )
260
+ function method {:opaque} getHashNonSet (item : DDB .AttributeMap, vf : VirtualFieldMap , key : Bytes , bucket : Bytes ) : (ret : Result< Option< DDB. AttributeValue> , Error> )
261
261
requires ! asSet
262
262
ensures ret. Success? ==>
263
263
// = specification/searchable-encryption/beacons.md#value-for-a-non-set-standard-beacon
@@ -276,17 +276,17 @@ module BaseBeacon {
276
276
// = type=implication
277
277
// # * This operation MUST convert the attribute value of the associated field to
278
278
// # a sequence of bytes, as per [attribute serialization](../dynamodb-encryption-client/ddb-attribute-serialization.md).
279
- && (bytes. Some? ==> ret. value. Some? && hash (bytes.value, key). Success? && ret. value. value == DDB. AttributeValue. S (hash(bytes.value, key). value))
279
+ && (bytes. Some? ==> ret. value. Some? && hash (bytes.value, key, bucket ). Success? && ret. value. value == DDB. AttributeValue. S (hash(bytes.value, key, bucket ). value))
280
280
// = specification/searchable-encryption/beacons.md#value-for-a-non-set-standard-beacon
281
281
// = type=implication
282
282
// # * This operation MUST return the [basicHash](#basichash) of the resulting bytes and the configured [beacon length](#beacon-length).
283
- && (bytes. Some? ==> ret. value. Some? && base. hash (bytes.value, key, length). Success? && ret. value. value == DDB. AttributeValue. S (base.hash(bytes.value, key, length). value))
283
+ && (bytes. Some? ==> ret. value. Some? && base. hash (bytes.value, key, length, bucket ). Success? && ret. value. value == DDB. AttributeValue. S (base.hash(bytes.value, key, length, bucket ). value))
284
284
{
285
285
var bytes :- VirtToBytes (loc, item, vf);
286
286
if bytes. None? then
287
287
Success (None)
288
288
else
289
- var res :- hash (bytes.value, key);
289
+ var res :- hash (bytes.value, key, bucket );
290
290
Success (Some(DDB.AttributeValue.S(res)))
291
291
}
292
292
@@ -303,7 +303,7 @@ module BaseBeacon {
303
303
[loc[0]. key]
304
304
}
305
305
306
- function method {:tailrecursion} BeaconizeStringSet (value : DDB .StringSetAttributeValue, key : Bytes , converted : seq <string > := [])
306
+ function method {:tailrecursion} BeaconizeStringSet (value : DDB .StringSetAttributeValue, key : Bytes , bucket : Bytes , converted : seq <string > := [])
307
307
: (ret : Result< seq < string > , Error> )
308
308
requires HasNoDuplicates (converted)
309
309
ensures ret. Success? ==> HasNoDuplicates (ret.value)
@@ -312,15 +312,15 @@ module BaseBeacon {
312
312
Success (converted)
313
313
else
314
314
var bytes :- DynamoToStruct. TopLevelAttributeToBytes (DDB.AttributeValue.S(value[0])). MapFailure (e => E(e));
315
- var h :- hash (bytes, key);
315
+ var h :- hash (bytes, key, bucket );
316
316
if h in converted then
317
- BeaconizeStringSet (value[1..], key, converted)
317
+ BeaconizeStringSet (value[1..], key, bucket, converted)
318
318
else
319
319
reveal HasNoDuplicates ();
320
- BeaconizeStringSet (value[1..], key, converted + [h])
320
+ BeaconizeStringSet (value[1..], key, bucket, converted + [h])
321
321
}
322
322
323
- function method {:tailrecursion} BeaconizeNumberSet (value : DDB .NumberSetAttributeValue, key : Bytes , converted : seq <string > := [])
323
+ function method {:tailrecursion} BeaconizeNumberSet (value : DDB .NumberSetAttributeValue, key : Bytes , bucket : Bytes , converted : seq <string > := [])
324
324
: (ret : Result< seq < string > , Error> )
325
325
requires HasNoDuplicates (converted)
326
326
ensures ret. Success? ==> HasNoDuplicates (ret.value)
@@ -329,15 +329,15 @@ module BaseBeacon {
329
329
Success (converted)
330
330
else
331
331
var bytes :- DynamoToStruct. TopLevelAttributeToBytes (DDB.AttributeValue.N(value[0])). MapFailure (e => E(e));
332
- var h :- hash (bytes, key);
332
+ var h :- hash (bytes, key, bucket );
333
333
if h in converted then
334
- BeaconizeNumberSet (value[1..], key, converted)
334
+ BeaconizeNumberSet (value[1..], key, bucket, converted)
335
335
else
336
336
reveal HasNoDuplicates ();
337
- BeaconizeNumberSet (value[1..], key, converted + [h])
337
+ BeaconizeNumberSet (value[1..], key, bucket, converted + [h])
338
338
}
339
339
340
- function method {:tailrecursion} BeaconizeBinarySet (value : DDB .BinarySetAttributeValue, key : Bytes , converted : seq <string > := [])
340
+ function method {:tailrecursion} BeaconizeBinarySet (value : DDB .BinarySetAttributeValue, key : Bytes , bucket : Bytes , converted : seq <string > := [])
341
341
: (ret : Result< seq < string > , Error> )
342
342
requires HasNoDuplicates (converted)
343
343
ensures ret. Success? ==> HasNoDuplicates (ret.value)
@@ -346,32 +346,32 @@ module BaseBeacon {
346
346
Success (converted)
347
347
else
348
348
var bytes :- DynamoToStruct. TopLevelAttributeToBytes (DDB.AttributeValue.B(value[0])). MapFailure (e => E(e));
349
- var h :- hash (bytes, key);
349
+ var h :- hash (bytes, key, bucket );
350
350
if h in converted then
351
- BeaconizeBinarySet (value[1..], key, converted)
351
+ BeaconizeBinarySet (value[1..], key, bucket, converted)
352
352
else
353
353
reveal HasNoDuplicates ();
354
- BeaconizeBinarySet (value[1..], key, converted + [h])
354
+ BeaconizeBinarySet (value[1..], key, bucket, converted + [h])
355
355
}
356
356
357
- function method GetBeaconValue (value : DDB .AttributeValue, key : Bytes , forContains : bool )
357
+ function method GetBeaconValue (value : DDB .AttributeValue, key : Bytes , forContains : bool , bucket : Bytes )
358
358
: (ret : Result< DDB. AttributeValue, Error> )
359
359
{
360
360
// in query, allow beaconization of terminals
361
361
if asSet && ! value. S? && ! value. N? && ! value. B? then
362
- ValueToSet (value, key)
362
+ ValueToSet (value, key, bucket )
363
363
else if forContains && (value. SS? || value. NS? || value. BS?) then
364
- ValueToSet (value, key)
364
+ ValueToSet (value, key, bucket )
365
365
else
366
366
var bytes :- DynamoToStruct. TopLevelAttributeToBytes (value). MapFailure (e => E(e));
367
- var h :- hash (bytes, key);
367
+ var h :- hash (bytes, key, bucket );
368
368
Success (DDB.AttributeValue.S(h))
369
369
}
370
370
371
371
// = specification/searchable-encryption/beacons.md#getpart-for-a-standard-beacon
372
372
// = type=implication
373
373
// # * getPart MUST take an [hmac key](./search-config.md#hmac-key-generation), a sequence of bytes as input, and produce a string.
374
- function method {:opaque} getPart (val : Bytes , key : Bytes )
374
+ function method {:opaque} getPart (val : Bytes , key : Bytes , bucket : Bytes )
375
375
: (ret : Result< string , Error> )
376
376
requires 0 < |val|
377
377
@@ -382,10 +382,10 @@ module BaseBeacon {
382
382
// = specification/searchable-encryption/beacons.md#getpart-for-a-standard-beacon
383
383
// = type=implication
384
384
// # * getPart MUST return the [basicHash](#basichash) of the input and the configured [beacon length](#beacon-length).
385
- && base. hash (val, key, length). Success?
386
- && ret. value == base. hash (val, key, length). value
385
+ && base. hash (val, key, length, bucket ). Success?
386
+ && ret. value == base. hash (val, key, length, bucket ). value
387
387
{
388
- base. hash (val, key, length)
388
+ base. hash (val, key, length, bucket )
389
389
}
390
390
predicate ValidState () {true }
391
391
}
0 commit comments