lotta stoof
wew
This commit is contained in:
parent
73ec4544f1
commit
0ce0fe099d
13 changed files with 160 additions and 37 deletions
|
@ -13,13 +13,33 @@ window.onload = function() {
|
||||||
|
|
||||||
// check for webgl support
|
// check for webgl support
|
||||||
var canvas = document.getElementById("cs");
|
var canvas = document.getElementById("cs");
|
||||||
if(!(canvas.getContext("webgl") || canvas.getContext("experimental-webgl")))
|
Rendering.context = canvas.getContext("webgl");
|
||||||
support.webgl = false;
|
if(!Rendering.context) {
|
||||||
|
Rendering.context = canvas.getContext("experimental-webgl");
|
||||||
|
if(!Rendering.context)
|
||||||
|
support.webgl = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for animation frame support
|
||||||
|
window.requestAnimationFrame = window.requestAnimationFrame
|
||||||
|
|| window.webkitRequestAnimationFrame
|
||||||
|
|| window.mozRequestAnimationFrame
|
||||||
|
|| window.oRequestAnimationFrame
|
||||||
|
|| window.msRequestAnimationFrame;
|
||||||
|
if(!window.requestAnimationFrame)
|
||||||
|
support.anim = false;
|
||||||
|
|
||||||
// check for indexedDB support
|
// check for indexedDB support
|
||||||
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
window.indexedDB = window.indexedDB
|
||||||
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBransaction;
|
|| window.mozIndexedDB
|
||||||
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
|
|| window.webkitIndexedDB
|
||||||
|
|| window.msIndexedDB;
|
||||||
|
window.IDBTransaction = window.IDBTransaction
|
||||||
|
|| window.webkitIDBTransaction
|
||||||
|
|| window.msIDBransaction;
|
||||||
|
window.IDBKeyRange = window.IDBKeyRange
|
||||||
|
|| window.webkitIDBKeyRange
|
||||||
|
|| window.msIDBKeyRange;
|
||||||
if(!window.indexedDB)
|
if(!window.indexedDB)
|
||||||
support.idb = false;
|
support.idb = false;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,10 @@ class Connection {
|
||||||
Connection.sock.onclose = Connection.onClose;
|
Connection.sock.onclose = Connection.onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static send(msg: Packet) {
|
||||||
|
Connection.sock.send(msg.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
private static onOpen(event: any): void {
|
private static onOpen(event: any): void {
|
||||||
Connection._isOpen = true;
|
Connection._isOpen = true;
|
||||||
|
|
||||||
|
@ -32,11 +36,12 @@ class Connection {
|
||||||
var raw = new Uint8Array(event.data);
|
var raw = new Uint8Array(event.data);
|
||||||
var msg = Packet.fromBytes(raw);
|
var msg = Packet.fromBytes(raw);
|
||||||
console.log(msg);
|
console.log(msg);
|
||||||
console.log(msg[1].toString());
|
|
||||||
|
|
||||||
switch(msg.id) {
|
switch(msg.id) {
|
||||||
case kPacketId.KeyExchange:
|
case kPacketId.KeyExchange:
|
||||||
|
var response = Key.generateResponsePacket(msg);
|
||||||
|
Connection.send(response);
|
||||||
|
console.log(response);
|
||||||
break;
|
break;
|
||||||
case kPacketId.LoginAttempt:
|
case kPacketId.LoginAttempt:
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,74 @@
|
||||||
class KeyExchange {
|
class Key {
|
||||||
|
private static secret: bigInt;
|
||||||
|
private static _privateKey: bigInt = new bigInt(0);
|
||||||
|
private static get privateKey(): bigInt {
|
||||||
|
return Key._privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static get succeeded(): boolean {
|
||||||
|
return !Key._privateKey.eq(new bigInt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static init(): void {
|
||||||
|
Key.secret = Random.generatePrime(512);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static generateResponsePacket(request: Packet): Packet {
|
||||||
|
var generator = new bigInt(request[0].toString(), 16);
|
||||||
|
var modulus = new bigInt(request[1].toString(), 16);
|
||||||
|
var serverKey = new bigInt(request[2].toString(), 16);
|
||||||
|
|
||||||
|
Key._privateKey = serverKey.modPow(Key.secret, modulus);
|
||||||
|
return Packet.create(kPacketId.KeyExchange, [generator.modPow(Key.secret, modulus).toString(16)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Cipher {
|
||||||
|
private static key: Uint8Array;
|
||||||
|
private static state: Uint8Array;
|
||||||
|
|
||||||
|
public static init(key: bigInt) {
|
||||||
|
Cipher.key = key.toByteArray(512 / 8);
|
||||||
|
Cipher.state = new Uint8Array(256);
|
||||||
|
Cipher.state.map((value: number, index: number): number => {
|
||||||
|
return index;
|
||||||
|
});
|
||||||
|
|
||||||
|
var i, j = 0, t;
|
||||||
|
for(i = 0; i < 256; ++i) {
|
||||||
|
j = (j + Cipher.state[i] + Cipher.key[i % Cipher.key.length]) % 256;
|
||||||
|
|
||||||
|
t = Cipher.state[i];
|
||||||
|
Cipher.state[i] = Cipher.state[j];
|
||||||
|
Cipher.state[j] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cipher.generateStream(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static generateStream(length: number): Uint8Array {
|
||||||
|
var stream = new Uint8Array(length);
|
||||||
|
var i = 0, j = 0, x, t;
|
||||||
|
|
||||||
|
for(x = 0; x < length; ++x) {
|
||||||
|
i = (i + 1) % 256;
|
||||||
|
j = (j + Cipher.state[i]) % 256;
|
||||||
|
|
||||||
|
t = Cipher.state[i];
|
||||||
|
Cipher.state[i] = Cipher.state[j];
|
||||||
|
Cipher.state[j] = t;
|
||||||
|
|
||||||
|
stream[x] = Cipher.state[(Cipher.state[i] + Cipher.state[j]) % 256];
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static parse(data: Uint8Array): Uint8Array {
|
||||||
|
var stream = Cipher.generateStream(data.length);
|
||||||
|
for(var i = 0; i < data.length; ++i)
|
||||||
|
data[i] = data[i] ^ stream[i];
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ class Entrypoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static start(): void {
|
public static start(): void {
|
||||||
Connection.open();
|
Key.init();
|
||||||
|
|
||||||
FileCache.initCache(
|
FileCache.initCache(
|
||||||
// SUCCESS
|
// SUCCESS
|
||||||
|
@ -27,6 +27,8 @@ class Entrypoint {
|
||||||
CriticalStop.redirect(error);
|
CriticalStop.redirect(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Connection.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ready(): void {
|
private static ready(): void {
|
||||||
|
|
|
@ -221,15 +221,19 @@ Uint8Array.prototype.toHexString = function(): string {
|
||||||
// ** BIGINT EXTENSIONS ** \\
|
// ** BIGINT EXTENSIONS ** \\
|
||||||
|
|
||||||
interface bigInt {
|
interface bigInt {
|
||||||
toByteArray(): Uint8Array;
|
toByteArray(byteCount: number): Uint8Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
bigInt.prototype.toByteArray = function(): Uint8Array {
|
bigInt.prototype.toByteArray = function(byteCount: number): Uint8Array {
|
||||||
var hexString: string = this.toString(16);
|
var hexString: string = this.toString(16);
|
||||||
var byteCount = Math.ceil(hexString.length / 2);
|
var loopCount = Math.ceil(hexString.length / 2);
|
||||||
var byteArray = new Uint8Array(byteCount);
|
var byteArray = new Uint8Array(byteCount);
|
||||||
|
|
||||||
for(var i = 0; i < byteCount; ++i) {
|
loopCount = Math.min(loopCount, byteCount);
|
||||||
byteArray[i] = parseInt(hexString.substr(Math.max(0, hexString.length - 2*(i+1)), hexString.length - 2*i), 16);
|
for(var i = 0; i < loopCount; ++i) {
|
||||||
|
var byte = hexString.substring(Math.max(0, hexString.length - 2*(i+1)), hexString.length - 2*i);
|
||||||
|
byteArray[i] = parseInt(byte, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return byteArray;
|
||||||
}
|
}
|
|
@ -79,9 +79,9 @@ class Packet {
|
||||||
bodySize += region.byteLength;
|
bodySize += region.byteLength;
|
||||||
|
|
||||||
++headerSize;
|
++headerSize;
|
||||||
if(region.byteLength >= 254 && region.byteLength <= 0xFFFF)
|
if(region.byteLength >= 0xFE && region.byteLength <= 0xFFFF)
|
||||||
headerSize += 2;
|
headerSize += 2;
|
||||||
else
|
else if(region.byteLength > 0xFFFF)
|
||||||
headerSize += 4;
|
headerSize += 4;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
class RenderContext {
|
class Rendering {
|
||||||
|
private static context: WebGLRenderingContext;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,4 +2,16 @@ class CriticalStop {
|
||||||
public static redirect(message: string): void {
|
public static redirect(message: string): void {
|
||||||
window.location.href = "error.html?txt="+ encodeURIComponent(message) +"&rterr";
|
window.location.href = "error.html?txt="+ encodeURIComponent(message) +"&rterr";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Random {
|
||||||
|
public static generatePrime(bitCount: number = 512): bigInt {
|
||||||
|
var lower = new bigInt(2).pow(bitCount - 1);
|
||||||
|
var upper = new bigInt(2).pow(bitCount).prev();
|
||||||
|
var prime = new bigInt(4);
|
||||||
|
while(!prime.isProbablePrime())
|
||||||
|
prime = bigInt.randBetween(lower, upper);
|
||||||
|
|
||||||
|
return prime;
|
||||||
|
}
|
||||||
}
|
}
|
24
client/src/def/BigInt.d.ts
vendored
24
client/src/def/BigInt.d.ts
vendored
|
@ -24,13 +24,13 @@ declare class bigInt {
|
||||||
|
|
||||||
public divide(x: any): bigInt;
|
public divide(x: any): bigInt;
|
||||||
public divmod(x: any): bigInt;
|
public divmod(x: any): bigInt;
|
||||||
public eq(x: any): bigInt;
|
public eq(x: any): boolean;
|
||||||
public equals(x: any): bigInt;
|
public equals(x: any): boolean;
|
||||||
|
|
||||||
public geq(x: any): bigInt;
|
public geq(x: any): boolean;
|
||||||
public greater(x: any): bigInt;
|
public greater(x: any): boolean;
|
||||||
public greaterOrEquals(x: any): bigInt;
|
public greaterOrEquals(x: any): boolean;
|
||||||
public gt(x: any): bigInt;
|
public gt(x: any): boolean;
|
||||||
|
|
||||||
public isDivisibleBy(x: any): boolean;
|
public isDivisibleBy(x: any): boolean;
|
||||||
public isEven(): boolean;
|
public isEven(): boolean;
|
||||||
|
@ -42,10 +42,10 @@ declare class bigInt {
|
||||||
public isUnit(): boolean;
|
public isUnit(): boolean;
|
||||||
public isZero(): boolean;
|
public isZero(): boolean;
|
||||||
|
|
||||||
public leq(x: any): bigInt;
|
public leq(x: any): boolean;
|
||||||
public lesser(x: any): bigInt;
|
public lesser(x: any): boolean;
|
||||||
public lesserOrEquals(x: any): bigInt;
|
public lesserOrEquals(x: any): boolean;
|
||||||
public lt(x: any): bigInt;
|
public lt(x: any): boolean;
|
||||||
|
|
||||||
public minus(x: any): bigInt;
|
public minus(x: any): bigInt;
|
||||||
public mod(x: any): bigInt;
|
public mod(x: any): bigInt;
|
||||||
|
@ -53,10 +53,10 @@ declare class bigInt {
|
||||||
public modPow(exp: any, mod: any): bigInt;
|
public modPow(exp: any, mod: any): bigInt;
|
||||||
public multiply(x: any): bigInt;
|
public multiply(x: any): bigInt;
|
||||||
|
|
||||||
public neq(x: any): bigInt;
|
public neq(x: any): boolean;
|
||||||
public next(): bigInt;
|
public next(): bigInt;
|
||||||
public not(): bigInt;
|
public not(): bigInt;
|
||||||
public notEquals(x: any): bigInt;
|
public notEquals(x: any): boolean;
|
||||||
|
|
||||||
public or(x: any): bigInt;
|
public or(x: any): bigInt;
|
||||||
public over(x: any): bigInt;
|
public over(x: any): bigInt;
|
||||||
|
|
|
@ -7,7 +7,7 @@ using System.Numerics;
|
||||||
using Square;
|
using Square;
|
||||||
|
|
||||||
namespace CircleScape.Encryption {
|
namespace CircleScape.Encryption {
|
||||||
class KeyExchange {
|
class Key {
|
||||||
private BigInteger Secret;
|
private BigInteger Secret;
|
||||||
public BigInteger Generator { get; private set; } = 2;
|
public BigInteger Generator { get; private set; } = 2;
|
||||||
public BigInteger Modulus { get; private set; }
|
public BigInteger Modulus { get; private set; }
|
||||||
|
@ -16,7 +16,7 @@ namespace CircleScape.Encryption {
|
||||||
get => !PrivateKey.IsZero;
|
get => !PrivateKey.IsZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyExchange() {
|
public Key() {
|
||||||
Secret = RNG.NextPrime(512 / 8);
|
Secret = RNG.NextPrime(512 / 8);
|
||||||
Modulus = RNG.NextPrime(512 / 8);
|
Modulus = RNG.NextPrime(512 / 8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Square {
|
||||||
if(offset > 0)
|
if(offset > 0)
|
||||||
arrEnum = arrEnum.Skip(offset);
|
arrEnum = arrEnum.Skip(offset);
|
||||||
if(count > 0 && count < arr.Length)
|
if(count > 0 && count < arr.Length)
|
||||||
arrEnum = arr.Take(count);
|
arrEnum = arrEnum.Take(count);
|
||||||
|
|
||||||
return arrEnum.ToArray();
|
return arrEnum.ToArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,14 @@ namespace CircleScape {
|
||||||
return ErrorPacket;
|
return ErrorPacket;
|
||||||
|
|
||||||
Packet packet = new Packet();
|
Packet packet = new Packet();
|
||||||
if(!Enum.IsDefined(typeof(kId), raw[0]))
|
if(!Enum.IsDefined(typeof(kId), (int)raw[0]))
|
||||||
return ErrorPacket;
|
return ErrorPacket;
|
||||||
packet.Id = (kId)raw[0];
|
packet.Id = (kId)raw[0];
|
||||||
var regionCount = raw[1];
|
var regionCount = raw[1];
|
||||||
var regionLengths = new List<uint>();
|
var regionLengths = new List<uint>();
|
||||||
var headerPtr = 2;
|
var headerPtr = 2;
|
||||||
for(var i = 0; i < regionCount; ++i) {
|
for(var i = 0; i < regionCount; ++i) {
|
||||||
|
regionLengths.Add(0);
|
||||||
var first = raw[headerPtr];
|
var first = raw[headerPtr];
|
||||||
if(first < 254) {
|
if(first < 254) {
|
||||||
regionLengths[i] = first;
|
regionLengths[i] = first;
|
||||||
|
@ -49,7 +50,7 @@ namespace CircleScape {
|
||||||
return ErrorPacket;
|
return ErrorPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(headerPtr + regionLengths.Sum(x => x) < raw.Length)
|
if(headerPtr + regionLengths.Sum(x => x) > raw.Length)
|
||||||
return ErrorPacket;
|
return ErrorPacket;
|
||||||
|
|
||||||
long bodyPtr = headerPtr;
|
long bodyPtr = headerPtr;
|
||||||
|
@ -125,6 +126,9 @@ namespace CircleScape {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator byte[] (Region region) => region.Data;
|
public static implicit operator byte[] (Region region) => region.Data;
|
||||||
|
public string Bytes {
|
||||||
|
get => this;
|
||||||
|
}
|
||||||
|
|
||||||
public static implicit operator string(Region region) {
|
public static implicit operator string(Region region) {
|
||||||
try {
|
try {
|
||||||
|
@ -133,6 +137,9 @@ namespace CircleScape {
|
||||||
return Encoding.ASCII.GetString(region.Data);
|
return Encoding.ASCII.GetString(region.Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public string Str {
|
||||||
|
get => this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,14 @@ using CircleScape.Encryption;
|
||||||
namespace CircleScape {
|
namespace CircleScape {
|
||||||
class PendingConnection : Connection {
|
class PendingConnection : Connection {
|
||||||
private DateTime ConnectionOpened;
|
private DateTime ConnectionOpened;
|
||||||
private KeyExchange Key;
|
private Key Key;
|
||||||
private Cipher Encryptor;
|
private Cipher Encryptor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnOpen() {
|
protected override void OnOpen() {
|
||||||
ConnectionOpened = DateTime.UtcNow;
|
ConnectionOpened = DateTime.UtcNow;
|
||||||
Key = new KeyExchange();
|
Key = new Key();
|
||||||
|
|
||||||
Send(Key.GenerateRequestPacket().GetBytes());
|
Send(Key.GenerateRequestPacket().GetBytes());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue