Skip to main content

Security reviews

Before release, the source code of BitTool Signer 1.0.0 was examined on each platform by two AI-assisted security reviews, each run on its own. All four reports are published in full below. None found a Critical or High issue. The iPhone reviews each found one Low issue. The Android reviews found Medium issues; four Medium-rated findings are open in the released Android 1.0.0, and three of them sit in the signing engine that both apps share.

Read the limits first
  • None is an audit by a security firm, and no human auditor was involved.
  • The Opus 5 and Opus 5.5 reviews come from the same model family that wrote or changed a material part of the code under review. The reports say they are not third-party attestation or certification.
  • The GPT-6 Astra reviews describe themselves as AI-assisted engineering reviews prepared for the project owner, not an audit-firm certification or human sign-off.
  • Both Android reports recommend fixing their open Medium findings before the app protects valuable wallets. BitTool Signer for Android 1.0.0 was released with them open; see every finding.
  • An independent third-party audit has not been done yet. The reports name it, together with testing on real devices and round trips with third-party wallets, as work that remains before holding significant funds.

BitTool Signer for iPhone​

The two reports​

Opus 5GPT-6 Astra
Date19 October 202618 October 2026 (report BTS-SEC-2026-1018-R3)
Code reviewedTag v1.0.0, commit f621372Working tree of 18 October: commit 3d706b7 plus 59 changed files and one new test
Engine reviewed (signer.js, SHA-256)6933d0d8…f210776933d0d8…f21077
MethodLine-by-line source review (3,546 lines of JavaScript, 11,858 of Swift), 11 attack probes, 4,000-case mutation test of the QR input, test suites, clean-room rebuildSource review by subsystem, comparison with the previous round, independent Bitcoin and Solana fixtures, 1,509-case mutation test, test suites, reproducible build, dependency advisories
Tests run210 engine, 168 native210 engine, 177 native and UI
Result0 Critical · 0 High · 0 Medium · 1 Low · 3 Informational0 Critical · 0 High · 0 Medium · 1 Low · 4 observations
IndependenceSelf-review by the author of much of the codeAI-assisted, prepared for the project owner

Both reviews examined the same engine file that BitTool Signer 1.0.0 ships: every transaction parser, risk rule and signing plan is in it. The rest of the app (interface, Keychain, storage) was reviewed by reading the Swift source.

Every finding​

IDSeverityFindingStatus in 1.0.0
BTS-OP5-01LowHigh-risk consent is enforced only in the interface. The engine requires an explicit acknowledgement for partially decoded and opaque requests, but not for fully decoded high-risk ones (unlimited approvals, setApprovalForAll, Safe permission changes, token burns). The app disables Sign until the box is ticked, so an attacker cannot reach this in 1.0.0; it matters because the engine is the part users can verify by hash.Open. The report recommends adding the check to the engine in 1.0.1.
R3-01LowBitcoin summary for a burn with change. For a transaction with a nonzero OP_RETURN output and verified change, the short summary on the result screen and in Activity reads "Every output returns to your wallet". The signing screen itself shows the burn, its amount and the High risk correctly.Open (the engine shipped in 1.0.0 is the one reviewed).
BTS-OP5-02InformationalA localization key in Activity is built from engine output, which SwiftUI renders as Markdown. Every value it can hold today is a fixed label, so it is latent.Open, latent.
BTS-OP5-03InformationalThe vault's password KDF (PBKDF2-HMAC-SHA256, 600,000 rounds) is not memory-hard. Mitigated by the second encryption layer under a device-bound Keychain key: a copied vault file alone cannot even be attacked.Accepted; Argon2id is suggested for a future vault format.
BTS-OP5-04InformationalIntermediate Ed25519 key material in the Solana derivation is not explicitly wiped; disposing of the JavaScript context is the actual control.Open, inherent limitation.
O-01InformationalDuring import, a slow "is this wallet already here?" lookup can finish after the phrase is edited and offer a password reset for the previous wallet. The reset itself re-derives the wallet identity and refuses the wrong wallet; no vault changes.Open at the time of the report.
O-02InformationalSafe and Solana summaries come from bounded decoders, not from executing the transaction. Live contract state is not known offline.By design; disclosed in the review screen.
O-03InformationalComplete memory zeroization cannot be guaranteed in Swift and JavaScript; the physical device, the OS random generator and the distributed binary were not tested.Limitation.
O-04InformationalSix development-only dependency advisories (3 moderate, 3 low). The affected packages are not in the shipped engine.Maintenance.

Both reports also re-tested the findings of two earlier review rounds, including one High (the summary of Safe multisig transactions with DELEGATECALL and nested MultiSend) and several Low ones in Bitcoin fee and Solana burn summaries, and found them fixed. Opus 5 additionally notes, as a property of the TRON protocol rather than a defect, that TRON signatures carry no network identifier; the app discloses this.

Found later in the shared engine​

BitTool Signer for iPhone 1.0.0 ships the engine with SHA-256 6933d0d8…f21077. The GPT-6 Astra review of the Android app reproduced its engine findings against exactly this file, and the Bitcoin, EVM and TRON code behind the Opus 5.5 findings is identical in it. These engine findings therefore also apply to iPhone 1.0.0:

IDSeverityWhat it means on iPhone 1.0.0
BTS-02, BTS-07MediumA Solana burn, authority change or delegation sent together with a dust transfer is summarized as that transfer. The warnings in the details and the risk acknowledgement remain.
BTS-08MediumBitcoin change is accepted at any address index of the wallet's single-sig profiles, including indexes a watch-only wallet will never scan.
BTS-09Low–MediumThe stored summary omits the native coin sent with an unknown EVM or TRON contract call. The review card shows it.

R3-01 above is the same defect as Android's BTS-04, which the Android engine fixes. The Opus 5.5 report recommends fixing the others in the shared engine, which then reaches both apps.

What the reviews confirmed​

AreaConfirmedDetails
SigningIn Release builds the only way to sign is through a fixed plan. Six independent checks tie the signature to the reviewed request, the planned wallet and the approved key, and the engine re-derives everything from the decrypted seed before signing. Confirmed by execution.Before signing
RandomnessRecovery phrases come from SecRandomCopyBytes; an error stops creation with no fallback. The engine's crypto.getRandomValues and Math.random are bridged to the same source.Seed generation
Key storageTwo AES-GCM layers with authenticated headers, a device-only Keychain key, and failed-attempt throttling that survives restarts.Key storage
RefusalsEvery refusal these docs describe holds: SIGHASH_NONE/SINGLE/ANYONECANPAY, SegWit v0 inputs without the previous transaction, Solana lookup tables, EIP-7702, blob transactions, raw-hash eth_sign and unsupported chain IDs.Limits and errors
Untrusted input5,509 mutated QR, CBOR, PSBT and JSON inputs across both reviews: none accepted when invalid, no uncontrolled exception.UR and CBOR
OfflineNeither CFNetwork nor Network.framework is linked, and the JavaScript bridge exposes no network API.Security model
Supply chainThe engine rebuilds byte for byte from the tag; runtime dependencies are exact-pinned; the production dependency audit reported no vulnerabilities.Below

What they did not cover​

Testing on physical devices (fault injection, memory dumps, side channels), the OS random generator and Secure Enclave internals, provenance of the App Store binary beyond the engine file, transactions on live chains, round trips with third-party wallets, a full audit of the cryptographic dependencies, linguistic review of the 21 interface languages, and formal verification. A passing test suite covers the cases it tests, not every transaction or device.

Verify the engine yourself​

The App Store executable cannot be reproduced byte for byte (Apple re-signs and encrypts it), but the engine is an unencrypted resource that can be compared. Build it from the tag:

git clone https://github.com/bitbill/bittool-signer-ios
cd bittool-signer-ios && git checkout v1.0.0
cd engine && npm ci --ignore-scripts && npm run build
shasum -a 256 ../BitToolSigner/Resources/signer.js
# 6933d0d8a6f60faa8222506ac0bd7eef80eb884c9f73e31e9f354b4740f21077 (1,181,026 bytes)

Then compare it with the file inside the app you installed: download the app as an .ipa with Apple Configurator, unzip it, and hash Payload/BitToolSigner.app/signer.js. The full procedure, including where verification stops, is in the repository's Reproducible-Build.md.

BitTool Signer for Android​

The two reports​

Opus 5.5GPT-6 Astra
Date25 October 202624 October 2026
Code reviewedRelease 1.0.0 (version code 1000001): code commit 71af693, release record 62996b8Commit e7e71fb, before the release: a re-audit of the changes since the previous baseline bb1e656
Engine reviewed (signer.js, SHA-256)4b371759…00fa196933d0d8…f21077, the engine iPhone 1.0.0 ships
MethodSource review of five areas, each traced end to end; every finding re-checked against the code; engine reproductions with synthetic data; dependency and artifact checksReview of the changed code and its callers, verification of three fixes, engine reproductions against the committed bundle, automated regression checks
Tests run2,075 app tests, 217 engine tests, release verification script 25 of 251,616 Android tests; 210 engine tests, one failing and one passing without running (BTS-06)
Result0 Critical · 0 High · 4 Medium (one rated Low–Medium) · 9 Low · informational notes0 Critical · 0 High · open: 1 Medium, 1 Low, 1 validation finding · 3 closed
RecommendationFix BTS-07, BTS-08 and BTS-10 before a general release that protects valuable walletsHold a general release for valuable wallets at that revision
IndependenceThe same model family wrote much of the code under reviewAI-assisted; production code was not modified

Both reviews looked at the whole Android app: the Kotlin modules, the native host (JNI over QuickJS, and the native PBKDF2) and the signing engine shared with iPhone.

Every finding​

Opus 5.5 reviewed the released code, so these are the findings of BitTool Signer for Android 1.0.0.

IDSeverityFindingWhere
BTS-07MediumSolana authority changes hide behind a dust transfer. A request that changes an account's owner or authority, approves a delegate or carries an opaque instruction, together with a 1-lamport transfer, gets that transfer as its headline and stored summary. The high-risk warnings stay in the details and the risk acknowledgement is still required.Shared engine, also iPhone
BTS-08MediumBitcoin change accepted at any index. An output counts as verified change if its script matches any of the wallet's single-sig profiles, on branch 0 or 1, at any index up to 2³¹−1. Funds sent there review as "All outputs return to your wallet" but may never be found by a wallet that scans a limited range of addresses.Shared engine, also iPhone
BTS-09Low–MediumStored summary omits native value on contract calls. An unknown EVM or TRON contract call that also sends the native coin is stored as "Unknown contract call". The review card and its warning do show the value.Shared engine, also iPhone
BTS-10MediumRelease signing key on the development machine. The key and its passwords were stored in plaintext in the working tree, excluded from Git.Release process
BTS-11LowThe QR camera can keep scanning behind the App Lock screen. Signing still needs the wallet password.Android app
BTS-12LowThe risk acknowledgement for fully decoded high-risk requests is enforced only in the interface.Android app (iPhone: BTS-OP5-01)
BTS-13LowAfter a Keystore error on Android 8–11, the key that authenticates public wallet data can be regenerated, and wallets then need Repair. No secret or funds are lost.Android app
BTS-14LowTwo auxiliary keys do not check for a screen lock, and parts of the documentation overstate the protection. The vault itself still requires one.Android app
BTS-15LowThe default task affinity allows task hijacking on older Android versions.Android app
BTS-16LowThe backup check can be passed by trial and error.Android app (same on iPhone, per the report)
BTS-17LowOne Recovery Card of a 12-word phrase leaves about 40 bits of entropy.Android app
BTS-18LowA cancelled wallet match can leave the review on "Finding the matching wallet…".Android app
BTS-19LowAndroid 8.0–9 cannot detect overlays that cover only part of a consent control. The password is still required.Android app

The report also lists informational notes, among them: no CPU-time limit on the engine thread (availability only), the Google Play build signed with the APK key until a separate upload key is set up, a retry delay based on the wall clock, and short-lived copies of the phrase that the JVM cannot wipe.

GPT-6 Astra reviewed an earlier commit. Its findings, and where they stand in the release:

IDSeverityFindingAt e7e71fbIn Android 1.0.0
BTS-01MediumPartly covered Sign and risk controls could be tapped through an overlayClosedClosed
BTS-02MediumA Solana burn or authority change mixed with a dust transfer is summarized as the transferOpenBurns fixed; authority changes remain as BTS-07
BTS-03LowSecret buffers could outlive a cancelled operationClosedClosed
BTS-04LowA Bitcoin burn with change is summarized as "Every output returns to your wallet" (iPhone R3-01)OpenFixed
BTS-05FunctionalAn interrupted QR scan did not resumeClosedClosed
BTS-06ValidationOutdated file paths made one engine test fail and another pass without runningOpenFixed (217 of 217 engine tests pass)

What the reviews confirmed​

AreaConfirmed
SigningNo password bypass and no way to sign anything but the reviewed and matched request. The plan is bound to the request hash, the plan hash and the digest of the signing bytes; the engine re-resolves it against the decrypted seed and rejects any change to an unsigned Bitcoin transaction. Late results after a cancellation, App Lock or a new request are dropped.
Key storagePBKDF2-HMAC-SHA256 with 600,000 iterations in native code, AES-256-GCM with a fresh nonce and salt for each encryption, then a per-wallet, non-exportable Android Keystore key (StrongBox when the phone has one). Every password attempt is counted before the key derivation, and a damaged counter fails closed.
Secrets in memoryUnlocked secrets live in holders that are closed after use and wiped even on cancellation. The recovery phrase is typed on the app's own keyboard, which no input method sees.
Engine hostThe bundle is pinned by SHA-256 and length; QuickJS runs without eval or Function, in a fresh runtime for every operation that touches a secret or untrusted input, with memory and stack limits.
Offline and platformNo Internet permission and no networking code. Only the main screen is exported, with no deep links; backups and device transfer are excluded; every window is kept out of screenshots, recordings and Recents; other apps' overlays are hidden on Android 12 and later. App Lock never authorizes a signature, and the release build logs nothing.
Supply chainThe engine rebuilt from a clean npm ci --ignore-scripts is byte-identical to the committed file and to the copy inside the APK. The production dependency audit reports no advisories.

What they did not cover​

Testing on real devices (Keystore and StrongBox behaviour of different manufacturers, biometrics, overlays, screen capture), malicious-overlay exercises, side channels, execution of the native code on ARM, transactions on live chains, a CVE scan of the Maven and native dependencies, and the copy that Google Play builds. Both reports ask for the release to be checked on representative devices from Android 8 to the latest version, and Opus 5.5 recommends an independent human audit before the app protects significant funds.

Verify the APK and the engine​

The APK published on bittool.com/signer can be checked completely: its hash, its signing certificate, the engine inside it, and the absence of the Internet permission (aapt2 dump badging lists no android.permission.INTERNET).

# 1. The APK from bittool.com/signer
shasum -a 256 BitToolSigner-1.0.0-1000001.apk
# 109dbf5c622ee77672904c34a10229df3c9b0eac45b07096c510b1e1e169c2a4
apksigner verify --print-certs BitToolSigner-1.0.0-1000001.apk
# Signer #1 certificate DN: CN=BITTOOL PTE. LTD., O=BITTOOL PTE. LTD., C=SG
# Signer #1 certificate SHA-256 digest: af41ed101765393ae89038eb4c6fc7fa96d930f6fcd76b881437a39b5a9e4631

# 2. The engine inside it
unzip -p BitToolSigner-1.0.0-1000001.apk assets/engine/signer.js | shasum -a 256
# 4b3717599e8ee3ed9d2480e640e7203731543cc8ab0f2c3cec3b78e6f400fa19 (1,181,432 bytes)

# 3. The same engine, rebuilt from source
git clone https://github.com/bitbill/bittool-signer-android
cd bittool-signer-android && git checkout 71af693
cd engine && npm ci --ignore-scripts && npm run build
shasum -a 256 ../core/engine/src/main/assets/engine/signer.js

The certificate never changes between releases, Android installs an update only if it carries the same one, and the app shows it in Settings › Fully Open Source › This build. A copy installed from Google Play is a different file, because Google Play builds it from the uploaded bundle, so its hash cannot be compared; its assets/engine/signer.js is unchanged and can be compared the same way after adb pull. The full procedure is in the repository's Reproducible-Build.md. We checked the values above against the published APK on 25 October 2026.

Download the reports​

ReportPagesSHA-256
iPhone · Opus 5, 19 October 2026 (PDF, 118 KB)17ff7ddd17e5dffccd99db6aaa43b8f0041167b58bd9b2bd7cc11d185e779bca1a
iPhone · GPT-6 Astra, report R3, 18 October 2026 (PDF, 46 KB)1602d7a358f8f35b2978eab7db1292add4365a94b736ff79e158dee3afb842b64a
Android · Opus 5.5, 25 October 2026 (PDF, 252 KB)88242d58aeec1aa88823eb0a938c9461b0681abfab3f37805e2f77a41b3bba34c
Android · GPT-6 Astra, re-audit, 24 October 2026 (PDF, 22 KB)7b37aaefd40d0d522384a86255accadeb976067175d76e38466a1b4c90b036f53

The summaries on this page are ours; where they differ in wording from a report, the report is authoritative.