16 changed files with 469 additions and 3345 deletions
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 11 KiB |
@ -1 +1 @@
|
||||
<!doctype html><html lang=en ng-app=myApp manifest=webogram.appcache><head><meta charset=utf-8><meta name=viewport content="width=device-width, user-scalable=no"><title>Webogram</title><link rel=stylesheet href=css/app.css><link rel=icon href=favicon.ico type=image/x-icon><meta property=og:title content=Webogram><meta property=og:url content="http://zhukov.github.io/webogram/"><meta property=og:image content=http://zhukov.github.io/webogram/img/logo_share.png><meta property=og:site_name content=Webogram><meta property=og:description content="Welcome to an experimental web-client of Telegram messenger. See https://github.com/zhukov/webogram for more info."></head><body><div ng-view=""></div><script src=js/app.js></script></body></html> |
||||
<!doctype html><html lang=en ng-app=myApp manifest=webogram.appcache><head><meta charset=utf-8><meta name=viewport content="width=device-width, user-scalable=no"><title>Webogram</title><link rel=stylesheet href=css/app.css><link rel=icon href=favicon.ico type=image/x-icon><meta property=og:title content=Webogram><meta property=og:url content="http://zhukov.github.io/webogram/"><meta property=og:image content=http://zhukov.github.io/webogram/img/logo_share.png><meta property=og:site_name content=Webogram><meta property=og:description content="Welcome to an experimental web-client of Telegram messenger. See https://github.com/zhukov/webogram for more info."></head><body><div class=page_wrap ng-view=""></div><script src=js/app.js></script></body></html> |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,435 @@
|
||||
/*! |
||||
* Webogram v0.1.7 - messaging web application for MTProto |
||||
* https://github.com/zhukov/webogram
|
||||
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com> |
||||
* https://github.com/zhukov/webogram/blob/master/LICENSE
|
||||
*/ |
||||
|
||||
function bigint (num) { |
||||
return new BigInteger(num.toString(16), 16); |
||||
} |
||||
|
||||
function bigStringInt (strNum) { |
||||
return new BigInteger(strNum, 10); |
||||
} |
||||
|
||||
function dHexDump (bytes) { |
||||
var arr = []; |
||||
for (var i = 0; i < bytes.length; i++) { |
||||
if (i && !(i % 2)) { |
||||
if (!(i % 16)) { |
||||
arr.push("\n"); |
||||
} else if (!(i % 4)) { |
||||
arr.push(' '); |
||||
} else { |
||||
arr.push(' '); |
||||
} |
||||
} |
||||
arr.push((bytes[i] < 16 ? '0' : '') + bytes[i].toString(16)); |
||||
} |
||||
|
||||
console.log(arr.join('')); |
||||
} |
||||
|
||||
function bytesToHex (bytes) { |
||||
bytes = bytes || []; |
||||
var arr = []; |
||||
for (var i = 0; i < bytes.length; i++) { |
||||
arr.push((bytes[i] < 16 ? '0' : '') + (bytes[i] || 0).toString(16)); |
||||
} |
||||
return arr.join(''); |
||||
} |
||||
|
||||
function bytesFromHex (hexString) { |
||||
var len = hexString.length, |
||||
i, |
||||
bytes = []; |
||||
|
||||
for (i = 0; i < len; i += 2) { |
||||
bytes.push(parseInt(hexString.substr(i, 2), 16)); |
||||
} |
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
function bytesToBase64 (bytes) { |
||||
var mod3, result = ''; |
||||
|
||||
for (var nLen = bytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { |
||||
mod3 = nIdx % 3; |
||||
nUint24 |= bytes[nIdx] << (16 >>> mod3 & 24); |
||||
if (mod3 === 2 || nLen - nIdx === 1) { |
||||
result += String.fromCharCode( |
||||
uint6ToBase64(nUint24 >>> 18 & 63), |
||||
uint6ToBase64(nUint24 >>> 12 & 63), |
||||
uint6ToBase64(nUint24 >>> 6 & 63), |
||||
uint6ToBase64(nUint24 & 63) |
||||
); |
||||
nUint24 = 0; |
||||
} |
||||
} |
||||
|
||||
return result.replace(/A(?=A$|$)/g, '='); |
||||
} |
||||
|
||||
function uint6ToBase64 (nUint6) { |
||||
return nUint6 < 26 |
||||
? nUint6 + 65 |
||||
: nUint6 < 52 |
||||
? nUint6 + 71 |
||||
: nUint6 < 62 |
||||
? nUint6 - 4 |
||||
: nUint6 === 62 |
||||
? 43 |
||||
: nUint6 === 63 |
||||
? 47 |
||||
: 65; |
||||
} |
||||
|
||||
function bytesCmp (bytes1, bytes2) { |
||||
var len = bytes1.length; |
||||
if (len != bytes2.length) { |
||||
return false; |
||||
} |
||||
|
||||
for (var i = 0; i < len; i++) { |
||||
if (bytes1[i] != bytes2[i]) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
function bytesXor (bytes1, bytes2) { |
||||
var len = bytes1.length, |
||||
bytes = []; |
||||
|
||||
for (var i = 0; i < len; ++i) { |
||||
bytes[i] = bytes1[i] ^ bytes2[i]; |
||||
} |
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
function bytesToWords (bytes) { |
||||
var len = bytes.length, |
||||
words = []; |
||||
|
||||
for (var i = 0; i < len; i++) { |
||||
words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8); |
||||
} |
||||
|
||||
return new CryptoJS.lib.WordArray.init(words, len); |
||||
} |
||||
|
||||
function bytesFromWords (wordArray) { |
||||
var words = wordArray.words, |
||||
sigBytes = wordArray.sigBytes, |
||||
bytes = []; |
||||
|
||||
for (var i = 0; i < sigBytes; i++) { |
||||
bytes.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff); |
||||
} |
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
function bytesFromBigInt (bigInt, len) { |
||||
var bytes = bigInt.toByteArray(); |
||||
|
||||
while (!bytes[0] && (!len || bytes.length > len)) { |
||||
bytes = bytes.slice(1); |
||||
} |
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
function bytesToArrayBuffer (b) { |
||||
return (new Uint8Array(b)).buffer; |
||||
} |
||||
|
||||
function bytesFromArrayBuffer (buffer) { |
||||
var len = buffer.byteLength, |
||||
byteView = new Uint8Array(buffer), |
||||
bytes = []; |
||||
|
||||
for (var i = 0; i < len; ++i) { |
||||
bytes[i] = byteView[i]; |
||||
} |
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
function longToInts (sLong) { |
||||
var divRem = bigStringInt(sLong).divideAndRemainder(bigint(0x100000000)); |
||||
|
||||
return [divRem[0].intValue(), divRem[1].intValue()]; |
||||
} |
||||
|
||||
function longToBytes (sLong) { |
||||
return bytesFromWords({words: longToInts(sLong), sigBytes: 8}).reverse(); |
||||
} |
||||
|
||||
function longFromInts (high, low) { |
||||
return bigint(high).shiftLeft(32).add(bigint(low)).toString(10); |
||||
} |
||||
|
||||
function intToUint (val) { |
||||
val = parseInt(val); |
||||
if (val < 0) { |
||||
val = val + 4294967296; |
||||
} |
||||
return val; |
||||
} |
||||
|
||||
function uintToInt (val) { |
||||
if (val > 2147483647) { |
||||
val = val - 4294967296; |
||||
} |
||||
return val; |
||||
} |
||||
|
||||
function sha1Hash (bytes) { |
||||
// console.log('SHA-1 hash start');
|
||||
var hashBytes = sha1.hash(bytes, true); |
||||
// console.log('SHA-1 hash finish');
|
||||
|
||||
return hashBytes; |
||||
} |
||||
|
||||
|
||||
|
||||
function rsaEncrypt (publicKey, bytes) { |
||||
var needPadding = 255 - bytes.length; |
||||
if (needPadding > 0) { |
||||
var padding = new Array(needPadding); |
||||
(new SecureRandom()).nextBytes(padding); |
||||
|
||||
bytes = bytes.concat(padding); |
||||
} |
||||
|
||||
// console.log('RSA encrypt start');
|
||||
var N = new BigInteger(publicKey.modulus, 16), |
||||
E = new BigInteger(publicKey.exponent, 16), |
||||
X = new BigInteger(bytes), |
||||
encryptedBigInt = X.modPowInt(E, N), |
||||
encryptedBytes = bytesFromBigInt(encryptedBigInt, 256); |
||||
|
||||
// console.log('RSA encrypt finish');
|
||||
|
||||
return encryptedBytes; |
||||
} |
||||
|
||||
function aesEncrypt (bytes, keyBytes, ivBytes) { |
||||
// console.log('AES encrypt start', bytes.length/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/);
|
||||
|
||||
var needPadding = 16 - (bytes.length % 16); |
||||
if (needPadding > 0 && needPadding < 16) { |
||||
var padding = new Array(needPadding); |
||||
(new SecureRandom()).nextBytes(padding); |
||||
|
||||
bytes = bytes.concat(padding); |
||||
} |
||||
|
||||
var encryptedWords = CryptoJS.AES.encrypt(bytesToWords(bytes), bytesToWords(keyBytes), { |
||||
iv: bytesToWords(ivBytes), |
||||
padding: CryptoJS.pad.NoPadding, |
||||
mode: CryptoJS.mode.IGE |
||||
}).ciphertext; |
||||
|
||||
var encryptedBytes = bytesFromWords(encryptedWords); |
||||
|
||||
// console.log('AES encrypt finish');
|
||||
|
||||
return encryptedBytes; |
||||
} |
||||
|
||||
function aesDecrypt (encryptedBytes, keyBytes, ivBytes) { |
||||
// console.log('AES decrypt start', encryptedBytes.length/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/);
|
||||
|
||||
var decryptedWords = CryptoJS.AES.decrypt({ciphertext: bytesToWords(encryptedBytes)}, bytesToWords(keyBytes), { |
||||
iv: bytesToWords(ivBytes), |
||||
padding: CryptoJS.pad.NoPadding, |
||||
mode: CryptoJS.mode.IGE |
||||
}); |
||||
|
||||
var bytes = bytesFromWords(decryptedWords); |
||||
|
||||
// console.log('AES decrypt finish');
|
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
function gzipUncompress (bytes) { |
||||
// console.log('Gzip uncompress start');
|
||||
var result = (new Zlib.Gunzip(bytes)).decompress(); |
||||
// console.log('Gzip uncompress finish');
|
||||
return result; |
||||
} |
||||
|
||||
function nextRandomInt (maxValue) { |
||||
return Math.floor(Math.random() * maxValue); |
||||
}; |
||||
|
||||
function pqPrimeFactorization (pqBytes) { |
||||
var what = new BigInteger(pqBytes), |
||||
result = false; |
||||
|
||||
console.log('PQ start', pqBytes, what.bitLength()); |
||||
|
||||
if (what.bitLength() <= 64) { |
||||
// console.time('PQ long');
|
||||
try { |
||||
result = pqPrimeLong(goog.math.Long.fromString(what.toString(16), 16)); |
||||
} catch (e) { |
||||
console.error('Pq long Exception', e); |
||||
}; |
||||
// console.timeEnd('PQ long');
|
||||
} |
||||
// console.log(result);
|
||||
|
||||
if (result === false) { |
||||
// console.time('pq BigInt');
|
||||
result = pqPrimeBigInteger(what); |
||||
// console.timeEnd('pq BigInt');
|
||||
} |
||||
|
||||
console.log('PQ finish'); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
function pqPrimeBigInteger (what) { |
||||
var it = 0, |
||||
g; |
||||
for (var i = 0; i < 3; i++) { |
||||
var q = (nextRandomInt(128) & 15) + 17, |
||||
x = bigint(nextRandomInt(1000000000) + 1), |
||||
y = x.clone(), |
||||
lim = 1 << (i + 18); |
||||
|
||||
for (var j = 1; j < lim; j++) { |
||||
++it; |
||||
var a = x.clone(), |
||||
b = x.clone(), |
||||
c = bigint(q); |
||||
|
||||
while (!b.equals(BigInteger.ZERO)) { |
||||
if (!b.and(BigInteger.ONE).equals(BigInteger.ZERO)) { |
||||
c = c.add(a); |
||||
if (c.compareTo(what) > 0) { |
||||
c = c.subtract(what); |
||||
} |
||||
} |
||||
a = a.add(a); |
||||
if (a.compareTo(what) > 0) { |
||||
a = a.subtract(what); |
||||
} |
||||
b = b.shiftRight(1); |
||||
} |
||||
|
||||
x = c.clone(); |
||||
var z = x.compareTo(y) < 0 ? y.subtract(x) : x.subtract(y); |
||||
g = z.gcd(what); |
||||
if (!g.equals(BigInteger.ONE)) { |
||||
break; |
||||
} |
||||
if ((j & (j - 1)) == 0) { |
||||
y = x.clone(); |
||||
} |
||||
} |
||||
if (g.compareTo(BigInteger.ONE) > 0) { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
var f = what.divide(g), P, Q; |
||||
|
||||
if (g.compareTo(f) > 0) { |
||||
P = f; |
||||
Q = g; |
||||
} else { |
||||
P = g; |
||||
Q = f; |
||||
} |
||||
|
||||
return [bytesFromBigInt(P), bytesFromBigInt(Q)]; |
||||
} |
||||
|
||||
function gcdLong(a, b) { |
||||
while (a.notEquals(goog.math.Long.ZERO) && b.notEquals(goog.math.Long.ZERO)) { |
||||
while (b.and(goog.math.Long.ONE).equals(goog.math.Long.ZERO)) { |
||||
b = b.shiftRight(1); |
||||
} |
||||
while (a.and(goog.math.Long.ONE).equals(goog.math.Long.ZERO)) { |
||||
a = a.shiftRight(1); |
||||
} |
||||
if (a.compare(b) > 0) { |
||||
a = a.subtract(b); |
||||
} else { |
||||
b = b.subtract(a); |
||||
} |
||||
} |
||||
return b.equals(goog.math.Long.ZERO) ? a : b; |
||||
} |
||||
|
||||
function pqPrimeLong(what) { |
||||
// console.log('start long');
|
||||
var it = 0, |
||||
g; |
||||
for (var i = 0; i < 3; i++) { |
||||
var q = goog.math.Long.fromInt((nextRandomInt(128) & 15) + 17), |
||||
x = goog.math.Long.fromInt(nextRandomInt(1000000000) + 1), |
||||
y = x, |
||||
lim = 1 << (i + 18); |
||||
|
||||
for (var j = 1; j < lim; j++) { |
||||
++it; |
||||
// if (!(it % 100)) {
|
||||
// console.log(dT(), 'it', it, i, j, x.toString());
|
||||
// }
|
||||
var a = x, |
||||
b = x, |
||||
c = q; |
||||
|
||||
while (b.notEquals(goog.math.Long.ZERO)) { |
||||
if (b.and(goog.math.Long.ONE).notEquals(goog.math.Long.ZERO)) { |
||||
c = c.add(a); |
||||
if (c.compare(what) > 0) { |
||||
c = c.subtract(what); |
||||
} |
||||
} |
||||
a = a.add(a); |
||||
if (a.compare(what) > 0) { |
||||
a = a.subtract(what); |
||||
} |
||||
b = b.shiftRight(1); |
||||
} |
||||
|
||||
x = c; |
||||
var z = x.compare(y) < 0 ? y.subtract(x) : x.subtract(y); |
||||
g = gcdLong(z, what); |
||||
if (g.notEquals(goog.math.Long.ONE)) { |
||||
break; |
||||
} |
||||
if ((j & (j - 1)) == 0) { |
||||
y = x; |
||||
} |
||||
} |
||||
if (g.compare(goog.math.Long.ONE) > 0) { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
var f = what.div(g), P, Q; |
||||
|
||||
if (g.compare(f) > 0) { |
||||
P = f; |
||||
Q = g; |
||||
} else { |
||||
P = g; |
||||
Q = f; |
||||
} |
||||
|
||||
return [bytesFromHex(P.toString(16)), bytesFromHex(Q.toString(16))]; |
||||
} |
Loading…
Reference in new issue