Skip to content

Commit 79e1306

Browse files
authored
chore: improve performance (#764)
1 parent 5ea20b7 commit 79e1306

File tree

21 files changed

+980
-136
lines changed

21 files changed

+980
-136
lines changed

.github/workflows/library_rust_tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,9 @@ jobs:
202202
unzip valid-Net-4.0.0.zip -d valid-Net-4.0.0
203203
204204
- name: Test Rust
205-
working-directory: ${{ matrix.library }}
205+
working-directory: ${{ matrix.library }}/runtimes/rust
206206
shell: bash
207207
run: |
208208
# Without this, running test vectors fails due to `fatal runtime error: stack overflow`
209209
export RUST_MIN_STACK=104857600
210-
make test_rust
210+
cargo test --release -- --test-threads 1 --nocapture

AwsEncryptionSDK/dafny/AwsEncryptionSdk/src/MessageBody.dfy

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,27 @@ module MessageBody {
147147
&& MessageFramesAreForTheSameMessage(regularFrames)
148148
}
149149

150+
lemma IsMessageRegularFramesCanBeSplit(
151+
regularFrames: seq<Frames.RegularFrame>
152+
)
153+
requires IsMessageRegularFrames(regularFrames)
154+
ensures forall accumulator
155+
| accumulator <= regularFrames
156+
::
157+
&& IsMessageRegularFrames(accumulator)
158+
{
159+
forall accumulator
160+
| accumulator <= regularFrames
161+
ensures
162+
&& IsMessageRegularFrames(accumulator)
163+
{
164+
assert |accumulator| <= |regularFrames|;
165+
assert 0 <= |accumulator| < ENDFRAME_SEQUENCE_NUMBER as nat;
166+
assume {:axiom} MessageFramesAreMonotonic(accumulator);
167+
assert MessageFramesAreForTheSameMessage(accumulator);
168+
}
169+
}
170+
150171
type NonFramedMessage = Frames.NonFramed
151172

152173
datatype FramedMessageBody = FramedMessageBody(
@@ -939,7 +960,7 @@ module MessageBody {
939960
WriteMessageRegularFrames(body.regularFrames) + Frames.WriteFinalFrame(body.finalFrame)
940961
}
941962

942-
function method WriteMessageRegularFrames(
963+
function WriteMessageRegularFrames(
943964
frames: MessageRegularFrames
944965
)
945966
:(ret: seq<uint8>)
@@ -954,6 +975,28 @@ module MessageBody {
954975
WriteMessageRegularFrames(Seq.DropLast(frames))
955976
+ Frames.WriteRegularFrame(Seq.Last(frames))
956977
}
978+
by method { // because Seq.DropLast makes a full copy
979+
var result : seq<uint8> := [];
980+
for i := 0 to |frames|
981+
invariant IsMessageRegularFrames(frames)
982+
invariant IsMessageRegularFrames(frames[..i])
983+
invariant result == WriteMessageRegularFrames(frames[..i])
984+
{
985+
result := result + Frames.WriteRegularFrame(frames[i]);
986+
assert result == WriteMessageRegularFrames(frames[..i]) + Frames.WriteRegularFrame(frames[i]);
987+
assert Seq.DropLast(frames[..i+1]) == frames[..i];
988+
assert result == WriteMessageRegularFrames(Seq.DropLast(frames[..i+1])) + Frames.WriteRegularFrame(Seq.Last(frames[..i+1]));
989+
IsMessageRegularFramesCanBeSplit(frames);
990+
assert IsMessageRegularFrames(frames[..i]);
991+
assert IsMessageRegularFrames(frames[..i+1]);
992+
assert result == WriteMessageRegularFrames(frames[..i+1]);
993+
994+
}
995+
assert result == WriteMessageRegularFrames(frames[..|frames|]);
996+
assert frames == frames[..|frames|];
997+
assert result == WriteMessageRegularFrames(frames);
998+
return result;
999+
}
9571000

9581001
function method {:recursive} {:vcs_split_on_every_assert} ReadFramedMessageBody(
9591002
buffer: ReadableBuffer,

AwsEncryptionSDK/dafny/AwsEncryptionSdk/src/Serialize/EncryptedDataKeys.dfy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module {:options "/functionSyntax:4" } EncryptedDataKeys {
2222
+ WriteShortLengthSeq(edk.ciphertext)
2323
}
2424

25+
// Seq.DropLast makes a full copy, but we seldom have more than one or two data keys,
26+
// so no point in optimizing away the copy.
2527
function {:tailrecursion} WriteEncryptedDataKeys(
2628
edks: ESDKEncryptedDataKeys
2729
):

AwsEncryptionSDK/dafny/AwsEncryptionSdk/src/Serialize/EncryptionContext.dfy

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ module {:options "/functionSyntax:4" } EncryptionContext {
387387
WriteUint16(|ec| as uint16) + WriteAADPairs(ec)
388388
}
389389

390-
function {:tailrecursion} WriteAADPairs(
390+
function WriteAADPairs(
391391
ec: ESDKCanonicalEncryptionContext
392392
):
393393
(ret: seq<uint8>)
@@ -406,6 +406,28 @@ module {:options "/functionSyntax:4" } EncryptionContext {
406406
assert LinearLength(Seq.DropLast(ec)) < LinearLength(ec);
407407
WriteAADPairs(Seq.DropLast(ec)) + WriteAADPair(Seq.Last(ec))
408408
}
409+
by method { // because Seq.DropLast makes a full copy
410+
var result : seq<uint8> := [];
411+
for i := 0 to |ec|
412+
invariant ESDKCanonicalEncryptionContext?(ec)
413+
invariant ESDKCanonicalEncryptionContext?(ec[..i])
414+
invariant result == WriteAADPairs(ec[..i])
415+
{
416+
result := result + WriteAADPair(ec[i]);
417+
ESDKCanonicalEncryptionContextCanBeSplit(ec);
418+
assert result == WriteAADPairs(ec[..i]) + WriteAADPair(ec[i]);
419+
assert Seq.DropLast(ec[..i+1]) == ec[..i];
420+
assert result == WriteAADPairs(Seq.DropLast(ec[..i+1])) + WriteAADPair(Seq.Last(ec[..i+1]));
421+
assert ESDKCanonicalEncryptionContext?(ec[..i]);
422+
assert ESDKCanonicalEncryptionContext?(ec[..i+1]);
423+
assert result == WriteAADPairs(ec[..i+1]);
424+
425+
}
426+
assert result == WriteAADPairs(ec[..|ec|]);
427+
assert ec == ec[..|ec|];
428+
assert result == WriteAADPairs(ec);
429+
return result;
430+
}
409431

410432
//= compliance/data-format/message-header.txt#2.5.1.7.2.2
411433
//# The following table describes the fields that form each key value

AwsEncryptionSDK/dafny/AwsEncryptionSdk/src/Serialize/SerializableTypes.dfy

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ module SerializableTypes {
149149
==> pairs[i].key != pairs[j].key)
150150
}
151151

152-
function method {:tailrecursion} LinearLength(
152+
function LinearLength(
153153
pairs: Linear<UTF8.ValidUTF8Bytes, UTF8.ValidUTF8Bytes>
154154
):
155155
(ret: nat)
@@ -162,6 +162,24 @@ module SerializableTypes {
162162
else
163163
LinearLength(Seq.DropLast(pairs)) + PairLength(Seq.Last(pairs))
164164
}
165+
by method { // because Seq.DropLast makes a full copy
166+
var result : nat := 0;
167+
for i := 0 to |pairs|
168+
invariant result == LinearLength(pairs[..i])
169+
{
170+
result := result + PairLength(pairs[i]);
171+
assert result == LinearLength(pairs[..i]) + PairLength(pairs[i]);
172+
assert Seq.DropLast(pairs[..i+1]) == pairs[..i];
173+
assert result == LinearLength(Seq.DropLast(pairs[..i+1])) + PairLength(Seq.Last(pairs[..i+1]));
174+
assert result == LinearLength(pairs[..i+1]);
175+
176+
}
177+
assert result == LinearLength(pairs[..|pairs|]);
178+
assert pairs == pairs[..|pairs|];
179+
assert result == LinearLength(pairs);
180+
return result;
181+
}
182+
165183

166184
function method PairLength(
167185
pair: Pair<UTF8.ValidUTF8Bytes, UTF8.ValidUTF8Bytes>

AwsEncryptionSDK/runtimes/go/ImplementationFromDafny-go/awscryptographyencryptionsdksmithygenerated/to_dafny.go

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

AwsEncryptionSDK/runtimes/go/ImplementationFromDafny-go/awscryptographyencryptionsdksmithygenerated/to_native.go

Lines changed: 20 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

AwsEncryptionSDK/runtimes/go/TestsFromDafny-go/awscryptographyencryptionsdksmithygenerated/to_dafny.go

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)