Untitled

 avatar
unknown
plain_text
a year ago
3.9 kB
21
No Index
import random
import base58
import tkinter as tk
from tkinter import filedialog
from Crypto.Cipher import ChaCha20_Poly1305
from Crypto.Random import get_random_bytes
from music21 import stream, note, meter, metadata

# Predefined 256-bit key (64 hex characters)
KEY_HEX = "1234567812345678123456781234567812345678123456781234567812345678"

# Convert HEX key to bytes
key = bytes.fromhex(KEY_HEX)

# Mapping of Base58 characters to MIDI notes (30 to 87)
def base58_to_midi(base58_str):
    midi_notes = []
    base58_chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    
    for char in base58_str:
        index = base58_chars.index(char)
        midi_note = 30 + index  # Starting MIDI note 30
        midi_notes.append(midi_note)
    
    return midi_notes

# Encrypt the input text using ChaCha20-Poly1305 and convert it to Base58
def encrypt_and_convert_to_midi(input_text):
    # Generate random nonce (96 bits, 12 bytes)
    nonce = get_random_bytes(12)

    # Create ChaCha20-Poly1305 cipher
    cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)

    # Encrypt the input text and get the ciphertext
    ciphertext, tag = cipher.encrypt_and_digest(input_text.encode())

    # Combine ciphertext and tag, then encode in Base58
    encrypted_base58 = base58.b58encode(ciphertext + tag).decode('utf-8')

    # Convert Base58 string to MIDI notes
    midi_notes = base58_to_midi(encrypted_base58)

    return midi_notes, nonce.hex()

# Generate the MusicXML file with the encrypted music
def generate_music_xml(midi_notes, nonce_hex):
    # Create a music21 stream (Grand Staff)
    score = stream.Score()
    
    # Add metadata (title is the nonce)
    score.metadata = metadata.Metadata()
    score.metadata.title = nonce_hex

    # Create two staves for the Grand Staff
    part_upper = stream.Part()
    part_lower = stream.Part()

    # Set the time signature to 5/4 for both staves
    time_sig = meter.TimeSignature('5/4')
    part_upper.append(time_sig)
    part_lower.append(time_sig)

    # Assign notes and rhythms to the upper staff (fixed 16th notes)
    for midi_note in midi_notes:
        n = note.Note()
        n.pitch.midi = midi_note
        n.quarterLength = 0.25  # Fixed sixteenth note
        part_upper.append(n)

    # Add both parts to the score
    score.insert(0, part_upper)
    score.insert(0, part_lower)

    # Save the score to a MusicXML file
    file_path = filedialog.asksaveasfilename(defaultextension=".xml", filetypes=[("MusicXML files", "*.xml")])
    if file_path:
        score.write('musicxml', fp=file_path)

def on_encrypt_click():
    input_text = input_text_box.get("1.0", tk.END).strip()

    if input_text:
        # Encrypt the text and get MIDI notes and nonce
        midi_notes, nonce_hex = encrypt_and_convert_to_midi(input_text)

        # Generate the MusicXML file
        generate_music_xml(midi_notes, nonce_hex)

        output_text_box.delete("1.0", tk.END)
        output_text_box.insert(tk.END, f"MusicXML file saved with title nonce: {nonce_hex}")
    else:
        output_text_box.delete("1.0", tk.END)
        output_text_box.insert(tk.END, "Please enter some text to encrypt.")

# Create the main window
window = tk.Tk()
window.title("ChaCha20-Poly1305 Encryption to MusicXML (16th Notes)")

# Create input text box for plain text
input_label = tk.Label(window, text="Input Text:")
input_label.pack()
input_text_box = tk.Text(window, width=50, height=10)
input_text_box.pack()

# Create Encrypt button
encrypt_button = tk.Button(window, text="Encrypt and Generate MusicXML", command=on_encrypt_click)
encrypt_button.pack()

# Create output text box for result or confirmation
output_label = tk.Label(window, text="Output:")
output_label.pack()
output_text_box = tk.Text(window, width=50, height=5)
output_text_box.pack()

# Start the Tkinter event loop
window.mainloop()
Editor is loading...