- 
                Notifications
    
You must be signed in to change notification settings  - Fork 5
 
Development
- This is the public flavor.
 - It should be always buildable without manual configurations.
 - This flavor only contains a sample publisher.
 
- This is an internal product flavor, which cannot be build directly.
 - Crashlytics is enabled.
 
Place the information required by the numbers backend in ./app/src/main/.../publisher/numbers_storage/Token.kt. For example:
package io.numbersprotocol.starlingcapture.publisher.numbers_storage
const val baseUrl = "https://sample.com"
const val token = "token 0123456789abcdef"- Debug
- LeakCanary is enabled.
 
 - QA
- The quality of this build type should be product-ready. Thus, it should not contain any visible debugging artifacts (e.g. LeakCanary) except error messages.
 
 
- Kotlin
- Coroutine
 - Flow
 
 - AndroidX
 - MVVM Architecture
 - Android Architecture Component
- Paging Library
 - Work Manager
 - Preference Library
 - Navigation Component
 - Room Database
 
 - Material Component
 - Koin - dependecy injection
 - Retrofit - networking
 - Moshi - proof serialization
 - Coil - image loading
 - Timber - logging
 - LeakCanary - memory leak detection
 
- The committed codes should pass all GitHub workflows.
 - The committed codes should not have warnings from Android Studio linter. You can use 
./gradlew lintto verify. - The committed codes should not have memory leak reports by LeakCanary, which is enabled in the debug variant.
 
The name in string.xml should match the English content in snake case. If the content of the string is a long message, the name should start with message_. For example:
<string name="public_key_signature">Public Key Signature</string>
<string name="message_are_you_sure">The action cannot be undone.</string>
Currently, three types of media source are implemented:
- Internal camera (image)
 - Internal camera (video)
 - Canon Camera with CCAPI (image and video)
 
The components regarding media source should be placed in ./app/src/main/.../source/.
Currently, we only use android-info-snapshot as information provider. The components regarding information collection should be placed in ./app/src/main/.../collector/information/.
To add new information provider,
- Extends the 
InformationProvider. - Override the 
provideInformation()method. - Store the information to the DB with 
InformationRepositoryclass. 
Currently, two types of signature provider are implemented:
- AndroidOpenSSL (default signature)
 - Zion signature (opt-in)
 
The components regarding information collection should be placed in ./app/src/main/.../collector/signature/.
To add new signature provider,
- Extends the 
SignatureProvider. - Override the 
provideSignature()method. - Sign the 
SortedProofInformationfrom the given proof hash. - Store the signature to the DB with 
SignatureRepositoryclass. 
Currently, we only provide a sample publisher which does nothing.
The components regarding information collection should be placed in ./app/src/main/.../publisher/.
To add new signature provider, see the SampleProofPublisher class for details.

- Store the proof raw file into the internal directory.
 - Store the hash of proof into proof repository.
 - Collect information.
 - Sign the proof and its collected information even if some information providers failed.
 
The SortedProofInformation class provides the message of signature provider.
{
    proof: {
        hash: String,
        mimeType: String,
        timestamp: Long
    },
    information: [
        {
            provider: String,
            name: String,
            value: String
        },
        ...
    ]
}Example (beautified), Sign with Zion is disabled:
$ jq . information.json
{
  "proof": {
    "hash": "3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014",
    "mimeType": "image/jpeg",
    "timestamp": 1652606172402
  },
  "information": [
    {
      "provider": "InfoSnapshot",
      "name": "Accelerometer",
      "value": "[0.4421997, 6.9092345, 6.9160113]"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Board",
      "value": "QC_Reference_Phone"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Brand",
      "value": "Htc"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Country",
      "value": "United States"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Accuracy",
      "value": "17.307"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Address",
      "value": "No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Altitude",
      "value": "27.399999618530273"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Bearing",
      "value": "0.0"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Latitude",
      "value": "24.9960048"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Longitude",
      "value": "121.5104486"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Speed",
      "value": "0.0"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Current GPS Timestamp",
      "value": "2022-05-15T09:16:13.438Z"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Device Build Fingerprint",
      "value": "Htc/bre2exdugl_00400/htc_bre2exdugl:8.1.0/OPM1.171019.011/200630:user/release-keys"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Device Build ID",
      "value": "1.15.709.1"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Device Build Tags",
      "value": "release-keys"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Device Build Time",
      "value": "6/30/20 8:16 PM"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Device Build Type",
      "value": "user"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Device Name",
      "value": "htc_bre2exdugl"
    },
    {
      "provider": "InfoSnapshot",
      "name": "End Product Name",
      "value": "EXODUS 1s"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Game Rotation Vector",
      "value": "UNSUPPORTED"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Geomagnetic Rotation Vector",
      "value": "[0.4146733, -0.044002537, 0.09306122, 0.9041181, 0.0]"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Gravity",
      "value": "[1.7164232, 7.280239, 6.3422546]"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Gyroscope",
      "value": "UNSUPPORTED"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Hardware",
      "value": "qcom"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Hash of Android ID",
      "value": "0fa0b3f57c76d453433151b46ed2f6562bd31183f1e21d0c092318e519a9aed5"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Language",
      "value": "English"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Accuracy",
      "value": "15.709"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Address",
      "value": "No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Altitude",
      "value": "27.399999618530273"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Bearing",
      "value": "0.0"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Latitude",
      "value": "24.996015"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Longitude",
      "value": "121.5104355"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Speed",
      "value": "0.0"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Last Known GPS Timestamp",
      "value": "2022-05-15T09:03:14.455Z"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Light",
      "value": "[6.0]"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Linear Accelerometer",
      "value": "[-1.2052132, -0.11499733, 0.21131894]"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Magnetic Field",
      "value": "[-0.09765625, -6.1523438, -77.83144]"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Manufacturer",
      "value": "HTC"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Name",
      "value": "English (United States)"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Overall Product Name",
      "value": "bre2exdugl_00400"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Rotation Vector",
      "value": "[0.4130853, -0.04073075, 0.08709024, 0.90559506, 0.0]"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Script",
      "value": ""
    },
    {
      "provider": "InfoSnapshot",
      "name": "Timestamp",
      "value": "2022-05-15T09:16:22.898Z"
    },
    {
      "provider": "InfoSnapshot",
      "name": "Variant",
      "value": ""
    }
  ]
}Example (raw), Sign with Zion is disabled:
$ cat information.json
{"proof":{"hash":"3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014","mimeType":"image/jpeg","timestamp":1652606172402},"information":[{"provider":"InfoSnapshot","name":"Accelerometer","value":"[0.4421997, 6.9092345, 6.9160113]"},{"provider":"InfoSnapshot","name":"Board","value":"QC_Reference_Phone"},{"provider":"InfoSnapshot","name":"Brand","value":"Htc"},{"provider":"InfoSnapshot","name":"Country","value":"United States"},{"provider":"InfoSnapshot","name":"Current GPS Accuracy","value":"17.307"},{"provider":"InfoSnapshot","name":"Current GPS Address","value":"No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"},{"provider":"InfoSnapshot","name":"Current GPS Altitude","value":"27.399999618530273"},{"provider":"InfoSnapshot","name":"Current GPS Bearing","value":"0.0"},{"provider":"InfoSnapshot","name":"Current GPS Latitude","value":"24.9960048"},{"provider":"InfoSnapshot","name":"Current GPS Longitude","value":"121.5104486"},{"provider":"InfoSnapshot","name":"Current GPS Speed","value":"0.0"},{"provider":"InfoSnapshot","name":"Current GPS Timestamp","value":"2022-05-15T09:16:13.438Z"},{"provider":"InfoSnapshot","name":"Device Build Fingerprint","value":"Htc/bre2exdugl_00400/htc_bre2exdugl:8.1.0/OPM1.171019.011/200630:user/release-keys"},{"provider":"InfoSnapshot","name":"Device Build ID","value":"1.15.709.1"},{"provider":"InfoSnapshot","name":"Device Build Tags","value":"release-keys"},{"provider":"InfoSnapshot","name":"Device Build Time","value":"6/30/20 8:16 PM"},{"provider":"InfoSnapshot","name":"Device Build Type","value":"user"},{"provider":"InfoSnapshot","name":"Device Name","value":"htc_bre2exdugl"},{"provider":"InfoSnapshot","name":"End Product Name","value":"EXODUS 1s"},{"provider":"InfoSnapshot","name":"Game Rotation Vector","value":"UNSUPPORTED"},{"provider":"InfoSnapshot","name":"Geomagnetic Rotation Vector","value":"[0.4146733, -0.044002537, 0.09306122, 0.9041181, 0.0]"},{"provider":"InfoSnapshot","name":"Gravity","value":"[1.7164232, 7.280239, 6.3422546]"},{"provider":"InfoSnapshot","name":"Gyroscope","value":"UNSUPPORTED"},{"provider":"InfoSnapshot","name":"Hardware","value":"qcom"},{"provider":"InfoSnapshot","name":"Hash of Android ID","value":"0fa0b3f57c76d453433151b46ed2f6562bd31183f1e21d0c092318e519a9aed5"},{"provider":"InfoSnapshot","name":"Language","value":"English"},{"provider":"InfoSnapshot","name":"Last Known GPS Accuracy","value":"15.709"},{"provider":"InfoSnapshot","name":"Last Known GPS Address","value":"No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"},{"provider":"InfoSnapshot","name":"Last Known GPS Altitude","value":"27.399999618530273"},{"provider":"InfoSnapshot","name":"Last Known GPS Bearing","value":"0.0"},{"provider":"InfoSnapshot","name":"Last Known GPS Latitude","value":"24.996015"},{"provider":"InfoSnapshot","name":"Last Known GPS Longitude","value":"121.5104355"},{"provider":"InfoSnapshot","name":"Last Known GPS Speed","value":"0.0"},{"provider":"InfoSnapshot","name":"Last Known GPS Timestamp","value":"2022-05-15T09:03:14.455Z"},{"provider":"InfoSnapshot","name":"Light","value":"[6.0]"},{"provider":"InfoSnapshot","name":"Linear Accelerometer","value":"[-1.2052132, -0.11499733, 0.21131894]"},{"provider":"InfoSnapshot","name":"Magnetic Field","value":"[-0.09765625, -6.1523438, -77.83144]"},{"provider":"InfoSnapshot","name":"Manufacturer","value":"HTC"},{"provider":"InfoSnapshot","name":"Name","value":"English (United States)"},{"provider":"InfoSnapshot","name":"Overall Product Name","value":"bre2exdugl_00400"},{"provider":"InfoSnapshot","name":"Rotation Vector","value":"[0.4130853, -0.04073075, 0.08709024, 0.90559506, 0.0]"},{"provider":"InfoSnapshot","name":"Script","value":""},{"provider":"InfoSnapshot","name":"Timestamp","value":"2022-05-15T09:16:22.898Z"},{"provider":"InfoSnapshot","name":"Variant","value":""}]}signature.json provides both a digital signature and a public key. The content of signature.json does not equal to the digital signature of a Sorted Proof Information directly.
[
    {
        proofHash: Hex String,  # raw asset's sha256
        provider: String,       # cryptographic signing algorithm provider
        signature: Hex String,  # cryptographic digital signature signed by the private key
        publicKey: Hex String   # cryptographic public key for verifying the signature above
    },
    ...
]Example (beautified), Sign with Zion is disabled:
$ jq . signature.json
[
  {
    "proofHash": "3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014",
    "provider": "AndroidOpenSSL",
    "signature": "304502203ced7a2eb4faee3422156066fd8da9afd8a851608f421340c437c3a1f0180fe7022100fdad1b273f5e4851077429ca4b692b223c9f20c0db5140a987aa2c6a86ea286b",
    "publicKey": "3059301306072a8648ce3d020106082a8648ce3d03010703420004813afd7f6ba95fdebeac7812c7ab5af9ca59547b2a73f5aa75accca4e4ad2eb6849d4948a9fcfb8c2b890ba0dfbe4463bbfe4ac163981a93517bfb34598fc850"
  }
]Example (raw), Sign with Zion is disabled:
$ cat signature.json
[{"proofHash":"3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014","provider":"AndroidOpenSSL","signature":"304502203ced7a2eb4faee3422156066fd8da9afd8a851608f421340c437c3a1f0180fe7022100fdad1b273f5e4851077429ca4b692b223c9f20c0db5140a987aa2c6a86ea286b","publicKey":"3059301306072a8648ce3d020106082a8648ce3d03010703420004813afd7f6ba95fdebeac7812c7ab5af9ca59547b2a73f5aa75accca4e4ad2eb6849d4948a9fcfb8c2b890ba0dfbe4463bbfe4ac163981a93517bfb34598fc850"}]The verification concept is that
- If Proof Information is trustworthy, the Asset checksum is trustworthy.
 - If the Asset checksum is trustworthy, the Asset is trustworthy.
 
The Verification Tool and starling-capture-verification-examples.zip demonstrate the steps to verify the signatures.
verify.sh is a wrapper of starling_capture_verifier.py. If you want to assign the metadata (information.json) and signature (signature.json) individually, you can use starling_capture_verifier.py.
$ cd util/verification/
$ unzip starling-capture-verification-examples.zip
$ ./verify.sh starling-capture-verification-examples/1.8.0/d7a07fafcbafceb5d626d673f0aabdb4db9d4ce6058f4e9859380831e556aa5a
Verification result: Pass
Summary:
        SW key verification: True
        HW key verification (Zion): False
        HW key verification classic (Zion): False
        HW session key verification (Zion): False
        HW session key verification classic (Zion): True
Wallet Addresses:
        Zion singer wallet address: 0x5f5ad77f4f924232a6e486216ddefba8a732b96b
Note
        1. For the HW-related verifications, only one of them will be True.
$ ./verify.sh starling-capture-verification-examples/1.9.2/7e96c9fe16f96540de449a422852138d723c9ae80269fe4ae0e802323bf6ac7d 
Verification result: Pass
Summary:
        SW key verification: True
        HW key verification (Zion): False
        HW key verification classic (Zion): False
        HW session key verification (Zion): True
        HW session key verification classic (Zion): False
Wallet Addresses:
        Zion singer wallet address: 0x5f5ad77f4f924232a6e486216ddefba8a732b96b
        Recovered wallet address: 0x5f5ad77f4f924232a6e486216ddefba8a732b96b
Note
        1. For the HW-related verifications, only one of them will be True.Before v1.9.2, Starling Capture uses "classic" signature/verification. The signature and verification flow charts are below.
Zion signature and verification

Zion session-based signature and verification

Zion signature and verification classic (< v1.9.2)

Zion session-based signature and verification classic (< v1.9.2)

The known regression in v1.7.x (non-public pre-release) was due to that signatures were generated before the completion of HW metadata collection (#122). The issue was first introduced by commit a1f381df  on 12 Oct 2020 and fixed 11 days after (23 Oct 2020) by commit 5f53d87.
Tips for verifying v1.7.0 metadata
- 
Metadata (
information.json) ends with "noeol"- Open Node.js
 - Create metadata JSON object
 - Save file by running 
fs.writeFileSync("information.json", JSON.stringify(metadataObj)) 
 - 
Make value of the
informationkey to be an empty list - 
Make metadata look like
{"proof":{"hash":"8e57db457dfb242405f31122318990cac21450a4bfed424e722a964ede1fe8e8","mimeType":"image/jpeg","timestamp":1662967587804},"information":[]} 
Please kindly be noted that since Starling Capture is a project to experiment with new concepts, fast iteration and sometimes unmatured technologies are expected. It is always safer to use the latest tagged version instead of the old versions and the code branches.