mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-20 02:09:10 +01:00
70 lines
2.2 KiB
JavaScript
70 lines
2.2 KiB
JavaScript
import { AppStorage } from './class';
|
|
import Expo from 'expo';
|
|
import { AsyncStorage } from 'react-native';
|
|
const bitcoin = require('bitcoinjs-lib');
|
|
const REQUIRE_NUM_CHUNKS = 16;
|
|
|
|
// 256 priv key = 32 bytes x 8 chunks
|
|
// each chunk needs 32 bits of entropy (since ISAAC is 32 bit)
|
|
// 8 * 32 = 256 bits of entropy for one private key
|
|
// we read accelerometer 10 times per sec, getting 2 bits of entropy => 20 bits of entropy per sec
|
|
// 256/20 = 13 sec of gathering entropy
|
|
|
|
let chunks = []; // array of 32bit ints
|
|
let currenChunk = ''; // temp storage of bits (string)
|
|
let runningListeners = 0;
|
|
|
|
let listener = function(accelerometerData) {
|
|
let hex = bitcoin.crypto.sha256(accelerometerData.x + '\t' + accelerometerData.y + '\t' + accelerometerData.z).toString('hex'); // whitening
|
|
let dec = parseInt('0x' + hex[0] + hex[1]);
|
|
let entropyBits = dec & 0b11;
|
|
|
|
currenChunk += ((entropyBits < 2 && '0') || '') + entropyBits.toString(2); // always 2-char string
|
|
|
|
if (currenChunk.length === 32) {
|
|
// got enough bits for 32bit int
|
|
console.log(currenChunk, parseInt(currenChunk, 2));
|
|
chunks.push(currenChunk);
|
|
chunks.push(parseInt(currenChunk, 2));
|
|
currenChunk = '';
|
|
}
|
|
|
|
if (chunks.length >= REQUIRE_NUM_CHUNKS) {
|
|
console.log('got enough entropy, saving to storage');
|
|
Expo.Accelerometer.removeAllListeners();
|
|
runningListeners--;
|
|
AsyncStorage.setItem(AppStorage.ENTROPY, JSON.stringify(chunks));
|
|
}
|
|
};
|
|
|
|
async function start() {
|
|
let entropy = await AsyncStorage.getItem(AppStorage.ENTROPY);
|
|
try {
|
|
entropy = JSON.parse(entropy);
|
|
} catch (Err) {
|
|
entropy = [];
|
|
}
|
|
chunks = entropy || [];
|
|
console.log('got', chunks.length * 32, 'bits of entropy');
|
|
|
|
setInterval(() => {
|
|
if (chunks.length < REQUIRE_NUM_CHUNKS && runningListeners === 0) {
|
|
console.log('not enough entropy, starting listener to gather');
|
|
Expo.Accelerometer.addListener(listener);
|
|
runningListeners++;
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
function gotEnoughEntropy() {
|
|
return chunks.length >= 8; // enough for at least one priv key
|
|
}
|
|
|
|
function get32bitInt() {
|
|
return chunks.pop();
|
|
}
|
|
|
|
module.exports.get32bitInt = get32bitInt;
|
|
module.exports.start = start;
|
|
module.exports.gotEnoughEntropy = gotEnoughEntropy;
|