Introduction

  • Delivery Mechanism
  • Key Management
  • Authentication
  • Hierarchical Deterministic Keys
  • PGP Key Exchange
  • Multi Signature Architecture

Delivery Mechanism

Ninki Wallet is delivered as a Chrome App via Google's Chrome Store. This enables a web type interface but without the insecurity of delivering code via a webpage.

Chrome Apps are not extensions, they do not run in the Chrome browser. They are a sandboxed application that runs in it's own instance of Chrome.

Chrome Apps disable certain features of Javascript that are responsbile for most XSS injection attacks and require a Content Security Policy to explicitly authorise access to external domains.

A summary of the disabled functions can be found here

The application itself is delivered via a signed delivery system and will not install unless the signature is correct. Updates can be pushed to users by a person in ownership of the Google account the app is registered under. In this respect it is very similar to the model for delivering iPhone and Android phone apps.

Key Management

Asset Owner Method
Online Key User Chrome Storage (Encrypted) + Encrypted backup
Offline Key User Offline Storage eg. written down, kept in safe, safety deposit
Countersign Key Service Encrypted Stored in database
PGP Key User/Service Encrypted by the user / stored in databse

Authentication

The following describes the process of the server authenticating the user and issuance of a session token.

When the user creates an account a secret is shared between the server and the client. The client encrypts a randomly generated secret using their password as an input to a pbkdf along with a unique salt. The encryption scheme is AES 256 Mode: CBC, Padding: No Padding

The encrypted secret is stored on the server. When the user attempts to login to the server the entered password is derived to a passphrase using a unique salt. The client requests the encrypted secret from the server, the server returns the encrypted secret and the client decrypts using the passphrase. The result is sent back to the server and the server compares the secret with value originally shared.

Once the user has proven that they can decrypt the secret, and therefore know the password, the server challenges them to provide a one time 2 factor authentication code. If this is validated succesfully the user is authenticated and a session token is issued.

The encrypted packet containing the users api key and public key information is sent to the client and decrypted using the passphrase. The client maintains a connection with the server polling every 10 seconds, if there is no communication for over 60 seconds, the session is timed out and the user will have to authenticate to establish a session.

Hierarchical Deterministic Keys

All keys are deterministic as defined in BIP32

The online and offline keys are derived from a random 32 byte array using window.crypto.getRandomValues. The data is then hashed using SHA256 and used as a seed to an HD key space.

Node m/0/0 is used for receiving address generation, node m/0/1 is used for change address generation and m/0/1000 is used for allocating nodes to contacts on your network.

Wallet Network

Rationale

Bitcoin addresses are difficult to exchange and require either copying and pasting or qr code scanning. This promotes address re-use which in turn can make funds vunerable to R value attacks and are detrimental to financial privacy.

The PGP scheme described here removes the need for exchanging bitcoin addresses everytime two users transact, and promotes zero address re-use. After the PGP validation is complete it becomes less effort to generate new addreses on behalf of each other then it does to find the previous address used for that user and copy/paste it into a transaction.

The server can facilitate the initial exchange, but should not be trusted, and so an out of band validation is required. Note: this should also happen over a secure channel, however this is up to the user as we have, by definition no control over the choice of channel.

Finally, the addresses are generated by the client and not handed off from the server, removing the threat of the server handing off bad addresses. The server acts purely as a verification service, a cross check between what the client has generated and what the server expected.

This provides an extra layer of security against malware on the client replacing the address before the transaction is signed and sent to our server.

PGP Key Exchange

The wallet supports exchanging HD public key nodes with other users on the service. The purpose of this is to allow users who regularly transact with each other, to generate addresses on each other's behalf. So instead of you sending me an address, I simply derive one from the next node on the public key chain you assinged and sent to me.

This presents a problem of a MIM attack when exchanging nodes. How do we know the server which is facilitating the exchange is not compromised?

To solve this we use PGP with the keys generated on the client at the time of account creation and stored in an encrypted packet, using the user's passphrase.

An out-of-band fingerprint exchange must occur between the two users in order to validate that the service or another actor has not compromised the integrity of the key exchange. We present this fingerprint in the form of a BIP39 encoded mnemonic referred to as a 'Ninki Phrase'.

Ninki Phrase
Copy

exhaust lumber tone tribe poem glide alpha vendor select morning maze tongue vote rain clock

Alice provides a node to Bob

  1. Bob's PGP public key is registered with the server, we can refer to this as an untrusted public key.
  2. Alice retrieves the untrusted PGP public key for Bob from the server.
  3. Alice encrypts her HD node with Bob's untrusted PGP public key and signs it with her PGP private key.
  4. Bob retrieves the packet encrypted by Alice from the server and decrypts using his PGP private key.
  5. Bob retrieves Alice's untrusted PGP public key from the server and validates the signature on the packet
  6. Bob encrypts the contents of the packet and Alice's untrusted PGP public key with his PGP public key and stores on the server for future reference.
  7. Out of band, Alice sends Bob her PGP public key fingerprint
  8. Bob verifies that the untrusted PGP public key he has stored for Alice matches this fingerprint.
  9. Alice's PGP public key is now trusted by Bob and the integrity of the exchange is verified.

Whenever Bob needs to generate an address for Alice, he retrieves the packet from the server, decrypts it with his PGP private key and derives a new address for Alice. The reverse process happens and Alice and Bob now have connected wallets.

Multi Signature Architecture

Ninki Wallet is a 2 of 3 multi-signature wallet where 2 keys are controlled by the user and one key is controlled by Ninki. The user would typically store one encrypted key online, on a usb drive or a cloud storage service. This is referred to as the Online key and should always be stored using encryption. The other user key would typically be stored offline, perhaps in paper format in a safe deposit box or safe. The Countersigning key is secured by Ninki on the server.

This configuration allows Ninki to act as a counter-signing service, but without the ability to move the funds alone, and provides the user with the ability to recover their funds in any event.

When the user initiates a transaction, it is built locally on the client, signed with the online key and then sent to the server for counter signing. The server validates the transaction and then countersigns and broadcasts it to the Bitcoin network.

Transaction Validation

Before countersigning the following items are checked on the server:

  • Single Transaction Limit
  • Daily Transaction Limit
  • Number of Transactions / 24hr Limit
  • Number of Transactions / 1hr Limit
  • Change address
  • Send to Contact Address

Sending beyond a transaction limit, requires two factor authentication, and is not possible from the mobile app