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
|
||||
var canvas = document.getElementById("cs");
|
||||
if(!(canvas.getContext("webgl") || canvas.getContext("experimental-webgl")))
|
||||
support.webgl = false;
|
||||
Rendering.context = canvas.getContext("webgl");
|
||||
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
|
||||
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBransaction;
|
||||
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
|
||||
window.indexedDB = window.indexedDB
|
||||
|| window.mozIndexedDB
|
||||
|| window.webkitIndexedDB
|
||||
|| window.msIndexedDB;
|
||||
window.IDBTransaction = window.IDBTransaction
|
||||
|| window.webkitIDBTransaction
|
||||
|| window.msIDBransaction;
|
||||
window.IDBKeyRange = window.IDBKeyRange
|
||||
|| window.webkitIDBKeyRange
|
||||
|| window.msIDBKeyRange;
|
||||
if(!window.indexedDB)
|
||||
support.idb = false;
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ class Connection {
|
|||
Connection.sock.onclose = Connection.onClose;
|
||||
}
|
||||
|
||||
public static send(msg: Packet) {
|
||||
Connection.sock.send(msg.getBytes());
|
||||
}
|
||||
|
||||
private static onOpen(event: any): void {
|
||||
Connection._isOpen = true;
|
||||
|
||||
|
@ -32,11 +36,12 @@ class Connection {
|
|||
var raw = new Uint8Array(event.data);
|
||||
var msg = Packet.fromBytes(raw);
|
||||
console.log(msg);
|
||||
console.log(msg[1].toString());
|
||||
|
||||
switch(msg.id) {
|
||||
case kPacketId.KeyExchange:
|
||||
|
||||
var response = Key.generateResponsePacket(msg);
|
||||
Connection.send(response);
|
||||
console.log(response);
|
||||
break;
|
||||
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 {
|
||||
Connection.open();
|
||||
Key.init();
|
||||
|
||||
FileCache.initCache(
|
||||
// SUCCESS
|
||||
|
@ -27,6 +27,8 @@ class Entrypoint {
|
|||
CriticalStop.redirect(error);
|
||||
}
|
||||
);
|
||||
|
||||
Connection.open();
|
||||
}
|
||||
|
||||
private static ready(): void {
|
||||
|
|
|
@ -221,15 +221,19 @@ Uint8Array.prototype.toHexString = function(): string {
|
|||
// ** BIGINT EXTENSIONS ** \\
|
||||
|
||||
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 byteCount = Math.ceil(hexString.length / 2);
|
||||
var loopCount = Math.ceil(hexString.length / 2);
|
||||
var byteArray = new Uint8Array(byteCount);
|
||||
|
||||
for(var i = 0; i < byteCount; ++i) {
|
||||
byteArray[i] = parseInt(hexString.substr(Math.max(0, hexString.length - 2*(i+1)), hexString.length - 2*i), 16);
|
||||
loopCount = Math.min(loopCount, byteCount);
|
||||
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;
|
||||
|
||||
++headerSize;
|
||||
if(region.byteLength >= 254 && region.byteLength <= 0xFFFF)
|
||||
if(region.byteLength >= 0xFE && region.byteLength <= 0xFFFF)
|
||||
headerSize += 2;
|
||||
else
|
||||
else if(region.byteLength > 0xFFFF)
|
||||
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 {
|
||||
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 divmod(x: any): bigInt;
|
||||
public eq(x: any): bigInt;
|
||||
public equals(x: any): bigInt;
|
||||
public eq(x: any): boolean;
|
||||
public equals(x: any): boolean;
|
||||
|
||||
public geq(x: any): bigInt;
|
||||
public greater(x: any): bigInt;
|
||||
public greaterOrEquals(x: any): bigInt;
|
||||
public gt(x: any): bigInt;
|
||||
public geq(x: any): boolean;
|
||||
public greater(x: any): boolean;
|
||||
public greaterOrEquals(x: any): boolean;
|
||||
public gt(x: any): boolean;
|
||||
|
||||
public isDivisibleBy(x: any): boolean;
|
||||
public isEven(): boolean;
|
||||
|
@ -42,10 +42,10 @@ declare class bigInt {
|
|||
public isUnit(): boolean;
|
||||
public isZero(): boolean;
|
||||
|
||||
public leq(x: any): bigInt;
|
||||
public lesser(x: any): bigInt;
|
||||
public lesserOrEquals(x: any): bigInt;
|
||||
public lt(x: any): bigInt;
|
||||
public leq(x: any): boolean;
|
||||
public lesser(x: any): boolean;
|
||||
public lesserOrEquals(x: any): boolean;
|
||||
public lt(x: any): boolean;
|
||||
|
||||
public minus(x: any): bigInt;
|
||||
public mod(x: any): bigInt;
|
||||
|
@ -53,10 +53,10 @@ declare class bigInt {
|
|||
public modPow(exp: any, mod: any): bigInt;
|
||||
public multiply(x: any): bigInt;
|
||||
|
||||
public neq(x: any): bigInt;
|
||||
public neq(x: any): boolean;
|
||||
public next(): bigInt;
|
||||
public not(): bigInt;
|
||||
public notEquals(x: any): bigInt;
|
||||
public notEquals(x: any): boolean;
|
||||
|
||||
public or(x: any): bigInt;
|
||||
public over(x: any): bigInt;
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Numerics;
|
|||
using Square;
|
||||
|
||||
namespace CircleScape.Encryption {
|
||||
class KeyExchange {
|
||||
class Key {
|
||||
private BigInteger Secret;
|
||||
public BigInteger Generator { get; private set; } = 2;
|
||||
public BigInteger Modulus { get; private set; }
|
||||
|
@ -16,7 +16,7 @@ namespace CircleScape.Encryption {
|
|||
get => !PrivateKey.IsZero;
|
||||
}
|
||||
|
||||
public KeyExchange() {
|
||||
public Key() {
|
||||
Secret = RNG.NextPrime(512 / 8);
|
||||
Modulus = RNG.NextPrime(512 / 8);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Square {
|
|||
if(offset > 0)
|
||||
arrEnum = arrEnum.Skip(offset);
|
||||
if(count > 0 && count < arr.Length)
|
||||
arrEnum = arr.Take(count);
|
||||
arrEnum = arrEnum.Take(count);
|
||||
|
||||
return arrEnum.ToArray();
|
||||
}
|
||||
|
|
|
@ -22,13 +22,14 @@ namespace CircleScape {
|
|||
return ErrorPacket;
|
||||
|
||||
Packet packet = new Packet();
|
||||
if(!Enum.IsDefined(typeof(kId), raw[0]))
|
||||
if(!Enum.IsDefined(typeof(kId), (int)raw[0]))
|
||||
return ErrorPacket;
|
||||
packet.Id = (kId)raw[0];
|
||||
var regionCount = raw[1];
|
||||
var regionLengths = new List<uint>();
|
||||
var headerPtr = 2;
|
||||
for(var i = 0; i < regionCount; ++i) {
|
||||
regionLengths.Add(0);
|
||||
var first = raw[headerPtr];
|
||||
if(first < 254) {
|
||||
regionLengths[i] = first;
|
||||
|
@ -49,7 +50,7 @@ namespace CircleScape {
|
|||
return ErrorPacket;
|
||||
}
|
||||
|
||||
if(headerPtr + regionLengths.Sum(x => x) < raw.Length)
|
||||
if(headerPtr + regionLengths.Sum(x => x) > raw.Length)
|
||||
return ErrorPacket;
|
||||
|
||||
long bodyPtr = headerPtr;
|
||||
|
@ -125,6 +126,9 @@ namespace CircleScape {
|
|||
}
|
||||
|
||||
public static implicit operator byte[] (Region region) => region.Data;
|
||||
public string Bytes {
|
||||
get => this;
|
||||
}
|
||||
|
||||
public static implicit operator string(Region region) {
|
||||
try {
|
||||
|
@ -133,6 +137,9 @@ namespace CircleScape {
|
|||
return Encoding.ASCII.GetString(region.Data);
|
||||
}
|
||||
}
|
||||
public string Str {
|
||||
get => this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,14 +11,14 @@ using CircleScape.Encryption;
|
|||
namespace CircleScape {
|
||||
class PendingConnection : Connection {
|
||||
private DateTime ConnectionOpened;
|
||||
private KeyExchange Key;
|
||||
private Key Key;
|
||||
private Cipher Encryptor;
|
||||
|
||||
|
||||
|
||||
protected override void OnOpen() {
|
||||
ConnectionOpened = DateTime.UtcNow;
|
||||
Key = new KeyExchange();
|
||||
Key = new Key();
|
||||
|
||||
Send(Key.GenerateRequestPacket().GetBytes());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue