Skip to content

BIP39 UI is the interface for editable mnemonic generation, with checksum recalculation and strength evaluation, on a vanilla interface with drag/drop and autocomplete. Integrate Self-Custodial Access Control, instead of traditional E-mail. Client and server side.

License

Notifications You must be signed in to change notification settings

VivaRado/bip39ui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Preface

BIP39UI is an Open Source project of VivaRado.

Screenshot

Screenshot

Introduction

BIP39 editable mnemonic with checksum recalculation, strength evaluation on a vanilla interface with drag/drop and autocomplete.

Contributors:


Profile

Introduction / Profile


  • Company: VivaRado LLP
  • Designer: Andreas Kalpakidis
  • Management: Madina Akhmatova

Project Overview

Introduction / Project Overview


  • Project Name: BIP39UI
  • Code Name: 39
  • Proposal Date: 20/09/2024

Design

BIP39UI is project ment to be used for access control, as a replacement to email or phone validation. A client creates a 12 or 24 word mnemonic generated on his machine (client side) for efficiency and load reduction of the servers, by choosing the words from the BIP39 standardized wordlist of 2048 words utilizing a user interface that allows for word to be draggable and discoverable with autocomplete. Post submission the vendor then validates the mnemonic (server side) and if valid, only stores the irreversible seed for later comparisson in password recovery routines maintaining anonymity for the client.

The source consists of BIP39, MnemStrong and the Interface.


BIP39

Design / BIP39


The BIP39 is responsible for generating a mnemonic of given length, parsing an existing mnemonic as entropy, turning said entropy back to a mnemonic, generating a seed from a mnemonic, and generating a list of valid checksum words if the last word of the mnemonic is missing or invalid. We go over these in detail further down.

To aleviate unnessessary server side load by issuing BIP39, validating and issuing checksums - every time the client interacts with the interface, we provide the appropriate ESM modules, in the file marked as .clt.esm.js, for that to happen on the client. When eventually the client submits the mnemonic to the server, you can run the corresponding validation functions once, in the file marked as .srv.cjs.js, to make sure what you are handling is a valid mnemonic.


Composition

Design / BIP39 / Composition


The src/bip39/deps contains ESM (ECMAScript modules) and CJS (Common JavaScript) files.


Assert

The assertions for the client include an additional report parameter that gets carried all the way from the functions in bip39/index to the functions src/bip39/deps/assert, in order to return the assertion results throughout the code.


Crypto

The built in NodeJS.crypto module, is used for various functions like pbkdf2, getRandomValues, createHash, this is replaced on the client with widely available Web APIs SubtleCrypto and window.crypto and the coresponding functions, to avoid creating overhead by using third party implementations.


Checksum Recalculation

As our BIP39 implementation is interactive, the checksum will be invalid as soon as the client replaces one of the words or drag/drops another one. For that reason we provide the checksumWords function that given 12-24 words sans the last (checksum), will recalculate and return the words that are valid for the given mnemonic. We then move those to the interface for the client to pick.


Functions

Design / BIP39 / Functions


Here is an overview of the BIP39 function(s):


generateMnemonic ( strength, report [opt.clsd], wordlist [opt.] )

param strength: mnemonic strength 128-256 bits.
param report: optional client side only, error report boolean
param wordlist: optional imported wordlist for specific language.


returns (report:false): 12-24 words.
returns (report:true): Object { mnemonic: 12-24 words, assertions: Array }


Generates x random words. Uses Cryptographically-Secure Random Number Generator.


entropyToMnemonic ( entropy, report [opt.clsd], wordlist [opt.] )

param entropy: entropy byte array.
param report: optional client side only, error report boolean
param wordlist: optional imported wordlist for specific language.


returns (report:false): 12-24 words.
returns (report:true): Object { mnemonic: 12-24 words, assertions: Array }


Reversible: Converts raw entropy in form of byte array to mnemonic string.


mnemonicToEntropy ( mnemonic, report [opt.clsd], wordlist [opt.] )

param mnemonic: 12-24 words.
param report: optional client side only, error report boolean
param wordlist: optional imported wordlist for specific language.


returns (report:false): Buffer / Uint8Array (clsd)
returns (report:true): Object { mnemonic: 12-24 words, assertions: Array }


Reversible: Converts mnemonic string to raw entropy in form of byte array.


validateMnemonic ( mnemonic, report [opt.clsd], wordlist [opt.] )

param mnemonic: 12-24 words.
param report: optional client side only, error report boolean
param wordlist: optional imported wordlist for specific language.


returns (report:false): boolean
returns (report:true): Object { mnemonic: 12-24 words, assertions: Array }


Validates mnemonic for being 12-24 words contained in wordlist.


mnemonicToSeed ( mnemonic, passphrase, report [opt.clsd], wordlist [opt.] )

param mnemonic: mnemonic 12-24 words (string | Uint8Array).
param passphrase: optional string that will additionally protect the key.
param report: optional client side only, error report boolean
param wordlist: imported wordlist for specific language.


returns (report:false): 64 bytes of key data.
returns (report:true): Object { seed: 64 bytes of key data, assertions: Array }


Irreversible (Sync/Async): Uses KDF to derive 64 bytes of key data from mnemonic and optional password.


checksumWords ( mnemonic, wordlist [opt.] )

param mnemonic: mnemonic 12-24 words (Array).
param wordlist: optional imported wordlist for specific language.


returns: Array with valid checksum words.


Generates array of valid checksum words given a mnemonic with invalid checksum.


MnemStrong

Design / MnemStrong


The MnemStrong is responsible for evaluating given mnemonic, it is based on zxcvbn with all the bloat removed as we are not evaluating a password comprised of alphanumeric plus common symbols, but a mnemonic constructed by words from a predefined wordlist. The evaluation functions detect dictionary words (words in the wordlist), unbroken repetition (repeated words) and dictionary sequences (words in sequence just as they appear in the wordlist ). The percentage estimation is based on average BIP39 scores for 128 that is (92 rounded to 100) and 256 that is (176 rounded to 180) Bit mnemonics.


Composition

Design / MnemStrong / Composition


The src/mnemstrong/deps contains ESM (ECMAScript modules) and CJS (Common JavaScript) files. Even though we provide ESM and CJS for Mnemstrong those are essentially the same files.


Functions

Design / MnemStrong / Functions


Here is an overview of the MnemStrong function(s):


mnemstrong ( mnemonic )

param mnemonic: mnemonic 12-24 words (Array).


returns: Object { sequence: matches Array, report_calc_time: Number, feedback: warning Array, crack_times_seconds: Object, crack_times_display: Object, score: Number, percentage: percent Number }


Evaluates a mnemonic.


Interface

Design / Interface


The Interface provides the interactivity with the wordlist to the client, specifically there is the ability to select the strength/size of the mnemonic between two options (128/256) using a dropdown like this.

The input fields are draggable, can autocomplete and are arrow navigable. There also is a generate button.


Composition

Design / Interface / Composition


The src/interface contains ESM (ECMAScript modules) only, the CSS is located in the src/interface/styles directory.


MnemonicUI

Design / Interface / MnemonicUI


This module is responsible for all the interface interactions, and binds together all the rest of the interface classes. It initiates the MnemStrong class and Autocomplete class and manages their state in relation to the mnemonic and checksum recalculation.


Usage

Design / Interface / MnemonicUI / Usage


Initiating the Mnemonic user interface by including the MnemonicUI class:

<script src="./src/interface/mnemonicui.esm.js" type="module"></script>

The code bellow is included in the file above. Both bip39 and MnemonicUI are exposed to the window, so you can run them at will.

Config Parameters

mnemostrong: If you do not want the mnemonic strength check to run, include mnemostrong:false in the config.

populate: If you do not want the input fields populated, include populate:false in the config.

// For active interface during mnemonic creation.
new MnemonicInterface();

// For passive interface during mnemonic recovery.
var config = {
  "mnemstrong":false,
  "populate": false
}

new MnemonicInterface(config);


Functions

Design / Interface / MnemonicUI / Functions


Here is an overview of the MnemonicUI functions:


reflectChecksumElm ()

Defines the interactivity of checksum elements by setting the element draggable attribute to false or true and adding or removing the checksum_elm class for current checksum and ante checksum respectively.

Distributes the appropriate wordlist array (dictionary or valid checksums) to the elements currently in the checksum positions (index 12 or 24) by retargeting the Autocomplete class using Autocomplete.destroy() on current and ante checksum, and Autocomplete.reattach() to self.autcom_sc and self.autcom_ac. These are the two groups of autocompletes, the autcom_sc sans checksum (without checksums) and autcom_ac avec checksum (with checksums).

Then updates the results pool Autocomplete.setpool() of the current checksum element with the valid checksums array set to self._cfg._vc from mnem_evaluate() .

Finally is sets the current checksum element's input value to the first value from the valid checksums array.


reflectMnemonic ( strength )

param strength: Number 128 or 256.


Generates a mnemonic of strength 128 or 256 and sets the values to the input field elements.


reflectActive ( strength, reflchs )

param strength: Number 128, 256 or 0.
param reflchs: boolean (reflect checksum), default is false.


Sets the self._cfg._ml (mnemonic length) according to the active selection of the dropdown. Resets the object order stored in data-index attribute.

Calls for mnemonic generation, evaluation and checksum element update and refreshes the data-index attribute.


reflectFeedback ( mv, ms )

param mv: Array (mnemonic validation).
param ms: Array (mnemonic strength).


Visual alerts and strength bar visuals.


mnemEvaluate ( updchs, reflchs, cb )

param updchs: boolean (update checksum).
param reflchs: boolean (reflect checksum).
param cb: callback function.


Runs validations and evaluations of current mnemonic with valid checksum. Forwards the feedback to reflect_feedback for visual alerts and strength bar visuals on the client. Updates current mnemonic array self._cfg._cm if updchs is true. Updates checksum element value if reflchs is true.


initAutocompleteGroups ()

Initiate the AutoComplete groups self.autcom_sc and self.autcom_ac.


initDraggable ()

Initiate dragstart, dragover, drop, dragend events on passphrase inputs container. Prevent checksum elements from being draggable. Evaluate mnemonic on drop and generate a new mnemonic. Manage Autocomplete reattachment to input groups.


AutoComplete

Design / Interface / AutoComplete


Autocomplete is responsible for displaying the input fields and their adding interactivity by setting events like input search, arrow navigation, click outside and escape press to close the dropdown. Loading the words to the interface and updating valid checksum words.


Functions

Design / Interface / AutoComplete / Functions


Here is an overview of the AutoComplete functions:


externalEvents ()

Setup external events, up and down arrow navigation, escape key press and click outside.


selctEvt ( self, ac )

param self: passing object context to avoid event this collision.
param ac: autocomplete input element.


Click on autocomplete dropdown element.


inputEvt ( self, ac )

param self: passing object context to avoid event this collision.
param ac: autocomplete input element.


Handle autocomplete field input event.


clickEvt ( self, ac )

param self: passing object context to avoid event this collision.
param ac: autocomplete input element.


Handle click event on autocomplete dropdown elements.


exterEvtHandler ()

Close the autocomplete on click outside the autocomplete.


arrowEvtHandler ()

Navigate the autocomplete results with up and down arrow.


clickEvtHandler ( ac )

param ac: autocomplete input element.


Pick item in autocomplete dropdown on click.


selctEvtHandler ( ac )

param ac: autocomplete input element.


Select autocomplete input text on click.


inputEvtHandler ( ac )

param ac: autocomplete input element.


Initiate search pool filtering on input event.


activate ( ac )

param ac: autocomplete input element.


Activate external events and click event for autocomplete.


toggle ( ac )

param ac: autocomplete input element.


Toggle show / hide of autocomplete dropdown.


show ( ac )

param ac: autocomplete input element.


Show autocomplete dropdown.


hide ( ac, emit )

param ac: autocomplete input element.
param emit: emit the event, default is false.


Hide autocomplete dropdown.


filterRes ( ac, marker, term )

param ac: autocomplete input element.
param marker: autocomplete dropdown item element.
param term: search term


Results pool filtering.


termInPool ( ac, term )

param ac: autocomplete input element.
param term: search term


Input of words not currently in the search pool or input is empty, results in error.


inputReflection ( e, ac )

param e: event.
param ac: autocomplete input element.


Manage the way the autocomplete reacts to input value.


fillSearchPool ( ac, serv_array )

param ac: autocomplete input element.
param serv_array: wordlist Array.


Create autocomplete element pool from provided array.


clearHiLight ()

Clear highlight from arrow navigation.


build ( ac )

param ac: autocomplete input element.


Build autocomplete.


interact ( ac )

param ac: autocomplete input element.


Set up autocomplete input element events.


reattach ( ac )

param ac: autocomplete input element.


Reattach input to autocomplete class


destroy ( self, ac, remove )

param self: passing object context to avoid event this collision.
param ac: autocomplete input element.
param remove: boolean, remove element from dom.


Destroy autocomplete and remove events from input.



Reports

Design / Interface / Reports


Contains the strength_check and display_alert report rendering functions.


Functions

Design / Interface / Reports / Functions


Here is an overview of the Reports functions:


strengthCheck ( strength_bar, value )

param strength_bar: strength bar element.
param value: Number.


Display strength value on strength bar as percentage.


displayAlert ( alert_data, target_alert, animation )

param alert_data: feedback array.
param target_alert: alert element.
param animation: Boolean.


Display feedback as alerts.


Production

To work on extending this module a few things are provided:

Run in browser with reload allong with gulp watch:

npm run dev

Just build with gulp

npm run build

Test the server side functions

npm run test

Installation

BIP39UI does not have any dependencies, other than those for development (--save-dev).

To install:

npm install

Glossary

BIP39: Bitcoin Improvement Proposal 0039.
opt.: Optional.
clsd: Client Side.


Reference

BIP39 Mediawiki GitHub


About

BIP39 UI is the interface for editable mnemonic generation, with checksum recalculation and strength evaluation, on a vanilla interface with drag/drop and autocomplete. Integrate Self-Custodial Access Control, instead of traditional E-mail. Client and server side.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published