EdDSA initial and untested implementation, test suite refactor, and solving steganography import issues
This commit is contained in:
+2
-1
@@ -2,4 +2,5 @@
|
||||
__pycache__/
|
||||
src/__pycache__/
|
||||
src/cryptography_primitives/__pycache__/
|
||||
tests/__pycache__/
|
||||
tests/__pycache__/
|
||||
wip/
|
||||
|
||||
@@ -0,0 +1,394 @@
|
||||
from cryptography.hazmat.primitives import asymmetric
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
import base64
|
||||
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
|
||||
|
||||
class InitNode:
|
||||
CATEGORY = "Cryptography/Modern/Asymmetric"
|
||||
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super().__init_subclass__(**kwargs)
|
||||
# Auto-set FUNCTION to lowercase class name
|
||||
cls.FUNCTION = cls.__name__.lower()
|
||||
|
||||
|
||||
class EdDSAPrivateKeyFormat(InitNode):
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"key_type": (
|
||||
["Ed25519", "Ed448"],
|
||||
{"default": "Ed25519", "description": "The key type to use for EdDSA-based asymmetric signing algorithms."},
|
||||
),
|
||||
"encoding_format": (
|
||||
["PEM", "DER (Converted)", "OpenSSH", "Raw (Converted)", "X962 (Converted)", "SMIME"],
|
||||
{
|
||||
"default": "PEM",
|
||||
"description": 'Encoding type for the private key. Some formats (ones with "(Converted)" next to them) are binary formats, which cannot be outputted normally in ComfyUI. To better serve the purpose of the node, these formats will be converted to a chosen format below in `conversion_format`.',
|
||||
},
|
||||
),
|
||||
"conversion_format": (
|
||||
["Base64", "Hexadecimal", "UTF-8 String", "Binary"],
|
||||
{
|
||||
"default": "Base64",
|
||||
"description": "The conversion format to be used with the converted encoding format that cannot be outputted raw.",
|
||||
},
|
||||
),
|
||||
"formatting": (
|
||||
["Traditional OpenSSL", "PKCS8", "Raw (Converted)", "OpenSSH (Requires PEM)"],
|
||||
{
|
||||
"default": "OpenSSH (Requires PEM)",
|
||||
"description": "What format to serialize the key in",
|
||||
},
|
||||
),
|
||||
"encryption_algorithm": (["Best Available", "None"], {"default": "Best Available"}),
|
||||
},
|
||||
"optional": {
|
||||
"encryption_password": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "The password to use to encrypt the private key.",
|
||||
},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("private_bytes",)
|
||||
|
||||
def from_private_key_formatting(self, encoding_format, formatting, encryption_algorithm, encryption_password):
|
||||
if encoding_format in ["PEM", "OpenSSH", "SMIME"]:
|
||||
encode = getattr(serialization.Encoding, encoding_format)
|
||||
elif encoding_format == "DER (Converted)":
|
||||
encode = serialization.Encoding.DER
|
||||
elif encoding_format == "Raw (Converted)":
|
||||
encode = serialization.Encoding.Raw
|
||||
elif encoding_format == "X962 (Converted)":
|
||||
encode = serialization.Encoding.X962
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
if formatting == "Traditional OpenSSL":
|
||||
format = serialization.PrivateFormat.TraditionalOpenSSL
|
||||
elif formatting == "PKCS8":
|
||||
format = serialization.PrivateFormat.PKCS8
|
||||
elif formatting == "Raw (Converted)":
|
||||
format = serialization.PrivateFormat.Raw
|
||||
elif formatting == "OpenSSH (Requires PEM)":
|
||||
format = serialization.PrivateFormat.OpenSSH
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
if encryption_algorithm == "Best Available":
|
||||
encryption_algorithm = serialization.BestAvailableEncryption(encryption_password.encode("utf-8"))
|
||||
elif encryption_algorithm == "None":
|
||||
encryption_algorithm = serialization.NoEncryption()
|
||||
else:
|
||||
raise ValueError
|
||||
return (encode, format, encryption_algorithm)
|
||||
|
||||
def eddsaprivatekeyformat(self, key_type, encoding_format, formatting, encryption_algorithm, conversion_format, encryption_password):
|
||||
if key_type == "Ed25519":
|
||||
ed = asymmetric.ed25519.Ed25519PrivateKey
|
||||
elif key_type == "Ed448":
|
||||
ed = asymmetric.ed448.Ed448PrivateKey
|
||||
else:
|
||||
raise ValueError
|
||||
ed_private_key = ed.generate()
|
||||
output = ed_private_key.private_bytes(
|
||||
self.from_private_key_formatting(encoding_format, formatting, encryption_algorithm, encryption_password)
|
||||
)
|
||||
if encoding_format in ["DER (Converted)", "Raw (Converted)", "X962 (Converted)"]:
|
||||
output = output.decode("utf-8")
|
||||
if conversion_format == "Base64":
|
||||
output = base64.b64encode(output).decode("utf-8")
|
||||
elif conversion_format == "Hexadecimal":
|
||||
output = output.hex()
|
||||
elif conversion_format == "UTF-8 String":
|
||||
output = output.decode("utf-8")
|
||||
elif conversion_format == "Binary":
|
||||
output = bytes(int(b, 2) for b in output.split(" ")).decode("utf-8")
|
||||
else:
|
||||
raise ValueError
|
||||
return (output,)
|
||||
|
||||
|
||||
class EdDSASignature(InitNode):
|
||||
CATEGORY = "Cryptography/Modern/Asymmetric"
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"key_source": (
|
||||
"BOOLEAN",
|
||||
{
|
||||
"label_on": "Fresh Key",
|
||||
"label_off": "From Private Bytes",
|
||||
"tooltip": "The source of the private key to be used to sign the message",
|
||||
},
|
||||
),
|
||||
"key_type": (
|
||||
["Ed25519", "Ed448"],
|
||||
{"default": "Ed25519", "description": "The key type to use for EdDSA-based asymmetric signing algorithms."},
|
||||
),
|
||||
"message": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "Hello World!",
|
||||
"multiline": True,
|
||||
"placeholder": "Type your message here...",
|
||||
},
|
||||
),
|
||||
},
|
||||
"optional": {
|
||||
"private_bytes": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Only applicable if key_source is set to From Private Bytes. Uses the format defined below.",
|
||||
},
|
||||
),
|
||||
"byte_format": (["Base64", "Hexadecimal", "String", "Binary"], {}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("signature",)
|
||||
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super().__init_subclass__(**kwargs)
|
||||
# Auto-set FUNCTION to lowercase class name
|
||||
cls.FUNCTION = cls.__name__.lower()
|
||||
|
||||
def EdDSAInit(self, key_source, key_type, private_bytes, byte_format):
|
||||
if key_type == "Ed25519":
|
||||
ed = asymmetric.ed25519.Ed25519PrivateKey
|
||||
elif key_type == "Ed448":
|
||||
ed = asymmetric.ed448.Ed448PrivateKey
|
||||
else:
|
||||
raise ValueError
|
||||
if key_source:
|
||||
ed_private_key = ed.generate()
|
||||
else:
|
||||
if byte_format == "Base64":
|
||||
ed_private_bytes = base64.b64decode(private_bytes).encode("utf-8")
|
||||
elif byte_format == "Hexadecimal":
|
||||
ed_private_bytes = bytes.fromhex(private_bytes)
|
||||
elif byte_format == "String":
|
||||
ed_private_bytes = private_bytes.encode("utf-8")
|
||||
elif byte_format == "Binary":
|
||||
ed_private_bytes = bytes(int(b, 2) for b in private_bytes.split(" "))
|
||||
else:
|
||||
raise ValueError
|
||||
ed_private_key = ed.from_private_bytes(ed_private_bytes)
|
||||
return ed_private_key
|
||||
|
||||
def edssasignature(self, key_source, key_type, message, private_bytes, byte_format):
|
||||
signature = self.EdDSAInit(key_source, key_type, private_bytes, byte_format).sign(message.encode("utf-8"))
|
||||
return (signature.hex(),)
|
||||
|
||||
|
||||
class EdDSAPublicKeyFormat(InitNode):
|
||||
CATEGORY = "Cryptography/Modern/Asymmetric"
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"key_source": (
|
||||
"BOOLEAN",
|
||||
{
|
||||
"label_on": "Fresh Key",
|
||||
"label_off": "From Private Bytes",
|
||||
"tooltip": "The source of the private key to be used to generate the public key.",
|
||||
},
|
||||
),
|
||||
"key_type": (
|
||||
["Ed25519", "Ed448"],
|
||||
{"default": "Ed25519", "description": "The key type to use for EdDSA-based asymmetric signing algorithms."},
|
||||
),
|
||||
"encoding_format": (
|
||||
["PEM", "DER (Converted)", "OpenSSH", "Raw (Converted)", "X962 (Converted)", "SMIME"],
|
||||
{
|
||||
"default": "PEM",
|
||||
"description": 'Encoding type for the private key. Some formats (ones with "(Converted)" next to them) are binary formats, which cannot be outputted normally in ComfyUI. To better serve the purpose of the node, these formats will be converted to a chosen format below in `conversion_format`.',
|
||||
},
|
||||
),
|
||||
"conversion_format": (
|
||||
["Base64", "Hexadecimal", "UTF-8 String", "Binary"],
|
||||
{
|
||||
"default": "Base64",
|
||||
"description": "The conversion format to be used with the converted encoding format that cannot be outputted raw.",
|
||||
},
|
||||
),
|
||||
"formatting": (
|
||||
["SubjectPublicKeyInfo", "PKCS8", "Raw (Converted)", "OpenSSH (Requires PEM)"],
|
||||
{
|
||||
"default": "OpenSSH (Requires PEM)",
|
||||
"description": "What format to serialize the key in",
|
||||
},
|
||||
),
|
||||
},
|
||||
"optional": {
|
||||
"private_bytes": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Only applicable if key_source is set to From Private Bytes. Uses the format defined below.",
|
||||
},
|
||||
),
|
||||
"byte_format": (["Base64", "Hexadecimal", "String", "Binary"], {}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("public_bytes",)
|
||||
|
||||
def from_public_key_formatting(self, encoding_format, formatting):
|
||||
if encoding_format in ["PEM", "OpenSSH", "SMIME"]:
|
||||
encode = getattr(serialization.Encoding, encoding_format)
|
||||
elif encoding_format == "DER (Converted)":
|
||||
encode = serialization.Encoding.DER
|
||||
elif encoding_format == "Raw (Converted)":
|
||||
encode = serialization.Encoding.Raw
|
||||
elif encoding_format == "X962 (Converted)":
|
||||
encode = serialization.Encoding.X962
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
if formatting == "SubjectPublicKeyInfo":
|
||||
format = serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
elif formatting == "PKCS8":
|
||||
format = serialization.PublicFormat.PKCS8
|
||||
elif formatting == "Raw (Converted)":
|
||||
format = serialization.PublicFormat.Raw
|
||||
elif formatting == "OpenSSH (Requires PEM)":
|
||||
format = serialization.PublicFormat.OpenSSH
|
||||
else:
|
||||
raise ValueError
|
||||
return (encode, format)
|
||||
|
||||
def eddsapublickeyformat(self, key_source, key_type, encoding_format, conversion_format, formatting, private_bytes, byte_format):
|
||||
ed_private_key = EdDSASignature.EdDSAInit(key_source, key_type, private_bytes, byte_format)
|
||||
ed_public_key = ed_private_key.public_key()
|
||||
output = ed_public_key.public_bytes(self.from_public_key_formatting(encoding_format, formatting))
|
||||
if encoding_format in ["DER (Converted)", "Raw (Converted)", "X962 (Converted)"]:
|
||||
output = output.decode("utf-8")
|
||||
if conversion_format == "Base64":
|
||||
output = base64.b64encode(output).decode("utf-8")
|
||||
elif conversion_format == "Hexadecimal":
|
||||
output = output.hex()
|
||||
elif conversion_format == "UTF-8 String":
|
||||
output = output.decode("utf-8")
|
||||
elif conversion_format == "Binary":
|
||||
output = bytes(int(b, 2) for b in output.split(" ")).decode("utf-8")
|
||||
else:
|
||||
raise ValueError
|
||||
return (output,)
|
||||
|
||||
|
||||
class EdDSAVerify(InitNode):
|
||||
CATEGORY = "Cryptography/Modern/Asymmetric"
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"key_source": (
|
||||
"BOOLEAN",
|
||||
{
|
||||
"label_on": "Fresh Key",
|
||||
"label_off": "From Public Bytes",
|
||||
"tooltip": "The source of the public key to be used to verify the message",
|
||||
},
|
||||
),
|
||||
"key_type": (
|
||||
["Ed25519", "Ed448"],
|
||||
{"default": "Ed25519", "description": "The key type to use for EdDSA-based asymmetric signing algorithms."},
|
||||
),
|
||||
"message": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "Hello World!",
|
||||
"multiline": True,
|
||||
"placeholder": "Type your message here...",
|
||||
},
|
||||
),
|
||||
"signature": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"placeholder": "Type your signature here... (in hexadecimal)",
|
||||
},
|
||||
),
|
||||
},
|
||||
"optional": {
|
||||
"public_bytes": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Only applicable if key_source is set to From Private Bytes. Uses the format defined below.",
|
||||
},
|
||||
),
|
||||
"byte_format": (["Base64", "Hexadecimal", "String", "Binary"], {}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
RETURN_NAMES = ("verify_status",)
|
||||
|
||||
def eddsaverify(self, key_source, key_type, message, signature, public_bytes, byte_format):
|
||||
if key_type == "Ed25519":
|
||||
ed = asymmetric.ed25519.Ed25519PrivateKey
|
||||
elif key_type == "Ed448":
|
||||
ed = asymmetric.ed448.Ed448PrivateKey
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
if key_source:
|
||||
ed_private_key = ed.generate()
|
||||
ed_public_key = ed_private_key.public_key()
|
||||
|
||||
elif not key_source:
|
||||
if byte_format == "Base64":
|
||||
ed_public_bytes = base64.b64decode(public_bytes).encode("utf-8")
|
||||
elif byte_format == "Hexadecimal":
|
||||
ed_public_bytes = bytes.fromhex(public_bytes)
|
||||
elif byte_format == "String":
|
||||
ed_public_bytes = public_bytes.encode("utf-8")
|
||||
elif byte_format == "Binary":
|
||||
ed_public_bytes = bytes(int(b, 2) for b in public_bytes.split(" "))
|
||||
else:
|
||||
raise ValueError
|
||||
ed_public_key = ed.from_public_bytes(ed_public_bytes)
|
||||
decoded_signature = bytes.fromhex(signature)
|
||||
try:
|
||||
ed_public_key.verify(decoded_signature, message)
|
||||
output = True
|
||||
except InvalidSignature:
|
||||
output = False
|
||||
return (output,)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"EdDSAPrivateKeyFormat": EdDSAPrivateKeyFormat,
|
||||
"EdDSASignature": EdDSASignature,
|
||||
"EdDSAPublicKeyFormat": EdDSAPublicKeyFormat,
|
||||
"EdDSAVerify": EdDSAVerify,
|
||||
}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"EdDSAPrivateKeyFormat": "EdDSA Private Key Bytes",
|
||||
"EdDSASignature": "EdDSA Signature Generator",
|
||||
"EdDSAPublicKeyFormat": "EdDSA Public Key Bytes",
|
||||
"EdDSAVerify": "EDDSA Message Verification",
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import sys
|
||||
import inspect
|
||||
import textwrap
|
||||
|
||||
@@ -8,7 +9,20 @@ import torch
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
|
||||
import folder_paths # This is dealt with by ComfyUI. If this import is throwing an error, ignore it.
|
||||
# folder_path.py solver, just so the complaints will stop.
|
||||
current = os.path.dirname(os.path.realpath(__file__))
|
||||
while True:
|
||||
candidate = os.path.join(current, "folder_paths.py")
|
||||
if os.path.exists(candidate):
|
||||
target_dir = current
|
||||
break
|
||||
parent = os.path.dirname(current)
|
||||
if parent == current:
|
||||
raise FileNotFoundError("folder_paths.py not found in any parent directories")
|
||||
current = parent
|
||||
sys.path.insert(0, target_dir)
|
||||
|
||||
import folder_paths # This import is handled by the solver above looking for it inside the parent directories. This will most likely hit the one from base ComfyUI, assuming no other nodes or .py file carry this namespace.
|
||||
|
||||
# Every node is inspired heavily by their reference implementations in their GitHub repository, with changes made to best use PyTorch as possible as it's the main way ComfyUI stores data
|
||||
# For more information, check https://docs.comfy.org/custom-nodes/backend/images_and_masks#images
|
||||
|
||||
@@ -100,61 +100,34 @@ class ConverterNodes:
|
||||
|
||||
class String2Binary(ConverterNodes):
|
||||
def string2binary(self, text, encoding_format, other_encoding_format):
|
||||
return (
|
||||
" ".join(
|
||||
format(c, "b")
|
||||
for c in bytearray(
|
||||
text, self.encoding_selector(encoding_format, other_encoding_format)
|
||||
)
|
||||
),
|
||||
)
|
||||
return (" ".join(format(c, "b") for c in bytearray(text, self.encoding_selector(encoding_format, other_encoding_format))),)
|
||||
|
||||
|
||||
class Binary2String(ConverterNodes):
|
||||
def binary2string(self, text, encoding_format, other_encoding_format):
|
||||
return (
|
||||
bytes(int(b, 2) for b in text.split(" ")).decode(
|
||||
self.encoding_selector(encoding_format, other_encoding_format)
|
||||
),
|
||||
)
|
||||
return (bytes(int(b, 2) for b in text.split(" ")).decode(self.encoding_selector(encoding_format, other_encoding_format)),)
|
||||
|
||||
|
||||
class String2Hex(ConverterNodes):
|
||||
def string2hex(self, text, encoding_format, other_encoding_format):
|
||||
return (
|
||||
text.encode(
|
||||
self.encoding_selector(encoding_format, other_encoding_format)
|
||||
).hex(),
|
||||
)
|
||||
return (text.encode(self.encoding_selector(encoding_format, other_encoding_format)).hex(),)
|
||||
|
||||
|
||||
class Hex2String(ConverterNodes):
|
||||
def hex2string(self, text, encoding_format, other_encoding_format):
|
||||
return (
|
||||
bytes.fromhex(text.replace("0x", "").replace(" ", "")).decode(
|
||||
self.encoding_selector(encoding_format, other_encoding_format)
|
||||
),
|
||||
bytes.fromhex(text.replace("0x", "").replace(" ", "")).decode(self.encoding_selector(encoding_format, other_encoding_format)),
|
||||
)
|
||||
|
||||
|
||||
class String2Base64(ConverterNodes):
|
||||
def string2base64(self, text, encoding_format, other_encoding_format):
|
||||
return (
|
||||
base64.b64encode(
|
||||
text.encode(
|
||||
self.encoding_selector(encoding_format, other_encoding_format)
|
||||
)
|
||||
).decode("ascii"),
|
||||
)
|
||||
return (base64.b64encode(text.encode(self.encoding_selector(encoding_format, other_encoding_format))).decode("ascii"),)
|
||||
|
||||
|
||||
class Base642String(ConverterNodes):
|
||||
def base642string(self, text, encoding_format, other_encoding_format):
|
||||
return (
|
||||
base64.b64decode(text.encode("ascii")).decode(
|
||||
self.encoding_selector(encoding_format, other_encoding_format)
|
||||
),
|
||||
)
|
||||
return (base64.b64decode(text.encode("ascii")).decode(self.encoding_selector(encoding_format, other_encoding_format)),)
|
||||
|
||||
|
||||
# The Bitwise category of Utilities. Also has auto-detection for the sake of my sanity.
|
||||
@@ -241,17 +214,13 @@ class BitwiseNodes:
|
||||
if len(cleaned) % 8 != 0:
|
||||
# pad to nearest byte
|
||||
cleaned = cleaned.zfill(((len(cleaned) + 7) // 8) * 8)
|
||||
return bytes(
|
||||
int(cleaned[i : i + 8], 2) for i in range(0, len(cleaned), 8)
|
||||
), "Binary"
|
||||
return bytes(int(cleaned[i : i + 8], 2) for i in range(0, len(cleaned), 8)), "Binary"
|
||||
|
||||
# Leading 0 + digits 0/1 → implicit binary
|
||||
elif text.startswith("0") and all(c in "01" for c in text):
|
||||
# pad to nearest byte
|
||||
cleaned = text.zfill(((len(text) + 7) // 8) * 8)
|
||||
return bytes(
|
||||
int(cleaned[i : i + 8], 2) for i in range(0, len(cleaned), 8)
|
||||
), "Binary"
|
||||
return bytes(int(cleaned[i : i + 8], 2) for i in range(0, len(cleaned), 8)), "Binary"
|
||||
|
||||
# Integer detection
|
||||
elif text.isdigit(): # simple positive integer
|
||||
@@ -277,25 +246,17 @@ class BitwiseNodes:
|
||||
|
||||
# Default to chosen formatted string
|
||||
else:
|
||||
return text.encode(
|
||||
self.encoding_selector(encoding_format, other_encoding_format)
|
||||
), "String"
|
||||
return text.encode(self.encoding_selector(encoding_format, other_encoding_format)), "String"
|
||||
|
||||
def operate(
|
||||
self, text_1, text_2, encoding_format, other_encoding_format=None, func=None
|
||||
):
|
||||
def operate(self, text_1, text_2, encoding_format, other_encoding_format=None, func=None):
|
||||
"""
|
||||
func: a callable that takes one or two byte objects and returns bytes
|
||||
Returns: (result_bytes, detected_format_of_input1)
|
||||
"""
|
||||
b1, return_fmt = self.detect_and_parse(
|
||||
text_1, encoding_format, other_encoding_format
|
||||
)
|
||||
b1, return_fmt = self.detect_and_parse(text_1, encoding_format, other_encoding_format)
|
||||
|
||||
if text_2 is not None:
|
||||
b2, _ = self.detect_and_parse(
|
||||
text_2, encoding_format, other_encoding_format
|
||||
)
|
||||
b2, _ = self.detect_and_parse(text_2, encoding_format, other_encoding_format)
|
||||
# Ensure same length for operations that need it
|
||||
if len(b1) != len(b2):
|
||||
raise ValueError("Inputs must be same length for bitwise operations")
|
||||
@@ -305,9 +266,7 @@ class BitwiseNodes:
|
||||
|
||||
return result, return_fmt
|
||||
|
||||
def format_output(
|
||||
self, data, output_format, encoding_format, other_encoding_format=None
|
||||
):
|
||||
def format_output(self, data, output_format, encoding_format, other_encoding_format=None):
|
||||
if output_format == "Binary":
|
||||
return " ".join(format(b, "08b") for b in data)
|
||||
elif output_format == "Hex":
|
||||
@@ -317,9 +276,7 @@ class BitwiseNodes:
|
||||
elif output_format == "Int":
|
||||
return str(int.from_bytes(data, "big"))
|
||||
elif output_format == "String":
|
||||
return data.decode(
|
||||
self.encoding_selector(encoding_format, other_encoding_format)
|
||||
)
|
||||
return data.decode(self.encoding_selector(encoding_format, other_encoding_format))
|
||||
else:
|
||||
raise ValueError(f"Unknown output format {output_format}")
|
||||
|
||||
@@ -333,11 +290,7 @@ class BitwiseAND(BitwiseNodes):
|
||||
other_encoding_format,
|
||||
func=lambda b1, b2: bytes(x & y for x, y in zip(b1, b2)),
|
||||
)
|
||||
return (
|
||||
self.format_output(
|
||||
result_bytes, input_format, encoding_format, other_encoding_format
|
||||
),
|
||||
)
|
||||
return (self.format_output(result_bytes, input_format, encoding_format, other_encoding_format),)
|
||||
|
||||
|
||||
class BitwiseOR(BitwiseNodes):
|
||||
@@ -349,11 +302,7 @@ class BitwiseOR(BitwiseNodes):
|
||||
other_encoding_format,
|
||||
func=lambda b1, b2: bytes(x | y for x, y in zip(b1, b2)),
|
||||
)
|
||||
return (
|
||||
self.format_output(
|
||||
result_bytes, input_format, encoding_format, other_encoding_format
|
||||
),
|
||||
)
|
||||
return (self.format_output(result_bytes, input_format, encoding_format, other_encoding_format),)
|
||||
|
||||
|
||||
class BitwiseNOT(BitwiseNodes):
|
||||
@@ -372,11 +321,7 @@ class BitwiseNOT(BitwiseNodes):
|
||||
other_encoding_format,
|
||||
func=lambda b1: bytes((~x & 0xFF) for x in b1),
|
||||
)
|
||||
return (
|
||||
self.format_output(
|
||||
result_bytes, input_format, encoding_format, other_encoding_format
|
||||
),
|
||||
)
|
||||
return (self.format_output(result_bytes, input_format, encoding_format, other_encoding_format),)
|
||||
|
||||
|
||||
class BitwiseXOR(BitwiseNodes):
|
||||
@@ -388,11 +333,7 @@ class BitwiseXOR(BitwiseNodes):
|
||||
other_encoding_format,
|
||||
func=lambda b1, b2: bytes(x ^ y for x, y in zip(b1, b2)),
|
||||
)
|
||||
return (
|
||||
self.format_output(
|
||||
result_bytes, input_format, encoding_format, other_encoding_format
|
||||
),
|
||||
)
|
||||
return (self.format_output(result_bytes, input_format, encoding_format, other_encoding_format),)
|
||||
|
||||
|
||||
class BitwiseLS(BitwiseNodes):
|
||||
@@ -404,11 +345,7 @@ class BitwiseLS(BitwiseNodes):
|
||||
other_encoding_format,
|
||||
func=lambda b1, b2: bytes(x << y for x, y in zip(b1, b2)),
|
||||
)
|
||||
return (
|
||||
self.format_output(
|
||||
result_bytes, input_format, encoding_format, other_encoding_format
|
||||
),
|
||||
)
|
||||
return (self.format_output(result_bytes, input_format, encoding_format, other_encoding_format),)
|
||||
|
||||
|
||||
class BitwiseRS(BitwiseNodes):
|
||||
@@ -420,11 +357,42 @@ class BitwiseRS(BitwiseNodes):
|
||||
other_encoding_format,
|
||||
func=lambda b1, b2: bytes(x >> y for x, y in zip(b1, b2)),
|
||||
)
|
||||
return (
|
||||
self.format_output(
|
||||
result_bytes, input_format, encoding_format, other_encoding_format
|
||||
),
|
||||
)
|
||||
return (self.format_output(result_bytes, input_format, encoding_format, other_encoding_format),)
|
||||
|
||||
|
||||
class StringLooper:
|
||||
CATEGORY = "Utilities/Padding"
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"text": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "Hello World!",
|
||||
"multiline": True,
|
||||
"placeholder": "Type your message here...",
|
||||
},
|
||||
),
|
||||
"loops": (
|
||||
"INT",
|
||||
{
|
||||
"min": 1,
|
||||
"step": 1,
|
||||
"default": 3,
|
||||
"tooltip": "The number of times to repeat the string given",
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("looped_text",)
|
||||
FUNCTION = "Looper"
|
||||
|
||||
def Looper(self, text=str, loops=int):
|
||||
return (text * (loops + 1),)
|
||||
|
||||
|
||||
# A dictionary that contains all nodes you want to export with their names
|
||||
@@ -443,6 +411,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"BitwiseXOR": BitwiseXOR,
|
||||
"BitwiseLS": BitwiseLS,
|
||||
"BitwiseRS": BitwiseRS,
|
||||
"StringLooper": StringLooper,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
@@ -459,4 +428,5 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"BitwiseXOR": "Bitwise XOR Operator",
|
||||
"BitwiseLS": "Bitwise Left Shift Operator",
|
||||
"BitwiseRS": "Bitwise Right Shift Operator",
|
||||
"StringLooper": "String Append Looper",
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
# This file makes the tests/nodes directory a Python package.
|
||||
@@ -0,0 +1,33 @@
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import auth_encrypt
|
||||
|
||||
# Test suite for auth_encrypt.py
|
||||
class TestAuthEncrypt:
|
||||
def test_chacha20poly1305(self):
|
||||
chacha20poly1305 = auth_encrypt.ChaCha20Poly1305()
|
||||
text = "Hello World"
|
||||
key = "0" * 64
|
||||
nonce = "0" * 24
|
||||
associated_data = ""
|
||||
encrypted_text = chacha20poly1305.cc20(text, key, nonce, associated_data, True)
|
||||
decrypted_text = chacha20poly1305.cc20(encrypted_text[0], key, nonce, associated_data, False)
|
||||
assert decrypted_text[0] == text
|
||||
|
||||
def test_aes_gcm(self):
|
||||
aes_gcm = auth_encrypt.AESAuth()
|
||||
text = "Hello World"
|
||||
key = "0" * 64
|
||||
nonce = "0" * 24
|
||||
associated_data = ""
|
||||
encrypted_text = aes_gcm.aesauth(text, key, nonce, associated_data, True, "AES-GCM", 16)
|
||||
decrypted_text = aes_gcm.aesauth(encrypted_text[0], key, nonce, associated_data, False, "AES-GCM", 16)
|
||||
assert decrypted_text[0] == text
|
||||
|
||||
def test_aes_ccm(self):
|
||||
aes_ccm = auth_encrypt.AESAuth()
|
||||
text = "Hello World"
|
||||
key = "0" * 64
|
||||
nonce = "0" * 24
|
||||
associated_data = ""
|
||||
encrypted_text = aes_ccm.aesauth(text, key, nonce, associated_data, True, "AES-CCM", 16)
|
||||
decrypted_text = aes_ccm.aesauth(encrypted_text[0], key, nonce, associated_data, False, "AES-CCM", 16)
|
||||
assert decrypted_text[0] == text
|
||||
@@ -0,0 +1,142 @@
|
||||
from src.comfyui_arg_toolkit import ciphers
|
||||
|
||||
# Test suite for ciphers.py
|
||||
class TestCiphers:
|
||||
def test_atbash_cipher(self):
|
||||
atbash_cipher = ciphers.Atbash()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
encrypted_text = atbash_cipher.atbash(text, alphabet, True, False)
|
||||
decrypted_text = atbash_cipher.atbash(encrypted_text[0], alphabet, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_caesar_cipher(self):
|
||||
caesar_cipher = ciphers.Caesar()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = 3
|
||||
encrypted_text = caesar_cipher.caesar(text, alphabet, key, True, False)
|
||||
decrypted_text = caesar_cipher.caesar(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_vigenere_cipher(self):
|
||||
vigenere_cipher = ciphers.Vigenere()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "KEY"
|
||||
encrypted_text = vigenere_cipher.vigenere(text, alphabet, key, True, False)
|
||||
decrypted_text = vigenere_cipher.vigenere(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_adfgx_cipher(self):
|
||||
adfgx_cipher = ciphers.ADFGX()
|
||||
text = "HelloWorld"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key = "KEY"
|
||||
encrypted_text = adfgx_cipher.adfgx(text, alphabet, key, True, False)
|
||||
decrypted_text = adfgx_cipher.adfgx(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower()
|
||||
|
||||
def test_autokey_cipher(self):
|
||||
autokey_cipher = ciphers.Autokey()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "KEY"
|
||||
encrypted_text = autokey_cipher.autokey(text, alphabet, key, True, False)
|
||||
decrypted_text = autokey_cipher.autokey(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_beaufort_cipher(self):
|
||||
beaufort_cipher = ciphers.Beaufort()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "KEY"
|
||||
encrypted_text = beaufort_cipher.beaufort(text, alphabet, key, True, False)
|
||||
decrypted_text = beaufort_cipher.beaufort(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_caesarprog_cipher(self):
|
||||
caesarprogessive_cipher = ciphers.CaesarProgressive()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = 3
|
||||
encrypted_text = caesarprogessive_cipher.caesarprogressive(text, alphabet, key, True, False)
|
||||
decrypted_text = caesarprogessive_cipher.caesarprogressive(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_rot13_cipher(self):
|
||||
rot13_cipher = ciphers.Rot13()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
encrypted_text = rot13_cipher.rot13(text, alphabet, 13, True, False)
|
||||
decrypted_text = rot13_cipher.rot13(encrypted_text[0], alphabet, 13, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_scytale_cipher(self):
|
||||
scytale_cipher = ciphers.Scytale()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = 4
|
||||
encrypted_text = scytale_cipher.scytale(text, alphabet, key, True, False)
|
||||
decrypted_text = scytale_cipher.scytale(encrypted_text[0], alphabet, key, False, False)
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_playfair_cipher(self):
|
||||
playfair_cipher = ciphers.Playfair()
|
||||
text = "Hello World"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key = "KEYWORD"
|
||||
encrypted_text = playfair_cipher.playfair(text, alphabet, key, True, False)
|
||||
decrypted_text = playfair_cipher.playfair(encrypted_text[0], alphabet, key, False, False)
|
||||
# secretpy may add padding, so check for inclusion
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_foursquare_cipher(self):
|
||||
foursquare_cipher = ciphers.FourSquare()
|
||||
text = "Hello World"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key_1 = "KEYONE"
|
||||
key_2 = "KEYTWO"
|
||||
encrypted_text = foursquare_cipher.foursquare(text, alphabet, key_1, key_2, True, False)
|
||||
decrypted_text = foursquare_cipher.foursquare(encrypted_text[0], alphabet, key_1, key_2, False, False)
|
||||
# secretpy may add padding, so check for inclusion
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_twosquare_cipher(self):
|
||||
twosquare_cipher = ciphers.TwoSquare()
|
||||
text = "Hello World"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key_1 = "KEYONE"
|
||||
key_2 = "KEYTWO"
|
||||
encrypted_text = twosquare_cipher.twosquare(text, alphabet, key_1, key_2, True, False)
|
||||
decrypted_text = twosquare_cipher.twosquare(encrypted_text[0], alphabet, key_1, key_2, False, False)
|
||||
# secretpy may add padding, so check for inclusion
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_gronsfeld_cipher(self):
|
||||
gronsfeld_cipher = ciphers.Gronsfeld()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "1337"
|
||||
encrypted_text = gronsfeld_cipher.gronsfeld(text, alphabet, key, True, False)
|
||||
decrypted_text = gronsfeld_cipher.gronsfeld(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_trifid_cipher(self):
|
||||
trifid_cipher = ciphers.Trifid()
|
||||
text = "HelloWorld"
|
||||
# Trifid in secretpy uses a 27-char alphabet (letters + separator)
|
||||
alphabet = "abcdefghijklmnopqrstuvwxyz."
|
||||
key = 5 # period
|
||||
encrypted_text = trifid_cipher.trifid(text, alphabet, key, True, False)
|
||||
decrypted_text = trifid_cipher.trifid(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower()
|
||||
|
||||
def test_zigzag_cipher(self):
|
||||
zigzag_cipher = ciphers.Zigzag()
|
||||
text = "Hello World"
|
||||
key = 4 # rails
|
||||
# The node wrapper for Zigzag doesn't use an alphabet, it's a pure transposition
|
||||
encrypted_text = zigzag_cipher.zigzag(text, key, True, False)
|
||||
decrypted_text = zigzag_cipher.zigzag(encrypted_text[0], key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
@@ -0,0 +1,128 @@
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import const_time
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import kdf
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import key_wrapper
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import symm_padding
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import symmetrical_encrypt
|
||||
|
||||
|
||||
class TestConstantTimeCompare:
|
||||
def test_compare_equal(self):
|
||||
compare = const_time.ConstantTimeCompare()
|
||||
a = "deadbeef"
|
||||
b = "deadbeef"
|
||||
result = compare.compare(a, b)
|
||||
assert result[0] is True
|
||||
|
||||
def test_compare_not_equal(self):
|
||||
compare = const_time.ConstantTimeCompare()
|
||||
a = "deadbeef"
|
||||
b = "cafebabe"
|
||||
result = compare.compare(a, b)
|
||||
assert result[0] is False
|
||||
|
||||
|
||||
class TestKeyDerivation:
|
||||
def test_argon2id_derive_verify(self):
|
||||
derive = kdf.Argon2id_Derive()
|
||||
verify = kdf.Argon2id_Verify()
|
||||
|
||||
message = "Hello World"
|
||||
salt = "00" * 16
|
||||
|
||||
derived_key = derive.argon2id_derive(message, 32, salt, 1, 4, 65536, "", "", True)
|
||||
|
||||
verified = verify.argon2id_verify(message, 32, salt, 1, 4, 65536, "", "", True, derived_key[0])
|
||||
|
||||
assert verified[0] is True
|
||||
|
||||
def test_pbkdf2hmac_derive_verify(self):
|
||||
derive = kdf.PBKDF2HMAC_Derive()
|
||||
verify = kdf.PBKDF2HMAC_Verify()
|
||||
|
||||
message = "Hello World"
|
||||
salt = "00" * 16
|
||||
|
||||
derived_key = derive.pbkdf2hmac_derive(message, 32, salt, 1000, "SHA256")
|
||||
|
||||
verified = verify.pbkdf2hmac_verify(message, 32, salt, 1000, "SHA256", derived_key[0])
|
||||
|
||||
assert verified[0] is True
|
||||
|
||||
def test_scrypt_derive_verify(self):
|
||||
derive = kdf.Scrypt_Derive()
|
||||
verify = kdf.Scrypt_Verify()
|
||||
|
||||
message = "Hello World"
|
||||
salt = "00" * 16
|
||||
|
||||
derived_key = derive.scrypt_derive(message, 32, salt, 14, 8, 1)
|
||||
|
||||
verified = verify.scrypt_verify(message, 32, salt, 14, 8, 1, derived_key[0])
|
||||
|
||||
assert verified[0] is True
|
||||
|
||||
|
||||
class TestKeyWrapper:
|
||||
def test_aeskeywrap(self):
|
||||
wrapper = key_wrapper.AESKeyWrap()
|
||||
wrapping_key = "00" * 32
|
||||
key_to_wrap = "11" * 16
|
||||
|
||||
wrapped_key = wrapper.aeskeywrap(wrapping_key, key_to_wrap, True)
|
||||
unwrapped_key = wrapper.aeskeywrap(wrapping_key, wrapped_key[0], False)
|
||||
|
||||
assert unwrapped_key[0] == key_to_wrap
|
||||
|
||||
def test_aeskeywrapwithpadding(self):
|
||||
wrapper = key_wrapper.AESKeyWrapWithPadding()
|
||||
wrapping_key = "00" * 32
|
||||
key_to_wrap = "11" * 20 # Not a multiple of 8
|
||||
|
||||
wrapped_key = wrapper.aeskeywrapwithpadding(wrapping_key, key_to_wrap, True)
|
||||
unwrapped_key = wrapper.aeskeywrapwithpadding(wrapping_key, wrapped_key[0], False)
|
||||
|
||||
assert unwrapped_key[0] == key_to_wrap
|
||||
|
||||
|
||||
class TestSymmetricalPadding:
|
||||
def test_pkcs7_padding(self):
|
||||
padding_node = symm_padding.PaddingNode()
|
||||
data = "Hello World"
|
||||
|
||||
padded_data = padding_node.padding(data, 128, "PKCS7", True)
|
||||
unpadded_data = padding_node.padding(padded_data[0], 128, "PKCS7", False)
|
||||
|
||||
assert unpadded_data[0] == data
|
||||
|
||||
def test_ansix923_padding(self):
|
||||
padding_node = symm_padding.PaddingNode()
|
||||
data = "Hello World"
|
||||
|
||||
padded_data = padding_node.padding(data, 128, "ANSIX923", True)
|
||||
unpadded_data = padding_node.padding(padded_data[0], 128, "ANSIX923", False)
|
||||
|
||||
assert unpadded_data[0] == data
|
||||
|
||||
|
||||
class TestSymmetricalEncryption:
|
||||
def test_aes_cbc_encryption_decryption(self):
|
||||
enc_dec = symmetrical_encrypt.EncryptDecrypt()
|
||||
|
||||
text = "Hello World"
|
||||
key = "00" * 32
|
||||
iv = "11" * 16
|
||||
|
||||
# Pad the text first
|
||||
padding_node = symm_padding.PaddingNode()
|
||||
padded_text = padding_node.padding(text, 128, "PKCS7", True)
|
||||
|
||||
encrypted_text = enc_dec.encryptdecrypt(padded_text[0], key, iv, "", "AES", "CBC", True, 16, "")
|
||||
|
||||
decrypted_text_hex = enc_dec.encryptdecrypt(encrypted_text[0], key, iv, "", "AES", "CBC", False, 16, "")
|
||||
print(f"Type: {type(decrypted_text_hex[0])}")
|
||||
print(f"Value: {repr(decrypted_text_hex[0])}")
|
||||
|
||||
# Unpad the decrypted text
|
||||
unpadded_data = padding_node.padding(decrypted_text_hex[0], 128, "PKCS7", False)
|
||||
|
||||
assert unpadded_data[0] == text
|
||||
@@ -0,0 +1,58 @@
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import hashing
|
||||
|
||||
# Test suite for hashing.py
|
||||
class TestHashing:
|
||||
def test_sha256(self):
|
||||
sha256 = hashing.SHA2()
|
||||
text = "Hello World"
|
||||
hashed_text = (sha256.sha2(key1=text, algorithm="SHA256"),)
|
||||
assert hashed_text[0][0] == "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
|
||||
|
||||
def test_blake2b(self):
|
||||
blake2b = hashing.BLAKE2()
|
||||
text = "Hello World"
|
||||
hashed_text = blake2b.blake2(key1=text, algorithm="BLAKE2b", digest_size=64)
|
||||
assert (
|
||||
hashed_text[0]
|
||||
== "4386a08a265111c9896f56456e2cb61a64239115c4784cf438e36cc851221972da3fb0115f73cd02486254001f878ab1fd126aac69844ef1c1ca152379d0a9bd"
|
||||
)
|
||||
|
||||
def test_sha3_256(self):
|
||||
sha3_256 = hashing.SHA3()
|
||||
text = "Hello World"
|
||||
hashed_text = (sha3_256.sha3(key1=text, algorithm="SHA3_256"),)
|
||||
assert hashed_text[0][0] == "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51"
|
||||
|
||||
def test_sha1(self):
|
||||
sha1 = hashing.SHA1()
|
||||
text = "Hello World"
|
||||
hashed_text = (sha1.sha1(key1=text, algorithm=None),)
|
||||
assert hashed_text[0][0] == "0a4d55a8d778e5022fab701977c5d840bbc486d0"
|
||||
|
||||
def test_md5(self):
|
||||
md5 = hashing.MD5()
|
||||
text = "Hello World"
|
||||
hashed_text = (md5.md5(key1=text, algorithm=None),)
|
||||
assert hashed_text[0][0] == "b10a8db164e0754105b7a99be72e3fe5"
|
||||
|
||||
def test_sm3(self):
|
||||
sm3 = hashing.SM3()
|
||||
text = "Hello World"
|
||||
hashed_text = (sm3.sm3(key1=text, algorithm=None),)
|
||||
assert hashed_text[0][0] == "77015816143ee627f4fa410b6dad2bdb9fcbdf1e061a452a686b8711a484c5d7"
|
||||
|
||||
def test_shake128(self):
|
||||
shake128 = hashing.SHAKE()
|
||||
text = "Hello World"
|
||||
hashed_text = shake128.shake(
|
||||
key1=text,
|
||||
algorithm="SHAKE128",
|
||||
output_length=32,
|
||||
digest_size=64,
|
||||
squeeze_bytes=16,
|
||||
squeeze_times=2,
|
||||
)
|
||||
assert (
|
||||
hashed_text[0][0]
|
||||
== "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef263cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e2"
|
||||
)
|
||||
@@ -0,0 +1,61 @@
|
||||
import unicodedata
|
||||
from src.comfyui_arg_toolkit import morse_code
|
||||
|
||||
# Test suite for morse_code.py
|
||||
class TestMorseCode:
|
||||
def setup_method(self):
|
||||
self.morse_code = morse_code.MorseCode()
|
||||
|
||||
def test_latin_morse_code(self):
|
||||
text = "Hello World"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "latin", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "latin", ".", "-")
|
||||
assert decoded_text[0].lower() == text.lower()
|
||||
|
||||
def test_russian_morse_code(self):
|
||||
text = "Привет мир"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "russian", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "russian", ".", "-")
|
||||
assert decoded_text[0].lower() == text.lower()
|
||||
|
||||
def test_arabic_morse_code(self):
|
||||
text = "مرحبا بالعالم"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "arabic", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "arabic", ".", "-")
|
||||
assert decoded_text[0] == text
|
||||
|
||||
def test_hebrew_morse_code(self):
|
||||
text = "שלום עולם"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "hebrew", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "hebrew", ".", "-")
|
||||
assert decoded_text[0] == "שלומ עולמ"
|
||||
|
||||
def test_greek_morse_code(self):
|
||||
text = "Γειά σου Κόσμε"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "greek", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "greek", ".", "-")
|
||||
assert decoded_text[0] == "ΓΕΙΑ ΣΟΥ ΚΟΣΜΕ"
|
||||
|
||||
def test_korean_morse_code(self):
|
||||
text = "안녕하세요"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "korean", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "korean", ".", "-")
|
||||
assert decoded_text[0] == "ㅇㅏㄴㄴㅕㅇㅎㅏㅅㅔㅇㅛ"
|
||||
|
||||
def test_japanese_wabun_morse_code(self):
|
||||
text = "こんにちは"
|
||||
normalized_text = unicodedata.normalize("NFKC", text)
|
||||
print(f"Normalized text: {normalized_text}")
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "japanese-wabun", ".", "-")
|
||||
print(f"Encoded text: {encoded_text}")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "japanese-wabun", ".", "-")
|
||||
print(f"Decoded text: {decoded_text}")
|
||||
assert decoded_text == ("コンニチハ",)
|
||||
|
||||
def test_custom_dot_dash_morse_code(self):
|
||||
text = "Hello World"
|
||||
dot = "1"
|
||||
dash = "0"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "latin", dot, dash)
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "latin", dot, dash)
|
||||
assert decoded_text[0].lower() == text.lower()
|
||||
@@ -0,0 +1,78 @@
|
||||
from src.comfyui_arg_toolkit import utils
|
||||
|
||||
# Test suite for utils.py
|
||||
class TestUtils:
|
||||
# Converters
|
||||
def test_string_to_binary(self):
|
||||
string_to_binary = utils.String2Binary()
|
||||
text = "Hello World"
|
||||
encoding = "utf-8"
|
||||
binary_text = string_to_binary.string2binary(text, encoding, "")
|
||||
assert binary_text[0] == "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
|
||||
|
||||
def test_binary_to_string(self):
|
||||
binary_to_string = utils.Binary2String()
|
||||
binary_text = "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
|
||||
encoding = "utf-8"
|
||||
text = binary_to_string.binary2string(binary_text, encoding, "")
|
||||
assert text[0] == "Hello World"
|
||||
|
||||
def test_string_to_hex(self):
|
||||
string_to_hex = utils.String2Hex()
|
||||
text = "Hello World"
|
||||
encoding = "utf-8"
|
||||
hex_text = string_to_hex.string2hex(text, encoding, "")
|
||||
assert hex_text[0] == "48656c6c6f20576f726c64"
|
||||
|
||||
def test_hex_to_string(self):
|
||||
hex_to_string = utils.Hex2String()
|
||||
hex_text = "48656c6c6f20576f726c64"
|
||||
encoding = "utf-8"
|
||||
text = hex_to_string.hex2string(hex_text, encoding, "")
|
||||
assert text[0] == "Hello World"
|
||||
|
||||
def test_string_to_base64(self):
|
||||
string_to_base64 = utils.String2Base64()
|
||||
text = "Hello World"
|
||||
encoding = "utf-8"
|
||||
base64_text = string_to_base64.string2base64(text, encoding, "")
|
||||
assert base64_text[0] == "SGVsbG8gV29ybGQ="
|
||||
|
||||
def test_base64_to_string(self):
|
||||
base64_to_string = utils.Base642String()
|
||||
base64_text = "SGVsbG8gV29ybGQ="
|
||||
encoding = "utf-8"
|
||||
text = base64_to_string.base642string(base64_text, encoding, "")
|
||||
assert text[0] == "Hello World"
|
||||
|
||||
# Bitwise Operators
|
||||
def test_bitwise_and(self):
|
||||
bitwise_and = utils.BitwiseAND()
|
||||
text1 = "68656c6c6f"
|
||||
text2 = "776f726c64"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_and.bitwiseand(text1, text2, encoding, "")
|
||||
assert result[0] == "6065606c64"
|
||||
|
||||
def test_bitwise_or(self):
|
||||
bitwise_or = utils.BitwiseOR()
|
||||
text1 = "68656c6c6f"
|
||||
text2 = "776f726c64"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_or.bitwiseor(text1, text2, encoding, "")
|
||||
assert result[0] == "7f6f7e6c6f"
|
||||
|
||||
def test_bitwise_xor(self):
|
||||
bitwise_xor = utils.BitwiseXOR()
|
||||
text1 = "68656c6c6f"
|
||||
text2 = "776f726c64"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_xor.bitwisexor(text1, text2, encoding, "")
|
||||
assert result[0] == "1f0a1e000b"
|
||||
|
||||
def test_bitwise_not(self):
|
||||
bitwise_not = utils.BitwiseNOT()
|
||||
text = "68656c6c6f"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_not.bitwisenot(text, encoding, "")
|
||||
assert result[0] == "979a939390"
|
||||
@@ -1,512 +0,0 @@
|
||||
import unicodedata
|
||||
from src.comfyui_arg_toolkit import ciphers
|
||||
from src.comfyui_arg_toolkit import utils
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import auth_encrypt
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import hashing
|
||||
from src.comfyui_arg_toolkit import morse_code
|
||||
|
||||
# The entire test suite is designed to be as close to what a regular user would input into the nodes. This means that, for the most part, the test suite will not attempt to test for every edge cases, but rather to test for the most common use cases.
|
||||
# For the most part, the test suite will not attempt to test for every edge cases, but rather to test for the most common use cases.
|
||||
|
||||
# For more information on how the test suite is designed, please refer to the README.md file.
|
||||
|
||||
|
||||
# Test suite for ciphers.py
|
||||
class TestCiphers:
|
||||
def test_atbash_cipher(self):
|
||||
atbash_cipher = ciphers.Atbash()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
encrypted_text = atbash_cipher.atbash(text, alphabet, True, False)
|
||||
decrypted_text = atbash_cipher.atbash(encrypted_text[0], alphabet, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_caesar_cipher(self):
|
||||
caesar_cipher = ciphers.Caesar()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = 3
|
||||
encrypted_text = caesar_cipher.caesar(text, alphabet, key, True, False)
|
||||
decrypted_text = caesar_cipher.caesar(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_vigenere_cipher(self):
|
||||
vigenere_cipher = ciphers.Vigenere()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "KEY"
|
||||
encrypted_text = vigenere_cipher.vigenere(text, alphabet, key, True, False)
|
||||
decrypted_text = vigenere_cipher.vigenere(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_adfgx_cipher(self):
|
||||
adfgx_cipher = ciphers.ADFGX()
|
||||
text = "HelloWorld"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key = "KEY"
|
||||
encrypted_text = adfgx_cipher.adfgx(text, alphabet, key, True, False)
|
||||
decrypted_text = adfgx_cipher.adfgx(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower()
|
||||
|
||||
def test_autokey_cipher(self):
|
||||
autokey_cipher = ciphers.Autokey()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "KEY"
|
||||
encrypted_text = autokey_cipher.autokey(text, alphabet, key, True, False)
|
||||
decrypted_text = autokey_cipher.autokey(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_beaufort_cipher(self):
|
||||
beaufort_cipher = ciphers.Beaufort()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "KEY"
|
||||
encrypted_text = beaufort_cipher.beaufort(text, alphabet, key, True, False)
|
||||
decrypted_text = beaufort_cipher.beaufort(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_caesarprog_cipher(self):
|
||||
caesarprogessive_cipher = ciphers.CaesarProgressive()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = 3
|
||||
encrypted_text = caesarprogessive_cipher.caesarprogressive(text, alphabet, key, True, False)
|
||||
decrypted_text = caesarprogessive_cipher.caesarprogressive(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_rot13_cipher(self):
|
||||
rot13_cipher = ciphers.Rot13()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
encrypted_text = rot13_cipher.rot13(text, alphabet, 13, True, False)
|
||||
decrypted_text = rot13_cipher.rot13(encrypted_text[0], alphabet, 13, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_scytale_cipher(self):
|
||||
scytale_cipher = ciphers.Scytale()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = 4
|
||||
encrypted_text = scytale_cipher.scytale(text, alphabet, key, True, False)
|
||||
decrypted_text = scytale_cipher.scytale(encrypted_text[0], alphabet, key, False, False)
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_playfair_cipher(self):
|
||||
playfair_cipher = ciphers.Playfair()
|
||||
text = "Hello World"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key = "KEYWORD"
|
||||
encrypted_text = playfair_cipher.playfair(text, alphabet, key, True, False)
|
||||
decrypted_text = playfair_cipher.playfair(encrypted_text[0], alphabet, key, False, False)
|
||||
# secretpy may add padding, so check for inclusion
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_foursquare_cipher(self):
|
||||
foursquare_cipher = ciphers.FourSquare()
|
||||
text = "Hello World"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key_1 = "KEYONE"
|
||||
key_2 = "KEYTWO"
|
||||
encrypted_text = foursquare_cipher.foursquare(text, alphabet, key_1, key_2, True, False)
|
||||
decrypted_text = foursquare_cipher.foursquare(encrypted_text[0], alphabet, key_1, key_2, False, False)
|
||||
# secretpy may add padding, so check for inclusion
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_twosquare_cipher(self):
|
||||
twosquare_cipher = ciphers.TwoSquare()
|
||||
text = "Hello World"
|
||||
alphabet = "abcdefghiklmnopqrstuvwxyz" # 25 chars, no j
|
||||
key_1 = "KEYONE"
|
||||
key_2 = "KEYTWO"
|
||||
encrypted_text = twosquare_cipher.twosquare(text, alphabet, key_1, key_2, True, False)
|
||||
decrypted_text = twosquare_cipher.twosquare(encrypted_text[0], alphabet, key_1, key_2, False, False)
|
||||
# secretpy may add padding, so check for inclusion
|
||||
assert text.lower().replace(" ", "") in decrypted_text[0]
|
||||
|
||||
def test_gronsfeld_cipher(self):
|
||||
gronsfeld_cipher = ciphers.Gronsfeld()
|
||||
text = "Hello World"
|
||||
alphabet = "ENGLISH"
|
||||
key = "1337"
|
||||
encrypted_text = gronsfeld_cipher.gronsfeld(text, alphabet, key, True, False)
|
||||
decrypted_text = gronsfeld_cipher.gronsfeld(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
def test_trifid_cipher(self):
|
||||
trifid_cipher = ciphers.Trifid()
|
||||
text = "HelloWorld"
|
||||
# Trifid in secretpy uses a 27-char alphabet (letters + separator)
|
||||
alphabet = "abcdefghijklmnopqrstuvwxyz."
|
||||
key = 5 # period
|
||||
encrypted_text = trifid_cipher.trifid(text, alphabet, key, True, False)
|
||||
decrypted_text = trifid_cipher.trifid(encrypted_text[0], alphabet, key, False, False)
|
||||
assert decrypted_text[0] == text.lower()
|
||||
|
||||
def test_zigzag_cipher(self):
|
||||
zigzag_cipher = ciphers.Zigzag()
|
||||
text = "Hello World"
|
||||
key = 4 # rails
|
||||
# The node wrapper for Zigzag doesn't use an alphabet, it's a pure transposition
|
||||
encrypted_text = zigzag_cipher.zigzag(text, key, True, False)
|
||||
decrypted_text = zigzag_cipher.zigzag(encrypted_text[0], key, False, False)
|
||||
assert decrypted_text[0] == text.lower().replace(" ", "")
|
||||
|
||||
|
||||
# Test suite for utils.py
|
||||
class TestUtils:
|
||||
# Converters
|
||||
def test_string_to_binary(self):
|
||||
string_to_binary = utils.String2Binary()
|
||||
text = "Hello World"
|
||||
encoding = "utf-8"
|
||||
binary_text = string_to_binary.string2binary(text, encoding, "")
|
||||
assert binary_text[0] == "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
|
||||
|
||||
def test_binary_to_string(self):
|
||||
binary_to_string = utils.Binary2String()
|
||||
binary_text = "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
|
||||
encoding = "utf-8"
|
||||
text = binary_to_string.binary2string(binary_text, encoding, "")
|
||||
assert text[0] == "Hello World"
|
||||
|
||||
def test_string_to_hex(self):
|
||||
string_to_hex = utils.String2Hex()
|
||||
text = "Hello World"
|
||||
encoding = "utf-8"
|
||||
hex_text = string_to_hex.string2hex(text, encoding, "")
|
||||
assert hex_text[0] == "48656c6c6f20576f726c64"
|
||||
|
||||
def test_hex_to_string(self):
|
||||
hex_to_string = utils.Hex2String()
|
||||
hex_text = "48656c6c6f20576f726c64"
|
||||
encoding = "utf-8"
|
||||
text = hex_to_string.hex2string(hex_text, encoding, "")
|
||||
assert text[0] == "Hello World"
|
||||
|
||||
def test_string_to_base64(self):
|
||||
string_to_base64 = utils.String2Base64()
|
||||
text = "Hello World"
|
||||
encoding = "utf-8"
|
||||
base64_text = string_to_base64.string2base64(text, encoding, "")
|
||||
assert base64_text[0] == "SGVsbG8gV29ybGQ="
|
||||
|
||||
def test_base64_to_string(self):
|
||||
base64_to_string = utils.Base642String()
|
||||
base64_text = "SGVsbG8gV29ybGQ="
|
||||
encoding = "utf-8"
|
||||
text = base64_to_string.base642string(base64_text, encoding, "")
|
||||
assert text[0] == "Hello World"
|
||||
|
||||
# Bitwise Operators
|
||||
def test_bitwise_and(self):
|
||||
bitwise_and = utils.BitwiseAND()
|
||||
text1 = "68656c6c6f"
|
||||
text2 = "776f726c64"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_and.bitwiseand(text1, text2, encoding, "")
|
||||
assert result[0] == "6065606c64"
|
||||
|
||||
def test_bitwise_or(self):
|
||||
bitwise_or = utils.BitwiseOR()
|
||||
text1 = "68656c6c6f"
|
||||
text2 = "776f726c64"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_or.bitwiseor(text1, text2, encoding, "")
|
||||
assert result[0] == "7f6f7e6c6f"
|
||||
|
||||
def test_bitwise_xor(self):
|
||||
bitwise_xor = utils.BitwiseXOR()
|
||||
text1 = "68656c6c6f"
|
||||
text2 = "776f726c64"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_xor.bitwisexor(text1, text2, encoding, "")
|
||||
assert result[0] == "1f0a1e000b"
|
||||
|
||||
def test_bitwise_not(self):
|
||||
bitwise_not = utils.BitwiseNOT()
|
||||
text = "68656c6c6f"
|
||||
encoding = "utf-8"
|
||||
result = bitwise_not.bitwisenot(text, encoding, "")
|
||||
assert result[0] == "979a939390"
|
||||
|
||||
|
||||
# Test suite for auth_encrypt.py
|
||||
class TestAuthEncrypt:
|
||||
def test_chacha20poly1305(self):
|
||||
chacha20poly1305 = auth_encrypt.ChaCha20Poly1305()
|
||||
text = "Hello World"
|
||||
key = "0" * 64
|
||||
nonce = "0" * 24
|
||||
associated_data = ""
|
||||
encrypted_text = chacha20poly1305.cc20(text, key, nonce, associated_data, True)
|
||||
decrypted_text = chacha20poly1305.cc20(encrypted_text[0], key, nonce, associated_data, False)
|
||||
assert decrypted_text[0] == text
|
||||
|
||||
def test_aes_gcm(self):
|
||||
aes_gcm = auth_encrypt.AESAuth()
|
||||
text = "Hello World"
|
||||
key = "0" * 64
|
||||
nonce = "0" * 24
|
||||
associated_data = ""
|
||||
encrypted_text = aes_gcm.aesauth(text, key, nonce, associated_data, True, "AES-GCM", 16)
|
||||
decrypted_text = aes_gcm.aesauth(encrypted_text[0], key, nonce, associated_data, False, "AES-GCM", 16)
|
||||
assert decrypted_text[0] == text
|
||||
|
||||
def test_aes_ccm(self):
|
||||
aes_ccm = auth_encrypt.AESAuth()
|
||||
text = "Hello World"
|
||||
key = "0" * 64
|
||||
nonce = "0" * 24
|
||||
associated_data = ""
|
||||
encrypted_text = aes_ccm.aesauth(text, key, nonce, associated_data, True, "AES-CCM", 16)
|
||||
decrypted_text = aes_ccm.aesauth(encrypted_text[0], key, nonce, associated_data, False, "AES-CCM", 16)
|
||||
assert decrypted_text[0] == text
|
||||
|
||||
|
||||
# Test suite for hashing.py
|
||||
class TestHashing:
|
||||
def test_sha256(self):
|
||||
sha256 = hashing.SHA2()
|
||||
text = "Hello World"
|
||||
hashed_text = (sha256.sha2(key1=text, algorithm="SHA256"),)
|
||||
assert hashed_text[0][0] == "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
|
||||
|
||||
def test_blake2b(self):
|
||||
blake2b = hashing.BLAKE2()
|
||||
text = "Hello World"
|
||||
hashed_text = blake2b.blake2(key1=text, algorithm="BLAKE2b", digest_size=64)
|
||||
assert (
|
||||
hashed_text[0]
|
||||
== "4386a08a265111c9896f56456e2cb61a64239115c4784cf438e36cc851221972da3fb0115f73cd02486254001f878ab1fd126aac69844ef1c1ca152379d0a9bd"
|
||||
)
|
||||
|
||||
def test_sha3_256(self):
|
||||
sha3_256 = hashing.SHA3()
|
||||
text = "Hello World"
|
||||
hashed_text = (sha3_256.sha3(key1=text, algorithm="SHA3_256"),)
|
||||
assert hashed_text[0][0] == "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51"
|
||||
|
||||
def test_sha1(self):
|
||||
sha1 = hashing.SHA1()
|
||||
text = "Hello World"
|
||||
hashed_text = (sha1.sha1(key1=text, algorithm=None),)
|
||||
assert hashed_text[0][0] == "0a4d55a8d778e5022fab701977c5d840bbc486d0"
|
||||
|
||||
def test_md5(self):
|
||||
md5 = hashing.MD5()
|
||||
text = "Hello World"
|
||||
hashed_text = (md5.md5(key1=text, algorithm=None),)
|
||||
assert hashed_text[0][0] == "b10a8db164e0754105b7a99be72e3fe5"
|
||||
|
||||
def test_sm3(self):
|
||||
sm3 = hashing.SM3()
|
||||
text = "Hello World"
|
||||
hashed_text = (sm3.sm3(key1=text, algorithm=None),)
|
||||
assert hashed_text[0][0] == "77015816143ee627f4fa410b6dad2bdb9fcbdf1e061a452a686b8711a484c5d7"
|
||||
|
||||
def test_shake128(self):
|
||||
shake128 = hashing.SHAKE()
|
||||
text = "Hello World"
|
||||
hashed_text = shake128.shake(
|
||||
key1=text,
|
||||
algorithm="SHAKE128",
|
||||
output_length=32,
|
||||
digest_size=64,
|
||||
squeeze_bytes=16,
|
||||
squeeze_times=2,
|
||||
)
|
||||
assert (
|
||||
hashed_text[0][0]
|
||||
== "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef263cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e2"
|
||||
)
|
||||
|
||||
|
||||
# Test suite for morse_code.py
|
||||
class TestMorseCode:
|
||||
def setup_method(self):
|
||||
self.morse_code = morse_code.MorseCode()
|
||||
|
||||
def test_latin_morse_code(self):
|
||||
text = "Hello World"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "latin", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "latin", ".", "-")
|
||||
assert decoded_text[0].lower() == text.lower()
|
||||
|
||||
def test_russian_morse_code(self):
|
||||
text = "Привет мир"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "russian", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "russian", ".", "-")
|
||||
assert decoded_text[0].lower() == text.lower()
|
||||
|
||||
def test_arabic_morse_code(self):
|
||||
text = "مرحبا بالعالم"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "arabic", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "arabic", ".", "-")
|
||||
assert decoded_text[0] == text
|
||||
|
||||
def test_hebrew_morse_code(self):
|
||||
text = "שלום עולם"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "hebrew", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "hebrew", ".", "-")
|
||||
assert decoded_text[0] == "שלומ עולמ"
|
||||
|
||||
def test_greek_morse_code(self):
|
||||
text = "Γειά σου Κόσμε"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "greek", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "greek", ".", "-")
|
||||
assert decoded_text[0] == "ΓΕΙΑ ΣΟΥ ΚΟΣΜΕ"
|
||||
|
||||
def test_korean_morse_code(self):
|
||||
text = "안녕하세요"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "korean", ".", "-")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "korean", ".", "-")
|
||||
assert decoded_text[0] == "ㅇㅏㄴㄴㅕㅇㅎㅏㅅㅔㅇㅛ"
|
||||
|
||||
def test_japanese_wabun_morse_code(self):
|
||||
text = "こんにちは"
|
||||
normalized_text = unicodedata.normalize("NFKC", text)
|
||||
print(f"Normalized text: {normalized_text}")
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "japanese-wabun", ".", "-")
|
||||
print(f"Encoded text: {encoded_text}")
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "japanese-wabun", ".", "-")
|
||||
print(f"Decoded text: {decoded_text}")
|
||||
assert decoded_text == ("コンニチハ",)
|
||||
|
||||
def test_custom_dot_dash_morse_code(self):
|
||||
text = "Hello World"
|
||||
dot = "1"
|
||||
dash = "0"
|
||||
encoded_text = self.morse_code.MorseCode(text, True, "latin", dot, dash)
|
||||
decoded_text = self.morse_code.MorseCode(encoded_text[0], False, "latin", dot, dash)
|
||||
assert decoded_text[0].lower() == text.lower()
|
||||
|
||||
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import const_time
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import kdf
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import key_wrapper
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import symm_padding
|
||||
from src.comfyui_arg_toolkit.cryptography_primitives import symmetrical_encrypt
|
||||
|
||||
|
||||
class TestConstantTimeCompare:
|
||||
def test_compare_equal(self):
|
||||
compare = const_time.ConstantTimeCompare()
|
||||
a = "deadbeef"
|
||||
b = "deadbeef"
|
||||
result = compare.compare(a, b)
|
||||
assert result[0] is True
|
||||
|
||||
def test_compare_not_equal(self):
|
||||
compare = const_time.ConstantTimeCompare()
|
||||
a = "deadbeef"
|
||||
b = "cafebabe"
|
||||
result = compare.compare(a, b)
|
||||
assert result[0] is False
|
||||
|
||||
|
||||
class TestKeyDerivation:
|
||||
def test_argon2id_derive_verify(self):
|
||||
derive = kdf.Argon2id_Derive()
|
||||
verify = kdf.Argon2id_Verify()
|
||||
|
||||
message = "Hello World"
|
||||
salt = "00" * 16
|
||||
|
||||
derived_key = derive.argon2id_derive(message, 32, salt, 1, 4, 65536, "", "", True)
|
||||
|
||||
verified = verify.argon2id_verify(message, 32, salt, 1, 4, 65536, "", "", True, derived_key[0])
|
||||
|
||||
assert verified[0] is True
|
||||
|
||||
def test_pbkdf2hmac_derive_verify(self):
|
||||
derive = kdf.PBKDF2HMAC_Derive()
|
||||
verify = kdf.PBKDF2HMAC_Verify()
|
||||
|
||||
message = "Hello World"
|
||||
salt = "00" * 16
|
||||
|
||||
derived_key = derive.pbkdf2hmac_derive(message, 32, salt, 1000, "SHA256")
|
||||
|
||||
verified = verify.pbkdf2hmac_verify(message, 32, salt, 1000, "SHA256", derived_key[0])
|
||||
|
||||
assert verified[0] is True
|
||||
|
||||
def test_scrypt_derive_verify(self):
|
||||
derive = kdf.Scrypt_Derive()
|
||||
verify = kdf.Scrypt_Verify()
|
||||
|
||||
message = "Hello World"
|
||||
salt = "00" * 16
|
||||
|
||||
derived_key = derive.scrypt_derive(message, 32, salt, 14, 8, 1)
|
||||
|
||||
verified = verify.scrypt_verify(message, 32, salt, 14, 8, 1, derived_key[0])
|
||||
|
||||
assert verified[0] is True
|
||||
|
||||
|
||||
class TestKeyWrapper:
|
||||
def test_aeskeywrap(self):
|
||||
wrapper = key_wrapper.AESKeyWrap()
|
||||
wrapping_key = "00" * 32
|
||||
key_to_wrap = "11" * 16
|
||||
|
||||
wrapped_key = wrapper.aeskeywrap(wrapping_key, key_to_wrap, True)
|
||||
unwrapped_key = wrapper.aeskeywrap(wrapping_key, wrapped_key[0], False)
|
||||
|
||||
assert unwrapped_key[0] == key_to_wrap
|
||||
|
||||
def test_aeskeywrapwithpadding(self):
|
||||
wrapper = key_wrapper.AESKeyWrapWithPadding()
|
||||
wrapping_key = "00" * 32
|
||||
key_to_wrap = "11" * 20 # Not a multiple of 8
|
||||
|
||||
wrapped_key = wrapper.aeskeywrapwithpadding(wrapping_key, key_to_wrap, True)
|
||||
unwrapped_key = wrapper.aeskeywrapwithpadding(wrapping_key, wrapped_key[0], False)
|
||||
|
||||
assert unwrapped_key[0] == key_to_wrap
|
||||
|
||||
|
||||
class TestSymmetricalPadding:
|
||||
def test_pkcs7_padding(self):
|
||||
padding_node = symm_padding.PaddingNode()
|
||||
data = "Hello World"
|
||||
|
||||
padded_data = padding_node.padding(data, 128, "PKCS7", True)
|
||||
unpadded_data = padding_node.padding(padded_data[0], 128, "PKCS7", False)
|
||||
|
||||
assert unpadded_data[0] == data
|
||||
|
||||
def test_ansix923_padding(self):
|
||||
padding_node = symm_padding.PaddingNode()
|
||||
data = "Hello World"
|
||||
|
||||
padded_data = padding_node.padding(data, 128, "ANSIX923", True)
|
||||
unpadded_data = padding_node.padding(padded_data[0], 128, "ANSIX923", False)
|
||||
|
||||
assert unpadded_data[0] == data
|
||||
|
||||
|
||||
class TestSymmetricalEncryption:
|
||||
def test_aes_cbc_encryption_decryption(self):
|
||||
enc_dec = symmetrical_encrypt.EncryptDecrypt()
|
||||
|
||||
text = "Hello World"
|
||||
key = "00" * 32
|
||||
iv = "11" * 16
|
||||
|
||||
# Pad the text first
|
||||
padding_node = symm_padding.PaddingNode()
|
||||
padded_text = padding_node.padding(text, 128, "PKCS7", True)
|
||||
|
||||
encrypted_text = enc_dec.encryptdecrypt(padded_text[0], key, iv, "", "AES", "CBC", True, 16, "")
|
||||
|
||||
decrypted_text_hex = enc_dec.encryptdecrypt(encrypted_text[0], key, iv, "", "AES", "CBC", False, 16, "")
|
||||
print(f"Type: {type(decrypted_text_hex[0])}")
|
||||
print(f"Value: {repr(decrypted_text_hex[0])}")
|
||||
|
||||
# Unpad the decrypted text
|
||||
unpadded_data = padding_node.padding(decrypted_text_hex[0], 128, "PKCS7", False)
|
||||
|
||||
assert unpadded_data[0] == text
|
||||
Reference in New Issue
Block a user