Initial commit.

This commit is contained in:
libroot 2025-08-06 16:58:36 +00:00
commit 0a9434be1b
18 changed files with 1860 additions and 0 deletions

87
client/README.md Normal file
View file

@ -0,0 +1,87 @@
# NOJSCAP client
The client directory includes NOJSCAP client implementations in multiple languages. Each version takes a challenge string and a difficulty level, then searches for a nonce such that the SHA-256 hash of `challenge + nonce` begins with the required number of leading zero bits.
## Implementations
- **C**: `nojscap.c`
- **Go**: `nojscap.go`
- **Python**: `nojscap.py`
- **JavaScript (Node.js)**: `nojscap.js`
- **Rust**: `nojscap.rs`
Each implementation provides similar usage and functionality.
---
## C Version
### Compilation
You need:
- GCC or any C compiler
- OpenSSL development libraries (`libssl-dev` on Debian-based systems)
```sh
gcc -O2 -o nojscap nojscap.c -lssl -lcrypto
```
### Usage
```sh
./nojscap <challenge_string> <difficulty_bits>
```
- `challenge_string`: Any input string used as the challenge.
- `difficulty_bits`: Integer between 1 and 256. Higher values are more computationally expensive.
### Example
```sh
./nojscap libroot12 26
Attempts: 0
Attempts: 1048576
Attempts: 2097152
Attempts: 3145728
Attempts: 4194304
Attempts: 5242880
Attempts: 6291456
Found nonce: 6368109
Hash: 0000000e724d990815e84e8a53f3f2410875046fe62a050de830d706b853ebe2
```
---
## Python
```sh
python3 nojscap.py <challenge_string> <difficulty_bits>
```
May require the `hashlib` module if using older Python verisons (standard in Python 3).
## Go
```sh
go run nojscap.go <challenge_string> <difficulty_bits>
```
Requires Go 1.13+.
## JavaScript (Node.js)
```sh
node nojscap.js <challenge_string> <difficulty_bits>
```
Uses the built-in `crypto` module.
## Rust
```sh
rustc nojscap.rs -o nojscap_rs
./nojscap_rs <challenge_string> <difficulty_bits>
```
Requires Rust and `sha2` crate if using the `Cargo` version.

71
client/nojscap.c Normal file
View file

@ -0,0 +1,71 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>
int check_difficulty(const unsigned char *hash, int difficulty_bits) {
int bits = difficulty_bits;
int i = 0;
while (bits > 0) {
unsigned char byte = hash[i];
if (bits >= 8) {
if (byte != 0) return 0;
bits -= 8;
} else {
unsigned char mask = 0xFF << (8 - bits);
if ((byte & mask) != 0) return 0;
bits = 0;
}
i++;
}
return 1;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <challenge_string> <difficulty_bits>\n", argv[0]);
return 1;
}
const char *challenge = argv[1];
int difficulty_bits = atoi(argv[2]);
if (difficulty_bits <= 0 || difficulty_bits > 256) {
fprintf(stderr, "Difficulty bits must be between 1 and 256\n");
return 1;
}
unsigned char hash[SHA256_DIGEST_LENGTH];
unsigned long long counter = 0;
size_t challenge_len = strlen(challenge);
char *input = malloc(challenge_len + 32);
if (!input) {
fprintf(stderr, "Memory allocation failed\n");
return 1;
}
while (1) {
sprintf(input, "%s%llu", challenge, counter);
SHA256((unsigned char *)input, strlen(input), hash);
if (check_difficulty(hash, difficulty_bits)) {
printf("===================\n");
printf("Found nonce: %llu\n", counter);
printf("===================\n");
printf("Hash: ");
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
printf("%02x", hash[i]);
printf("\n");
break;
}
if ((counter & 0xFFFFF) == 0) {
printf("Attempts: %llu\n", counter);
}
counter++;
}
free(input);
return 0;
}

66
client/nojscap.go Normal file
View file

@ -0,0 +1,66 @@
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"os"
"strconv"
)
func checkDifficulty(hash []byte, difficultyBits int) bool {
bits := difficultyBits
i := 0
for bits > 0 {
b := hash[i]
if bits >= 8 {
if b != 0 {
return false
}
bits -= 8
} else {
mask := byte(0xFF << (8 - bits))
if (b & mask) != 0 {
return false
}
bits = 0
}
i++
}
return true
}
func main() {
if len(os.Args) != 3 {
fmt.Fprintf(os.Stderr, "Usage: %s <challenge_string> <difficulty_bits>\n", os.Args[0])
os.Exit(1)
}
challenge := os.Args[1]
difficultyBits, err := strconv.Atoi(os.Args[2])
if err != nil || difficultyBits <= 0 || difficultyBits > 256 {
fmt.Fprintln(os.Stderr, "Difficulty bits must be between 1 and 256")
os.Exit(1)
}
var counter uint64 = 0
for {
input := fmt.Sprintf("%s%d", challenge, counter)
hash := sha256.Sum256([]byte(input))
if checkDifficulty(hash[:], difficultyBits) {
fmt.Printf("===================\n")
fmt.Printf("Found nonce: %d\n", counter)
fmt.Printf("===================\n")
fmt.Printf("Hash: %s\n", hex.EncodeToString(hash[:]))
break
}
if counter&0xFFFFF == 0 {
fmt.Printf("Attempts: %d\n", counter)
}
counter++
}
}

57
client/nojscap.js Normal file
View file

@ -0,0 +1,57 @@
const crypto = require('crypto');
function checkDifficulty(hashBuffer, difficultyBits) {
let bits = difficultyBits;
let i = 0;
while (bits > 0) {
const byte = hashBuffer[i];
if (bits >= 8) {
if (byte !== 0) return false;
bits -= 8;
} else {
const mask = 0xFF << (8 - bits);
if ((byte & mask) !== 0) return false;
bits = 0;
}
i++;
}
return true;
}
function main() {
if (process.argv.length !== 4) {
console.error(`Usage: node ${process.argv[1]} <challenge_string> <difficulty_bits>`);
process.exit(1);
}
const challenge = process.argv[2];
const difficultyBits = parseInt(process.argv[3], 10);
if (isNaN(difficultyBits) || difficultyBits <= 0 || difficultyBits > 256) {
console.error('Difficulty bits must be a number between 1 and 256');
process.exit(1);
}
let counter = 0;
while (true) {
const input = challenge + counter;
const hash = crypto.createHash('sha256').update(input).digest();
if (checkDifficulty(hash, difficultyBits)) {
console.log('===================');
console.log(`Found nonce: ${counter}`);
console.log('===================');
console.log(`Hash: ${hash.toString('hex')}`);
break;
}
if ((counter & 0xFFFFF) === 0) {
console.log(`Attempts: ${counter}`);
}
counter++;
}
}
main();

52
client/nojscap.py Normal file
View file

@ -0,0 +1,52 @@
import hashlib
import sys
def check_difficulty(hash_bytes: bytes, difficulty_bits: int) -> bool:
bits = difficulty_bits
i = 0
while bits > 0:
byte = hash_bytes[i]
if bits >= 8:
if byte != 0:
return False
bits -= 8
else:
mask = 0xFF << (8 - bits) & 0xFF
if (byte & mask) != 0:
return False
bits = 0
i += 1
return True
def main():
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <challenge_string> <difficulty_bits>")
sys.exit(1)
challenge = sys.argv[1]
try:
difficulty_bits = int(sys.argv[2])
except ValueError:
print("Difficulty must be a number")
sys.exit(1)
if difficulty_bits <= 0 or difficulty_bits > 256:
print("Difficulty bits must be between 1 and 256")
sys.exit(1)
counter = 0
while True:
input_str = f"{challenge}{counter}"
hash_bytes = hashlib.sha256(input_str.encode()).digest()
if check_difficulty(hash_bytes, difficulty_bits):
print("====================")
print(f"Found nonce: {counter}")
print("====================")
print(f"Hash: {hash_bytes.hex()}")
break
if counter & 0xFFFFF == 0:
print(f"Attempts: {counter}")
counter += 1
if __name__ == "__main__":
main()

65
client/nojscap.rs Normal file
View file

@ -0,0 +1,65 @@
use sha2::{Digest, Sha256};
use std::env;
use std::process;
fn check_difficulty(hash: &[u8], difficulty_bits: u32) -> bool {
let mut bits = difficulty_bits;
let mut i = 0;
while bits > 0 {
let byte = hash[i];
if bits >= 8 {
if byte != 0 {
return false;
}
bits -= 8;
} else {
let mask = 0xFF << (8 - bits);
if (byte & mask) != 0 {
return false;
}
bits = 0;
}
i += 1;
}
true
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 3 {
eprintln!("Usage: {} <challenge_string> <difficulty_bits>", args[0]);
process::exit(1);
}
let challenge = &args[1];
let difficulty_bits: u32 = match args[2].parse() {
Ok(num) if num > 0 && num <= 256 => num,
_ => {
eprintln!("Difficulty bits must be between 1 and 256");
process::exit(1);
}
};
let mut counter: u64 = 0;
loop {
let input = format!("{}{}", challenge, counter);
let hash = Sha256::digest(input.as_bytes());
if check_difficulty(&hash, difficulty_bits) {
println!("===================");
println!("Found nonce: {}", counter);
println!("===================");
println!("Hash: {:x}", hash);
break;
}
if counter & 0xFFFFF == 0 {
println!("Attempts: {}", counter);
}
counter += 1;
}
}