@@ -42,16 +42,16 @@ module BaseBeacon {
4242 // = specification/searchable-encryption/beacons.md#basichash
4343 // = type=implication
4444 // # * 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 )
4646 : (ret : Result< string , Error> )
4747 ensures ret. Success? ==>
4848 // = specification/searchable-encryption/beacons.md#basichash
4949 // = type=implication
5050 // # * basicHash MUST produce a non-empty string as output.
5151 && |ret. value| > 0
5252
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;
5555
5656 // = specification/searchable-encryption/beacons.md#basichash
5757 // = type=implication
@@ -64,19 +64,19 @@ module BaseBeacon {
6464 && |ret. value| == (((length as uint8) + 3) / 4) as nat
6565
6666 {
67- var hash :- getHmac (val, key);
67+ var hash :- getHmac (val + bucket , key);
6868 Success (BytesToHex(hash, length))
6969 }
7070
7171 // 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> )
7373 ensures res. Success? ==> |res. value| > 0
7474 {
7575 var str := UTF8. Encode (val);
7676 if str. Failure? then
7777 Failure (E(str.error))
7878 else
79- hash (str.value, key, length)
79+ hash (str.value, key, length, bucket )
8080 }
8181
8282 // calculate the HMAC for some bytes
@@ -142,16 +142,16 @@ module BaseBeacon {
142142 asSet : bool ,
143143 share : Option <string >
144144 ) {
145- function method {:opaque} hash (val : Bytes , key : Bytes )
145+ function method {:opaque} hash (val : Bytes , key : Bytes , bucket : Bytes )
146146 : (ret : Result< string , Error> )
147147 ensures ret. Success? ==>
148148 && |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
151151
152152 && |ret. value| == (((length as uint8) + 3) / 4) as nat
153153 {
154- base. hash (val, key, length)
154+ base. hash (val, key, length, bucket )
155155 }
156156
157157 // return the name of the hmac key to use
@@ -170,7 +170,7 @@ module BaseBeacon {
170170 // = type=implication
171171 // # * string hash MUST take a string and some [key materials](./search-config.md#get-beacon-key-materials)
172172 // # 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> )
174174 ensures res. Success? ==> |res. value| > 0
175175
176176 // = specification/searchable-encryption/beacons.md#string-hash
@@ -182,28 +182,28 @@ module BaseBeacon {
182182 && keyName () in keys
183183 && UTF8. Encode (val). Success?
184184 && 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
187187 {
188188 :- Need (keyName() in keys, E ("Internal Error, no key for " + keyName()));
189189 var str := UTF8. Encode (val);
190190 if str. Failure? then
191191 Failure (E(str.error))
192192 else
193- hash (str.value, keys[keyName()])
193+ hash (str.value, keys[keyName()], bucket )
194194 }
195195
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> )
197197 ensures ret. Success? ==> ret. value. SS?
198198 ensures ! value. SS? && ! value. NS? && ! value. BS? ==> ret. Failure?
199199 ensures ret. Success? ==> HasNoDuplicates (ret.value.SS)
200200 {
201201 reveal HasNoDuplicates ();
202202 assert HasNoDuplicates< string > ([]);
203203 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 )
207207 case _ => Failure (E("Beacon " + base.name + " has style AsSet, but attribute has type " + AttrTypeToStr(value) + ". "))
208208 };
209209 Success (DDB.AttributeValue.SS(beaconSeq))
@@ -212,22 +212,22 @@ module BaseBeacon {
212212 // = specification/searchable-encryption/beacons.md#value-for-a-standard-beacon
213213 // = type=implication
214214 // # * 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> )
216216 // = specification/searchable-encryption/beacons.md#value-for-a-standard-beacon
217217 // = type=implication
218218 // # * If this beacon is marked AsSet then this operation MUST return the
219219 // # [set value](#value-for-a-set-standard-beacon),
220220 // # 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 )
223223 {
224224 if asSet then
225- getHashSet (item, key)
225+ getHashSet (item, key, bucket )
226226 else
227- getHashNonSet (item, vf, key)
227+ getHashNonSet (item, vf, key, bucket )
228228 }
229229
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> )
231231 requires asSet
232232 ensures ret. Success? ==>
233233 // = specification/searchable-encryption/beacons.md#value-for-a-set-standard-beacon
@@ -254,10 +254,10 @@ module BaseBeacon {
254254 // = specification/searchable-encryption/beacons.md#asset-initialization
255255 // # * The Standard Beacon MUST be stored in the item as a Set,
256256 // # 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 );
258258 Success (Some(setValue))
259259 }
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> )
261261 requires ! asSet
262262 ensures ret. Success? ==>
263263 // = specification/searchable-encryption/beacons.md#value-for-a-non-set-standard-beacon
@@ -276,17 +276,17 @@ module BaseBeacon {
276276 // = type=implication
277277 // # * This operation MUST convert the attribute value of the associated field to
278278 // # 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))
280280 // = specification/searchable-encryption/beacons.md#value-for-a-non-set-standard-beacon
281281 // = type=implication
282282 // # * 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))
284284 {
285285 var bytes :- VirtToBytes (loc, item, vf);
286286 if bytes. None? then
287287 Success (None)
288288 else
289- var res :- hash (bytes.value, key);
289+ var res :- hash (bytes.value, key, bucket );
290290 Success (Some(DDB.AttributeValue.S(res)))
291291 }
292292
@@ -303,7 +303,7 @@ module BaseBeacon {
303303 [loc[0]. key]
304304 }
305305
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 > := [])
307307 : (ret : Result< seq < string > , Error> )
308308 requires HasNoDuplicates (converted)
309309 ensures ret. Success? ==> HasNoDuplicates (ret.value)
@@ -312,15 +312,15 @@ module BaseBeacon {
312312 Success (converted)
313313 else
314314 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 );
316316 if h in converted then
317- BeaconizeStringSet (value[1..], key, converted)
317+ BeaconizeStringSet (value[1..], key, bucket, converted)
318318 else
319319 reveal HasNoDuplicates ();
320- BeaconizeStringSet (value[1..], key, converted + [h])
320+ BeaconizeStringSet (value[1..], key, bucket, converted + [h])
321321 }
322322
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 > := [])
324324 : (ret : Result< seq < string > , Error> )
325325 requires HasNoDuplicates (converted)
326326 ensures ret. Success? ==> HasNoDuplicates (ret.value)
@@ -329,15 +329,15 @@ module BaseBeacon {
329329 Success (converted)
330330 else
331331 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 );
333333 if h in converted then
334- BeaconizeNumberSet (value[1..], key, converted)
334+ BeaconizeNumberSet (value[1..], key, bucket, converted)
335335 else
336336 reveal HasNoDuplicates ();
337- BeaconizeNumberSet (value[1..], key, converted + [h])
337+ BeaconizeNumberSet (value[1..], key, bucket, converted + [h])
338338 }
339339
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 > := [])
341341 : (ret : Result< seq < string > , Error> )
342342 requires HasNoDuplicates (converted)
343343 ensures ret. Success? ==> HasNoDuplicates (ret.value)
@@ -346,32 +346,32 @@ module BaseBeacon {
346346 Success (converted)
347347 else
348348 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 );
350350 if h in converted then
351- BeaconizeBinarySet (value[1..], key, converted)
351+ BeaconizeBinarySet (value[1..], key, bucket, converted)
352352 else
353353 reveal HasNoDuplicates ();
354- BeaconizeBinarySet (value[1..], key, converted + [h])
354+ BeaconizeBinarySet (value[1..], key, bucket, converted + [h])
355355 }
356356
357- function method GetBeaconValue (value : DDB .AttributeValue, key : Bytes , forContains : bool )
357+ function method GetBeaconValue (value : DDB .AttributeValue, key : Bytes , forContains : bool , bucket : Bytes )
358358 : (ret : Result< DDB. AttributeValue, Error> )
359359 {
360360 // in query, allow beaconization of terminals
361361 if asSet && ! value. S? && ! value. N? && ! value. B? then
362- ValueToSet (value, key)
362+ ValueToSet (value, key, bucket )
363363 else if forContains && (value. SS? || value. NS? || value. BS?) then
364- ValueToSet (value, key)
364+ ValueToSet (value, key, bucket )
365365 else
366366 var bytes :- DynamoToStruct. TopLevelAttributeToBytes (value). MapFailure (e => E(e));
367- var h :- hash (bytes, key);
367+ var h :- hash (bytes, key, bucket );
368368 Success (DDB.AttributeValue.S(h))
369369 }
370370
371371 // = specification/searchable-encryption/beacons.md#getpart-for-a-standard-beacon
372372 // = type=implication
373373 // # * 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 )
375375 : (ret : Result< string , Error> )
376376 requires 0 < |val|
377377
@@ -382,10 +382,10 @@ module BaseBeacon {
382382 // = specification/searchable-encryption/beacons.md#getpart-for-a-standard-beacon
383383 // = type=implication
384384 // # * 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
387387 {
388- base. hash (val, key, length)
388+ base. hash (val, key, length, bucket )
389389 }
390390 predicate ValidState () {true }
391391 }
0 commit comments