-
Notifications
You must be signed in to change notification settings - Fork 119
Adding react-native environment #187
base: master
Are you sure you want to change the base?
Adding react-native environment #187
Conversation
Switched this PR to use text-encoding instead of web-encoding because web-encoding broke after ejecting my expo app. |
Friendly bump on this :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use single quotes for strings. In general, the PR is very cool, I'm ready to smear it after corrections
"peerDependencies": { | ||
"react-native": "*", | ||
"fast-sha256": "^1.3.0", | ||
"jssha": "^3.2.0", | ||
"react-native-get-random-values": "^1.7.0", | ||
"text-encoding": "^0.7.0" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package file.json is used for all environments, so I think it's better to remove peerDependencies for react-native from here. Instead, I will add instructions for installing these dependencies to the documentation
Hello, any updates? :) By the way, can I somehow extract this PR into my own local copy of repository and merge it? Maybe make a patch file from this PR for patch-package? I really want to use it in my project! (expo) |
I was able to use this but I ran into some problems:
|
It seems to be problem with TextEncoder Benchmark: class Crypto {
constructor({ SHA1, SHA256, PBKDF2, getRandomBytes }) {
this.SHA1 = SHA1;
this.SHA256 = SHA256;
this.PBKDF2 = PBKDF2;
this.getRandomBytes = getRandomBytes;
this.rsa = new RSA({ SHA1 });
}
async getSRPParams({ g, p, salt1, salt2, gB, password }) {
const H = this.SHA256;
const SH = (data, salt) => {
return this.SHA256(concatBytes(salt, data, salt));
};
const PH1 = async (password, salt1, salt2) => {
return await SH(await SH(password, salt1), salt2);
};
const PH2 = async (password, salt1, salt2) => {
return await SH(
await this.PBKDF2(await PH1(password, salt1, salt2), salt1, 100000),
salt2
);
};
const encoder = new TextEncoder();
// == SECTION 1 == //
const gBigInt = bigInt(g);
const gBytes = bigIntToBytes(gBigInt, 256);
const pBigInt = bytesToBigInt(p);
const aBigInt = bytesToBigInt(this.getRandomBytes(256));
const gABigInt = gBigInt.modPow(aBigInt, pBigInt);
const gABytes = bigIntToBytes(gABigInt);
const gBBytes = bytesToBigInt(gB);
// == SECTION 2 == //
const [k, u, x] = await Promise.all([
H(concatBytes(p, gBytes)),
H(concatBytes(gABytes, gB)),
PH2(encoder.encode(password), salt1, salt2),
]);
// == SECTION 3 == //
const kBigInt = bytesToBigInt(k);
const uBigInt = bytesToBigInt(u);
const xBigInt = bytesToBigInt(x);
const vBigInt = gBigInt.modPow(xBigInt, pBigInt);
const kVBigInt = kBigInt.multiply(vBigInt).mod(pBigInt);
let tBigInt = gBBytes.subtract(kVBigInt).mod(pBigInt);
if (tBigInt.isNegative()) {
tBigInt = tBigInt.add(pBigInt);
}
const sABigInt = tBigInt.modPow(
aBigInt.add(uBigInt.multiply(xBigInt)),
pBigInt
);
const sABytes = bigIntToBytes(sABigInt);
// == SECTION 4 == //
const kA = await H(sABytes);
// == SECTION 5 == //
const M1 = await H(
concatBytes(
xorBytes(await H(p), await H(gBytes)),
await H(salt1),
await H(salt2),
gABytes,
gB,
kA
)
);
// == SECTION 6 == //
return { A: gABytes, M1 };
}
}
Result: 180.29 seconds (3 minutes) |
I ran additional test to find execution time for this line: TextEncoder.encode() function takes 0.01 seconds to complete, and PH2 is 135.61 seconds, so it's a problem with crypto module. I noticed PBKDF2 takes iterations number as argument in function, which is hardcoded to Also account.getPassword method takes about 30 seconds to complete. Maybe it's because I'm running it twice? First time I execute it with new socket, it responds immediately. Update: I think PBKDF2 doesn't work at all. It always gives me incorrect 2fa password error. |
const sha256 = require("fast-sha256"); | ||
|
||
async function PBKDF2(password, salt, iterations) { | ||
return sha256.pbkdf2(password, salt, iterations, 512); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May return incorrect string. Also sometimes getting SRP_ID_INVALID
error
This adds a working react-native environment to mtproto-core. I was unable to get things working with the canonical expo-crypto because it does not accept
Uint8Array
s as inputs to it's hashing methods, so I grabbed some off-the-shelf modules to polyfill all the required methods and built-ins.