Skip to content
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

Performance improvements and new sample apps. #434

Merged
merged 1 commit into from
Jan 24, 2024
Merged

Performance improvements and new sample apps. #434

merged 1 commit into from
Jan 24, 2024

Conversation

davidz25
Copy link
Contributor

This PR introduces two sample apps - preconsent-mdl and age-verifier-mdl - to help with pinpointing performance issues with the libraries.

This helped identify two problems making both the reader and the holder feel sluggish.

  • Calling BouncyCastle() is extremely expensive and we were doing this in a number of utility functions, including Util.coseKeyDecode(). This is fixed by using variants that pass BouncyCastle.PROVIDER_NAME instead. This also requires fixing up apps and test cases to manually register BouncyCastle at startup.

  • Determining the EC curve for a PublicKey is very expensive and also potentially fragile. Instead, modify the whole library stack to pass the curve along the public key. This is possible because we always know the curve, either if we created the key ourselves or if we received it from the reader or issuer (through COSE_Key).

There's still room for optimization but these two fixes already help a lot and the two new samples makes it easier to identify and fix other bottlenecks.

Other changes:

  • Use version catalogs in identity and identity-android.

  • Introduce DataTransportUdp as a super-low-latency data transfer method. The goal of this is to be able to pinpoint bottlenecks in non-data-transfer related code. For example, prior to the performance fixes mentioned above, it would occasionally take almost 1000ms to process DeviceEngagement and send encrypted DeviceRequest.

  • Remove reportConnectionMethodReady() as it's not needed for any of the data transfer methods in ISO 18013-5. For our two proprietary data transfer methods (DataTransportTcp and DataTransportUdp), just have connect() block on a call to the kernel to get a port number assigned.

  • Have Credential.findAuthenticationKey() also take the domain. This was really just an oversight when we added started tying authentication keys to domains.

  • Add onHandoverSelectMessageSent() callback to NfcEngagementHelper. This gives the mdoc application an opportunity to signal to the user that it's now safe to remove the device from the NFC field, for example by vibration.

Fixes Issue #387.

Test: Manually tested and all unit tests pass.

@davidz25 davidz25 force-pushed the sample-apps branch 5 times, most recently from 7d023a8 to 6b1f8e8 Compare December 13, 2023 13:41
@davidz25 davidz25 force-pushed the sample-apps branch 2 times, most recently from 412d14a to 569501f Compare January 23, 2024 16:33
Copy link
Contributor

@suzannajiwani suzannajiwani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, just some minor nits

This PR introduces two sample apps - `preconsent-mdl` and
`age-verifier-mdl` - to help with pinpointing performance issues with
the libraries.

This helped identify two problems making both the reader and the
holder feel sluggish.

- Calling `BouncyCastle()` is extremely expensive and we were doing
  this in a number of utility functions, including `Util.coseKeyDecode()`.
  This is fixed by using variants that pass `BouncyCastle.PROVIDER_NAME` instead.
  This also requires fixing up apps and test cases to manually register
  BouncyCastle at startup.

- Determining the EC curve for a `PublicKey` is very expensive and
  also potentially fragile. Instead, modify the whole library stack to
  pass the curve along the public key. This is possible because we
  always know the curve, either if we created the key ourselves or if
  we received it from the reader or issuer (through COSE_Key).

There's still room for optimization but these two fixes already help a
lot and the two new samples makes it easier to identify and fix other
bottlenecks.

Other changes:

- Use version catalogs in identity and identity-android.

- Introduce DataTransportUdp as a super-low-latency data transfer
  method. The goal of this is to be able to pinpoint bottlenecks
  in non-data-transfer related code. For example, prior to the
  performance fixes mentioned above, it would occasionally take
  almost 1000ms to process DeviceEngagement and send encrypted
  DeviceRequest.

- Remove reportConnectionMethodReady() as it's not needed for
  any of the data transfer methods in ISO 18013-5. For our two
  proprietary data transfer methods (DataTransportTcp and
  DataTransportUdp), just have `connect()` block on a call to
  the kernel to get a port number assigned.

- Have `Credential.findAuthenticationKey()` also take the domain.
  This was really just an oversight when we added started tying
  authentication keys to domains.

- Add `onHandoverSelectMessageSent()` callback to `NfcEngagementHelper`.
  This gives the mdoc application an opportunity to signal to the
  user that it's now safe to remove the device from the NFC field,
  for example by vibration.

- In `VerificationHelper`, add API to allow the application to
  specify which connection methods to offer via NFC Negotiated
  Handover (this was a long-standing TODO). Also, pre-warm
  these connections meaning that for "mdoc central client mode"
  the reader will advertise the BLE UUID before interaction
  happens. This means that the BLE stack in the holder's device
  will have a chance to cache this UUID and MAC for a faster
  connection when in the vicinity.

- Add new experimental option to `DataTransportOptions` for the
  application to specify whether to include the BLE L2CAP PSM in
  the engagement data. Also add code to directly connect to L2CAP
  in case the PSM was found in the engagement data. Since this is
  not standardized yet, default this setting to off.

Fixes Issue #387.

Test: Manually tested and all unit tests pass.
Signed-off-by: David Zeuthen <[email protected]>
@davidz25 davidz25 merged commit ca5956a into main Jan 24, 2024
5 checks passed
@davidz25 davidz25 deleted the sample-apps branch January 24, 2024 15:51
davidz25 added a commit that referenced this pull request Apr 19, 2024
At while ago (PR #434) we introduced the concept of warmed-up
transports when using Negotiated Handover to speed up
presentations. Unfortunately this introduced a bug where we didn't set
the right BLEIdent on the GATT Server when using mdoc BLE central
client mode. This caused a problem with some mdoc implementations
which fails if the BLEIdent value isn't what they expect.

Our own mdoc implementation will only warn if the BLEIdent read from
the GATT server isn't what is expects. This behavior has existed for a
while but it originally used to error out. Implementations using an
old version of our code thus may not currently work with our current
VerificationHelper if they're using Negotiated Handover.

Fix this by setting the BLEIdent on a warmed-up connection right after
receiving Handover Select. Tested this fix against an implementation
known to fail if the BLEIdent isn't it should be.

Test: Manually tested.
Signed-off-by: David Zeuthen <[email protected]>
suzannajiwani pushed a commit that referenced this pull request Apr 22, 2024
At while ago (PR #434) we introduced the concept of warmed-up
transports when using Negotiated Handover to speed up
presentations. Unfortunately this introduced a bug where we didn't set
the right BLEIdent on the GATT Server when using mdoc BLE central
client mode. This caused a problem with some mdoc implementations
which fails if the BLEIdent value isn't what they expect.

Our own mdoc implementation will only warn if the BLEIdent read from
the GATT server isn't what is expects. This behavior has existed for a
while but it originally used to error out. Implementations using an
old version of our code thus may not currently work with our current
VerificationHelper if they're using Negotiated Handover.

Fix this by setting the BLEIdent on a warmed-up connection right after
receiving Handover Select. Tested this fix against an implementation
known to fail if the BLEIdent isn't it should be.

Test: Manually tested.

Signed-off-by: David Zeuthen <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants