-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Develop .seigr protocol: SeedDotSeigr and seigr_identity integration …
…for secure lineage tracking - Introduce protocol-aligned serialization format for .seigr files - Integrate seigr_identity for senary-encoded unique IDs - Expand SeedDotSeigr to support initial file creation and lineage tracking - Update seigr_constants with 53,194 KB segment size target - Develop replication, integrity, and rollback modules; functionality in progress
- Loading branch information
Showing
26 changed files
with
813 additions
and
718 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,125 +1,22 @@ | ||
import sys | ||
# app.py | ||
from flask import Flask | ||
from routes import identity_routes, ping_routes, cluster_routes, monitor_routes | ||
from config import Config | ||
import os | ||
from flask import Flask, render_template, request, redirect, url_for, flash, send_file | ||
import uuid | ||
import logging | ||
|
||
# Set up centralized logging to a file | ||
LOG_FILE_PATH = os.path.join("logs", "dot_seigr.log") | ||
os.makedirs("logs", exist_ok=True) # Ensure the logs directory exists | ||
|
||
logging.basicConfig( | ||
filename=LOG_FILE_PATH, | ||
level=logging.DEBUG, # Set to DEBUG to capture all levels of log messages | ||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", | ||
filemode="a" # Append to log file | ||
) | ||
|
||
# Optionally set up logging to console for critical issues | ||
console_handler = logging.StreamHandler() | ||
console_handler.setLevel(logging.ERROR) # Only show critical errors in console | ||
formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s") | ||
console_handler.setFormatter(formatter) | ||
logging.getLogger().addHandler(console_handler) | ||
|
||
# Set up logger | ||
logger = logging.getLogger(__name__) | ||
|
||
# Ensure the src directory is in the path | ||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src')) | ||
|
||
from dot_seigr.seigr_encoder import SeigrEncoder | ||
from dot_seigr.seigr_decoder import SeigrDecoder | ||
|
||
app = Flask( | ||
__name__, | ||
template_folder="src/templates", | ||
static_folder="src/static" | ||
) | ||
app.secret_key = "supersecretkey" | ||
|
||
# Configurations for uploads and file storage | ||
app.config["UPLOAD_FOLDER"] = "uploads" | ||
app.config["ENCODED_FOLDER"] = "encoded_files" | ||
app.config["DECODED_FOLDER"] = "decoded_files" | ||
os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) | ||
os.makedirs(app.config["ENCODED_FOLDER"], exist_ok=True) | ||
os.makedirs(app.config["DECODED_FOLDER"], exist_ok=True) | ||
|
||
# Home route | ||
@app.route("/") | ||
def home(): | ||
return render_template("home.html") | ||
|
||
# Encoding route | ||
@app.route("/encode", methods=["GET", "POST"]) | ||
def encode(): | ||
if request.method == "POST": | ||
uploaded_file = request.files.get("file") | ||
if uploaded_file: | ||
logger.info("File upload detected. Starting encoding process.") | ||
file_id = str(uuid.uuid4()) | ||
file_path = os.path.join(app.config["UPLOAD_FOLDER"], f"{str(file_id)}_{uploaded_file.filename}") | ||
uploaded_file.save(file_path) | ||
|
||
try: | ||
# Read and encode the file | ||
with open(file_path, "rb") as f: | ||
data = f.read() | ||
encoder = SeigrEncoder( | ||
data=data, | ||
creator_id=file_id, | ||
base_dir=app.config["ENCODED_FOLDER"], | ||
original_filename=uploaded_file.filename | ||
) | ||
encoder.encode() | ||
flash("File successfully encoded.", "success") | ||
logger.info("Encoding process completed successfully.") | ||
except Exception as e: | ||
flash(f"Encoding failed: {e}", "error") | ||
logger.error(f"Encoding process failed: {e}") | ||
return redirect(url_for("home")) | ||
else: | ||
flash("No file detected for encoding.", "error") | ||
logger.error("No file detected for encoding.") | ||
return redirect(url_for("encode")) | ||
|
||
# If request is GET, render the encode template | ||
return render_template("encode.html") | ||
|
||
# Decoding route | ||
@app.route("/decode", methods=["GET", "POST"]) | ||
def decode(): | ||
if request.method == "POST": | ||
seed_files = request.files.getlist("seed_files") | ||
if seed_files: | ||
seed_file_paths = [] | ||
for file in seed_files: | ||
file_path = os.path.join(app.config["ENCODED_FOLDER"], file.filename) | ||
file.save(file_path) | ||
seed_file_paths.append(file.filename) # Pass filenames, not paths | ||
|
||
try: | ||
# Initialize decoder and perform decoding | ||
decoder = SeigrDecoder( | ||
cluster_files=seed_file_paths, | ||
base_dir=app.config["ENCODED_FOLDER"] | ||
) | ||
decoded_file_path = decoder.decode() | ||
import sys | ||
|
||
if decoded_file_path: | ||
flash("File successfully decoded.", "success") | ||
return send_file(decoded_file_path, as_attachment=True) | ||
else: | ||
flash("Decoding failed: no data was decoded.", "error") | ||
return redirect(url_for("decode")) | ||
# Ensure `src` is added to the system path | ||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))) | ||
|
||
except Exception as e: | ||
flash(f"Decoding failed: {e}", "error") | ||
logger.error(f"Decoding process failed: {e}") | ||
return redirect(url_for("decode")) | ||
# Initialize Flask app | ||
app = Flask(__name__) | ||
app.config.from_object(Config) | ||
|
||
return render_template("decode.html") | ||
# Register blueprints from each modular route | ||
app.register_blueprint(identity_routes.bp) | ||
app.register_blueprint(ping_routes.bp) | ||
app.register_blueprint(cluster_routes.bp) | ||
app.register_blueprint(monitor_routes.bp) | ||
|
||
if __name__ == "__main__": | ||
if __name__ == '__main__': | ||
app.run(debug=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# config.py | ||
import os | ||
|
||
class Config: | ||
SECRET_KEY = os.environ.get("SECRET_KEY", "your_secret_key") | ||
SEIGR_DIRECTORY = os.path.expanduser("~/.seigr") | ||
SEIGR_ID_PATH = os.path.join(SEIGR_DIRECTORY, "seigr_id.json") | ||
LOG_DIRECTORY = os.path.join(SEIGR_DIRECTORY, "logs") | ||
PING_LOG_PATH = os.path.join(SEIGR_DIRECTORY, "ping_logs.json") | ||
CLUSTER_DIRECTORY = os.path.join(SEIGR_DIRECTORY, "seed_clusters") | ||
UPLOAD_FOLDER = os.path.join(SEIGR_DIRECTORY, "uploads") | ||
os.makedirs(SEIGR_DIRECTORY, exist_ok=True) | ||
os.makedirs(LOG_DIRECTORY, exist_ok=True) | ||
os.makedirs(CLUSTER_DIRECTORY, exist_ok=True) | ||
os.makedirs(UPLOAD_FOLDER, exist_ok=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# routes/cluster_routes.py | ||
from flask import Blueprint, jsonify, request | ||
from src.dot_seigr.dot_seigr import DotSeigr | ||
from src.dot_seigr.seed_dot_seigr import SeedDotSeigr | ||
from config import Config | ||
import os | ||
|
||
bp = Blueprint('cluster_routes', __name__) | ||
|
||
@bp.route('/create_seed_cluster', methods=['POST']) | ||
def create_seed_cluster(): | ||
"""Creates a root cluster using SeedDotSeigr and saves metadata.""" | ||
initial_hash = "root_hash" # Placeholder root hash | ||
seed = SeedDotSeigr(initial_hash) | ||
seed_path = seed.save_to_disk(Config.CLUSTER_DIRECTORY) | ||
return jsonify({"status": "seed_cluster_created", "path": seed_path}) | ||
|
||
@bp.route('/encode_data', methods=['POST']) | ||
def encode_data(): | ||
"""Encodes data and stores it as .seigr files in clusters.""" | ||
data = request.data # Assumes binary data sent via POST | ||
creator_id = "user_creator_id" # Placeholder creator ID | ||
base_dir = Config.CLUSTER_DIRECTORY | ||
dot_seigr = DotSeigr(data, creator_id, base_dir, original_filename="uploaded_data") | ||
|
||
# Process segmentation and encoding | ||
seed = SeedDotSeigr("root_hash") | ||
updated_seed = dot_seigr.create_segmented_seigr_files(base_dir, seed) | ||
return jsonify({"status": "data_encoded", "seed_path": updated_seed}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# routes/identity_routes.py | ||
from flask import Blueprint, jsonify, request | ||
from src.identity.seigr_identity import SeigrIdentity | ||
from config import Config | ||
import os | ||
import json | ||
import logging | ||
|
||
bp = Blueprint('identity_routes', __name__) | ||
logger = logging.getLogger(__name__) | ||
|
||
@bp.route('/create_seigr_id', methods=['POST']) | ||
def create_seigr_id(): | ||
"""Generates a new Seigr ID and saves it securely in the user's local .seigr directory.""" | ||
try: | ||
data = request.get_json() | ||
password = data.get("password") | ||
|
||
if not password: | ||
return jsonify({"error": "Password is required to create Seigr ID"}), 400 | ||
|
||
seigr_identity = SeigrIdentity() | ||
seigr_id = seigr_identity.generate_seigr_id() | ||
seigr_identity.set_encryption_key(password=password) | ||
|
||
# Define the path to save the Seigr ID | ||
if not os.path.exists(Config.SEIGR_ID_DIRECTORY): | ||
os.makedirs(Config.SEIGR_ID_DIRECTORY) | ||
seigr_id_path = os.path.join(Config.SEIGR_ID_DIRECTORY, "seigr_id.json") | ||
|
||
seigr_identity.save_to_external(seigr_id_path) | ||
|
||
logger.info("Seigr ID created and saved successfully.") | ||
return jsonify({"status": "success", "seigr_id": seigr_id}) | ||
except Exception as e: | ||
logger.error(f"Failed to create Seigr ID: {e}") | ||
return jsonify({"error": "Failed to create Seigr ID"}), 500 | ||
|
||
@bp.route('/get_seigr_id', methods=['POST']) | ||
def get_seigr_id(): | ||
"""Retrieves and decrypts the Seigr ID from the local storage if available.""" | ||
try: | ||
data = request.get_json() | ||
password = data.get("password") | ||
|
||
if not password: | ||
return jsonify({"error": "Password is required to retrieve Seigr ID"}), 400 | ||
|
||
seigr_identity = SeigrIdentity() | ||
seigr_id_path = os.path.join(Config.SEIGR_ID_DIRECTORY, "seigr_id.json") | ||
|
||
if os.path.exists(seigr_id_path): | ||
if seigr_identity.load_from_external(seigr_id_path, password=password): | ||
return jsonify({"status": "success", "seigr_id": seigr_identity.senary_id}) | ||
else: | ||
return jsonify({"error": "Failed to decrypt Seigr ID. Check your password."}), 403 | ||
else: | ||
return jsonify({"error": "Seigr ID not found"}), 404 | ||
except Exception as e: | ||
logger.error(f"Failed to retrieve Seigr ID: {e}") | ||
return jsonify({"error": "Failed to retrieve Seigr ID"}), 500 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# routes/monitor_routes.py | ||
from flask import Blueprint, jsonify | ||
import os | ||
import json | ||
from config import Config | ||
|
||
bp = Blueprint('monitor_routes', __name__) | ||
|
||
@bp.route('/get_activity_log', methods=['GET']) | ||
def get_activity_log(): | ||
"""Returns the ping activity log for the Seigr ID.""" | ||
if not os.path.exists(Config.PING_LOG_PATH): | ||
return jsonify({"error": "No activity log found"}), 404 | ||
|
||
with open(Config.PING_LOG_PATH, 'r') as f: | ||
logs = [json.loads(line) for line in f.readlines()] | ||
|
||
return jsonify({"activity_log": logs}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# routes/ping_routes.py | ||
from flask import Blueprint, jsonify | ||
from datetime import datetime | ||
import json | ||
from config import Config | ||
|
||
bp = Blueprint('ping_routes', __name__) | ||
|
||
@bp.route('/ping', methods=['POST']) | ||
def ping(): | ||
"""Records a network ping for the Seigr ID, logging the timestamp.""" | ||
timestamp = datetime.now().isoformat() | ||
ping_entry = {"timestamp": timestamp} | ||
|
||
# Append the new ping to the log file | ||
with open(Config.PING_LOG_PATH, 'a') as f: | ||
f.write(json.dumps(ping_entry) + "\n") | ||
|
||
return jsonify({"status": "pinged", "timestamp": timestamp}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# src/crypto/encoding_utils.py | ||
import logging | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
def encode_to_senary(binary_data: bytes) -> str: | ||
"""Encodes binary data to a senary-encoded string.""" | ||
senary_str = "" | ||
previous_value = 1 # Presumably used as an integer seed for transformations | ||
|
||
for i, byte in enumerate(binary_data): | ||
transformed_byte = _substitution_permutation(byte + previous_value, i) | ||
previous_value = transformed_byte | ||
base6_encoded = _base6_encode(transformed_byte) | ||
logger.debug(f"base6_encoded (should be str): {base6_encoded}, type: {type(base6_encoded)}") | ||
senary_str += base6_encoded # _base6_encode should return a string | ||
|
||
logger.debug("Encoded data to senary format.") | ||
return senary_str | ||
|
||
def decode_from_senary(senary_str: str) -> bytes: | ||
"""Decodes a senary (base-6) encoded string back to binary data.""" | ||
binary_data = bytearray() | ||
previous_value = 1 | ||
for i in range(0, len(senary_str), 2): | ||
byte = _base6_decode(senary_str[i:i + 2]) | ||
reversed_byte = _reverse_substitution_permutation(byte, previous_value, i // 2) | ||
binary_data.append(reversed_byte) | ||
previous_value = byte | ||
logger.debug("Decoded senary data to binary format.") | ||
return bytes(binary_data) | ||
|
||
# Helper functions | ||
def _substitution_permutation(value: int, position: int) -> int: | ||
substituted = (value ^ (position * 17 + 23)) & 0xFF | ||
rotated = ((substituted << 3) & 0xFF) | (substituted >> 5) | ||
return rotated | ||
|
||
def _reverse_substitution_permutation(value: int, prev_val: int, position: int) -> int: | ||
rotated = ((value >> 3) & 0x1F) | ((value & 0x1F) << 5) | ||
substituted = (rotated ^ (position * 17 + 23)) & 0xFF | ||
return (substituted - prev_val) & 0xFF | ||
|
||
def _base6_encode(byte: int) -> str: | ||
senary = [str((byte // 6**i) % 6) for i in range((byte.bit_length() + 1) // 3 + 1)] | ||
return ''.join(reversed(senary)).zfill(2) | ||
|
||
def _base6_decode(senary_str: str) -> int: | ||
byte = 0 | ||
for char in senary_str: | ||
byte = byte * 6 + int(char) | ||
return byte |
Oops, something went wrong.