Celebrating Six Years of Post-Quantum Security: The Journey of QRL

Read More

QRL Improvement Proposal (QIP-017)

A Proposed v3 Wallet Format & Use of scrypt/AES-256-GCM

Overview & status

AuthorJP Lomas (@jplomas)
Statusproposal open
Created2021-12-17
Discussions tohttps://github.com/theQRL/qips/pull/37

A Proposed v3 Wallet Format & Use of scrypt/AES-256-GCM

Abstract

This QIP proposes a ‘version 3’ wallet file format with enhancements to the encryption to reduce the risk of funds loss when an encrypted wallet file is publicly exposed.

Motivation

Encrypted wallet files exfiltrated from a target system are at risk of (a) brute force/dictionary attacks and (b) theoretical man-in-the-middle / tampering attacks.

The risk can be reduced by using scrypt in conjunction with the existing aes256 encryption, and by swapped the aes256 mode from CTR to GCM.

Additionally, there has been no formal specification of the QRL wallet format.

Specification

1. Wallet format

Extraneous public data which can be derived from other elements, for example tree height/PK, is excluded.

Plain ASCII text file containing valid JSON detailing the version number, whether the elements are encrypted and with an array of 1 or more wallets in the format:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "version": 3,
  "encrypted": <boolean>,
  "addresses": [
    {
      "address": "<string>",
      "hexseed": "<string>",
      "mnemonic": "<string>"
    },
    {
      "address": "<string>",
      "hexseed": "<string>",
      "mnemonic": "<string>"
    },
    ...
  ]
}

Retention of unencrypted wallet file support is retained for use where the environment is secured by another means (e.g. encrypted volume) but is not recommended for standard use cases.

2. Encryption

Within the addresses array, the elements are encrypted using scrypt and aes-256-gcm as per the reference implementation and presented as a string with elements separated by a colon, formatted as:

1
[IV hexstring]:[authentication tag hexstring]:[salt hexstring]:[encrypted data:hexstring]

Eg:

The plain text address:

1
Q010600beb663d164df6a4d984155df86ba2a938d5a57a364033a39e34ae47ec642d8f3ee900e08

When encrypted with AES-256-GCM with scrypt, the password My Secret Password and formatted as per above results in the following:

1
87b448183d0924b7fcb4e5643097400f:79652dc221037d2a78198019defce625:bc36990b72b6a4e2127f57fab00bf03601bdd2ea7045a80ddbd883dee63a0a71:ef416f256fc4ab5a6da0a421e8cb26b7f81c99a4fea2f22384f679a93a03bf4f51bef137c2d9b6f9119bee9556f889c5923ae9e0dc05ec960c04a642b1c6fbd6f6bc87624bd1572e73f8324f227502

Backward compatibility

Existing wallet implementations should retain backwards compatibility for legacy wallet formats. It is preferable to offer the user the option to upgrade to a version 3 wallet file.

Reference Implementation

A worked example (with code peer review by @leongb - thank you Leon) is at https://runkit.com/jplomas/aes-256-gcm-with-scrypt/6.0.0

Additionally some work has been commenced in implementing this in @theqrl/wallet-helpers NPM module

A Python reference implementation is underway.

Security Considerations

Implementation recommended by x41-D-sec; rationale, cryptography and reference code peer reviewed by @leongb. Both the existing and this use of AES256 is considered post-quantum secure.

Clearly the most secure means of protecting funds are that wallet files remain solely in the possession of their owners. This implementation reduces to some degree the risk of loss should this principle be compromised.