Initial ChronoSeal release
This commit is contained in:
commit
a66debdece
48 files changed
+2362
No files matched your search
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "antibot-wasm"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
shared = { path = "../shared" }
|
||||
wasm-bindgen = "0.2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
ed25519-dalek = { version = "2", features = ["rand_core"] }
|
||||
rand = "0.8" # <-- add this
|
||||
blake3 = "1"
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
hex = "0.4"
|
||||
base64 = "0.22"
|
||||
serde-wasm-bindgen = "0.6"
|
||||
@@ -0,0 +1,2 @@
|
||||
// Example: break debugger detection, console clearing, etc.
|
||||
// Currently empty.
|
||||
@@ -0,0 +1,47 @@
|
||||
use ed25519_dalek::{SigningKey, Signer};
|
||||
use std::cell::RefCell;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
thread_local! {
|
||||
static KEYPAIR: RefCell<Option<SigningKey>> = RefCell::new(None);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn generate_keypair() -> String {
|
||||
let mut rng = rand::thread_rng();
|
||||
let sk = SigningKey::generate(&mut rng);
|
||||
let pk = sk.verifying_key();
|
||||
let hex_pub = hex::encode(pk.as_bytes());
|
||||
KEYPAIR.with(|kp| *kp.borrow_mut() = Some(sk));
|
||||
hex_pub
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_public_key() -> String {
|
||||
KEYPAIR.with(|kp| hex::encode(kp.borrow().as_ref().unwrap().verifying_key().as_bytes()))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn sign_message(message_json: &str) -> String {
|
||||
KEYPAIR.with(|kp| {
|
||||
let sk = kp.borrow();
|
||||
let sig = sk.as_ref().unwrap().sign(message_json.as_bytes());
|
||||
hex::encode(sig.to_bytes())
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn compute_next_hash(
|
||||
prev_hash_hex: &str,
|
||||
timestamp: u64,
|
||||
entropy_data_json: &str,
|
||||
stack_state_json: &str,
|
||||
salt_hex: &str,
|
||||
) -> String {
|
||||
let prev = hex::decode(prev_hash_hex).unwrap();
|
||||
let salt = hex::decode(salt_hex).unwrap();
|
||||
let entropy = serde_json::from_str::<shared::protocol::EntropyData>(entropy_data_json).unwrap();
|
||||
let stack = serde_json::from_str::<shared::protocol::StackState>(stack_state_json).unwrap();
|
||||
let new = shared::hashing::next_chain_hash(&prev, timestamp, &entropy, &stack, &salt);
|
||||
hex::encode(&new)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// This module is handled on the JS side; WASM only receives the prepared entropy data.
|
||||
// Could be used to add extra entropy sources (e.g., from JS via import).
|
||||
@@ -0,0 +1 @@
|
||||
// Fingerprint collection is done in JS, this module is a placeholder.
|
||||
@@ -0,0 +1,6 @@
|
||||
pub mod anti_debug;
|
||||
pub mod crypto;
|
||||
pub mod entropy;
|
||||
pub mod fingerprint;
|
||||
pub mod transport;
|
||||
pub mod vm;
|
||||
@@ -0,0 +1 @@
|
||||
// Could contain WebTransport related code if needed later.
|
||||
@@ -0,0 +1,55 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
use shared::protocol::StackState;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn run_program(program_b64: &str) -> JsValue {
|
||||
use base64::Engine;
|
||||
let bytes = base64::engine::general_purpose::STANDARD.decode(program_b64).unwrap();
|
||||
let state = execute(&bytes);
|
||||
serde_wasm_bindgen::to_value(&state).unwrap()
|
||||
}
|
||||
|
||||
fn execute(program: &[u8]) -> StackState {
|
||||
let mut stack: Vec<u32> = Vec::new();
|
||||
let mut ip: usize = 0;
|
||||
while ip < program.len() {
|
||||
let op = program[ip];
|
||||
ip += 1;
|
||||
match op {
|
||||
0x00 => {
|
||||
if ip + 4 > program.len() { break; }
|
||||
let val = u32::from_le_bytes([program[ip], program[ip+1], program[ip+2], program[ip+3]]);
|
||||
ip += 4;
|
||||
stack.push(val);
|
||||
}
|
||||
0x01..=0x07 => {
|
||||
if stack.len() < 2 { break; }
|
||||
let b = stack.pop().unwrap();
|
||||
let a = stack.pop().unwrap();
|
||||
let r = match op {
|
||||
0x01 => a.wrapping_add(b),
|
||||
0x02 => a.wrapping_sub(b),
|
||||
0x03 => a.wrapping_mul(b),
|
||||
0x04 => a ^ b,
|
||||
0x05 => a & b,
|
||||
0x06 => a | b,
|
||||
0x07 => a.rotate_left(b % 32),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
stack.push(r);
|
||||
}
|
||||
0x08 => {
|
||||
if stack.is_empty() { break; }
|
||||
let a = stack.pop().unwrap();
|
||||
stack.push(!a);
|
||||
}
|
||||
0x09 => {
|
||||
let r = shared::hashing::hash_stack(&stack);
|
||||
stack.clear();
|
||||
stack.push(r);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
StackState { stack, ip: ip as u16 }
|
||||
}
|
||||
Reference in new issue
Block a user