Skip to main content

Recent Posts

DH GROUP FINAL

Jun 26, 2025AustinLeath

0 likes • 2 views

def parse_ike_proposal(proposal):
"""
Parse an IKE or ESP proposal string to extract encryption, hash, and DH group in human-readable format.
Args:
proposal (str): IKE or ESP proposal string, e.g., 'IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024'
or 'IKE:AES_GCM_16_256/PRF_HMAC_SHA2_256/ECP_384' or 'ESP:AES_CBC_256/HMAC_SHA1_96/NO_EXT_SEQ'
Returns:
dict: Dictionary with encryption, hash, and DH group in human-readable format
"""
dh_mapping = {
# Standard MODP groups from RFC 2409 and RFC 3526
'MODP_768': '1', # 768-bit MODP group
'MODP_1024': '2', # 1024-bit MODP group
'MODP_1536': '5', # 1536-bit MODP group
'MODP_2048': '14', # 2048-bit MODP group
'MODP_3072': '15', # 3072-bit MODP group
'MODP_4096': '16', # 4096-bit MODP group
'MODP_6144': '17', # 6144-bit MODP group
'MODP_8192': '18', # 8192-bit MODP group
# Elliptic Curve groups from RFC 5114 and RFC 5903
'ECP_256': '19', # 256-bit ECP group
'ECP_384': '20', # 384-bit ECP group
'ECP_521': '21', # 521-bit ECP group
'ECP_192': '25', # 192-bit ECP group
'ECP_224': '26', # 224-bit ECP group
# MODP groups with subgroup sizes from RFC 5114
'MODP_1024_160': '22', # 1024-bit MODP with 160-bit subgroup
'MODP_2048_224': '23', # 2048-bit MODP with 224-bit subgroup
'MODP_2048_256': '24', # 2048-bit MODP with 256-bit subgroup
# Additional groups from RFC 7919 (FFDHE - Finite Field Diffie-Hellman Ephemeral)
'FFDHE_2048': '256', # 2048-bit FFDHE group
'FFDHE_3072': '257', # 3072-bit FFDHE group
'FFDHE_4096': '258', # 4096-bit FFDHE group
'FFDHE_6144': '259', # 6144-bit FFDHE group
'FFDHE_8192': '260', # 8192-bit FFDHE group
# Brainpool curves from RFC 6954
'BRAINPOOL_P256R1': '28', # 256-bit Brainpool curve
'BRAINPOOL_P384R1': '29', # 384-bit Brainpool curve
'BRAINPOOL_P512R1': '30', # 512-bit Brainpool curve
# Modern elliptic curve groups from RFC 8031
'CURVE25519': '31', # 256-bit elliptic curve (Curve25519, 128-bit security)
'CURVE448': '32', # 448-bit elliptic curve (Curve448, 224-bit security)
}
enc_mapping = {
# AES in CBC mode (RFC 3602, commonly used in IPsec and TLS)
'AES_CBC_128': 'AES-128', # 128-bit key, CBC mode
'AES_CBC_192': 'AES-192', # 192-bit key, CBC mode
'AES_CBC_256': 'AES-256', # 256-bit key, CBC mode
# AES in GCM mode (RFC 4106, authenticated encryption for IPsec/TLS)
'AES_GCM_16_128': 'AES-GCM-128', # 128-bit key, GCM mode, 16-byte ICV
'AES_GCM_16_192': 'AES-GCM-192', # 192-bit key, GCM mode, 16-byte ICV
'AES_GCM_16_256': 'AES-GCM-256', # 256-bit key, GCM mode, 16-byte ICV
'AES_GCM_8_128': 'AES-GCM-128-8', # 128-bit key, GCM mode, 8-byte ICV
'AES_GCM_8_256': 'AES-GCM-256-8', # 256-bit key, GCM mode, 8-byte ICV
'AES_GCM_12_128': 'AES-GCM-128-12', # 128-bit key, GCM mode, 12-byte ICV
'AES_GCM_12_256': 'AES-GCM-256-12', # 256-bit key, GCM mode, 12-byte ICV
# AES in CCM mode (RFC 4309, used in IPsec and some wireless protocols)
'AES_CCM_16_128': 'AES-CCM-128', # 128-bit key, CCM mode, 16-byte ICV
'AES_CCM_16_256': 'AES-CCM-256', # 256-bit key, CCM mode, 16-byte ICV
# AES in CTR mode (RFC 3686, used in some VPNs and SSH)
'AES_CTR_128': 'AES-CTR-128', # 128-bit key, CTR mode
'AES_CTR_192': 'AES-CTR-192', # 192-bit key, CTR mode
'AES_CTR_256': 'AES-CTR-256', # 256-bit key, CTR mode
# Legacy and alternative algorithms
'3DES_CBC': '3DES', # Triple DES, CBC mode (RFC 2451, deprecated)
'DES_CBC': 'DES', # Single DES, CBC mode (RFC 2405, obsolete)
'CAMELLIA_CBC_128': 'CAMELLIA-128', # 128-bit Camellia, CBC mode (RFC 5529)
'CAMELLIA_CBC_256': 'CAMELLIA-256', # 256-bit Camellia, CBC mode (RFC 5529)
'CHACHA20_POLY1305': 'CHACHA20-POLY1305', # ChaCha20 with Poly1305 (RFC 8032, used in TLS 1.3, OpenVPN)
'BLOWFISH_CBC': 'BLOWFISH', # Blowfish, CBC mode (non-standard, used in some OpenSSH/OpenVPN)
'CAST5_CBC': 'CAST5', # CAST-128, CBC mode (non-standard, used in some OpenVPN)
# Null encryption (for testing or integrity-only scenarios, RFC 2410)
'NULL': 'NULL' # No encryption, only integrity protection
}
hash_mapping = {
# Legacy hash algorithms (RFC 2403, RFC 2404, deprecated in modern systems)
'HMAC_MD5': 'MD5', # MD5 HMAC, 128-bit output (insecure, legacy use in IPsec/SSH)
'HMAC_MD5_96': 'MD5-96', # MD5 HMAC, truncated to 96 bits (IPsec)
'HMAC_SHA1': 'SHA1', # SHA1 HMAC, 160-bit output (legacy, used in IPsec/TLS)
'HMAC_SHA1_96': 'SHA1-96', # SHA1 HMAC, truncated to 96 bits (IPsec)
# SHA2-based HMAC algorithms (RFC 4868, used in IPsec, TLS, SSH)
'HMAC_SHA2_256': 'SHA2-256', # SHA2-256 HMAC, full 256-bit output
'HMAC_SHA2_256_128': 'SHA2-256-128', # SHA2-256 HMAC, truncated to 128 bits
'HMAC_SHA2_384': 'SHA2-384', # SHA2-384 HMAC, full 384-bit output
'HMAC_SHA2_384_192': 'SHA2-384-192', # SHA2-384 HMAC, truncated to 192 bits
'HMAC_SHA2_512': 'SHA2-512', # SHA2-512 HMAC, full 512-bit output
'HMAC_SHA2_512_256': 'SHA2-512-256', # SHA2-512 HMAC, truncated to 256 bits
# SHA3-based HMAC algorithms (RFC 8009, emerging in modern protocols)
'HMAC_SHA3_224': 'SHA3-224', # SHA3-224 HMAC, 224-bit output
'HMAC_SHA3_256': 'SHA3-256', # SHA3-256 HMAC, 256-bit output
'HMAC_SHA3_384': 'SHA3-384', # SHA3-384 HMAC, 384-bit output
'HMAC_SHA3_512': 'SHA3-512', # SHA3-512 HMAC, 512-bit output
# Authenticated encryption integrity (used with AES-GCM/CCM, RFC 4106, RFC 4309)
'AES_GMAC_128': 'GMAC-128', # AES-GMAC with 128-bit key
'AES_GMAC_192': 'GMAC-192', # AES-GMAC with 192-bit key
'AES_GMAC_256': 'GMAC-256', # AES-GMAC with 256-bit key
# Poly1305 (RFC 8032, used with ChaCha20 in TLS 1.3, OpenVPN)
'POLY1305': 'POLY1305', # Poly1305 authenticator, 128-bit output
# Null authentication (RFC 2410, for testing or encryption-only scenarios)
'NONE': 'NULL' # No integrity protection
}
# Split the proposal into components
components = proposal.split('/')
# Initialize result dictionary
result = {
'encryption': 'Unknown',
'hash': 'None', # Default to 'None' for AEAD ciphers like AES-GCM
'dh_group': 'None' # Default to 'None' for ESP or proposals without DH
}
# Extract components based on expected length
if len(components) == 4: # Standard IKE format: IKE:ENC/HASH/PRF/DH
result['encryption'] = enc_mapping.get(components[0].replace('IKE:', ''), 'Unknown')
result['hash'] = hash_mapping.get(components[1], 'Unknown')
result['dh_group'] = dh_mapping.get(components[3], 'None')
elif len(components) == 3: # AEAD IKE format: IKE:ENC/PRF/DH or ESP:ENC/HASH/EXT
result['encryption'] = enc_mapping.get(components[0].replace('IKE:', '').replace('ESP:', ''), 'Unknown')
if components[0].startswith('IKE:') and components[1].startswith('PRF_'): # AEAD IKE (e.g., AES-GCM)
result['hash'] = 'None'
result['dh_group'] = dh_mapping.get(components[2], 'None')
else: # ESP format (e.g., ESP:AES_CBC_256/HMAC_SHA1_96/NO_EXT_SEQ)
result['hash'] = hash_mapping.get(components[1], 'Unknown')
result['dh_group'] = 'None' # ESP proposals typically lack DH groups
return result
def process_proposals(proposal_list):
"""
Process a list of IKE or ESP proposals, grouping by encryption and hash, and listing all DH groups.
Args:
proposal_list (str): Comma-separated string of IKE or ESP proposals
Returns:
dict: Dictionary mapping (encryption, hash) tuples to lists of DH groups
"""
proposals = proposal_list.split(', ')
grouped_proposals = {}
for proposal in proposals:
parsed = parse_ike_proposal(proposal.strip())
key = (parsed['encryption'], parsed['hash'])
dh_group = parsed['dh_group']
if key not in grouped_proposals:
grouped_proposals[key] = []
if dh_group != 'None' and dh_group not in grouped_proposals[key]:
grouped_proposals[key].append(dh_group)
# Sort DH groups for consistency (numerically by group number)
for key in grouped_proposals:
grouped_proposals[key].sort(key=lambda x: int(x))
# Format output as strings
result = []
for (enc, hash_val), dh_groups in grouped_proposals.items():
hash_part = f", Hash {hash_val}" if hash_val != 'None' else ""
dh_group_part = f", DH Group(s) {' '.join(dh_groups)}" if dh_groups else ", DH Group(s) None"
result.append(f"Encryption {enc}{hash_part}{dh_group_part}")
return result
# Example usage
if __name__ == "__main__":
proposals = """IKE:AES_CBC_128/AES_CBC_256/HMAC_SHA1_96/HMAC_SHA2_256_128/HMAC_SHA2_384_192/HMAC_SHA2_512_256/PRF_HMAC_SHA1/PRF_HMAC_SHA2_256/PRF_HMAC_SHA2_384/PRF_HMAC_SHA2_512/MODP_1024/MODP_2048/MODP_3072/MODP_4096/MODP_6144/MODP_8192/ECP_256/ECP_384/ECP_521/MODP_1024_160/MODP_2048_224/MODP_2048_256, IKE:AES_GCM_16_128/AES_GCM_16_256/PRF_HMAC_SHA1/PRF_HMAC_SHA2_256/PRF_HMAC_SHA2_384/PRF_HMAC_SHA2_512/MODP_1024/MODP_2048/MODP_3072/MODP_4096/MODP_6144/MODP_8192/ECP_256/ECP_384/ECP_521/MODP_1024_160/MODP_2048_224/MODP_2048_256"""
result = process_proposals(proposals)
print(result)

DH Group Aggregator

Jun 26, 2025AustinLeath

0 likes • 2 views

Untitled

Jun 26, 2025AustinLeath

0 likes • 1 view

def parse_ike_proposal(proposal):
"""
Parse an IKE proposal string to extract encryption, hash, PRF, and DH group in human-readable format.
Args:
proposal (str): IKE proposal string, e.g., 'IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024'
Returns:
dict: Dictionary with encryption, hash, PRF, and DH group in human-readable format
"""
dh_mapping = {
'MODP_1024': 'Group 2',
'MODP_2048': 'Group 14',
'MODP_3072': 'Group 15',
'MODP_4096': 'Group 16',
'MODP_6144': 'Group 17',
'MODP_8192': 'Group 18',
'ECP_256': 'Group 19',
'ECP_384': 'Group 20',
'ECP_521': 'Group 21',
'MODP_1024_160': 'Group 22',
'MODP_2048_224': 'Group 23',
'MODP_2048_256': 'Group 24'
}
enc_mapping = {
'AES_CBC_128': 'AES-128',
'AES_CBC_256': 'AES-256'
}
hash_mapping = {
'HMAC_SHA1_96': 'SHA1',
'HMAC_SHA2_256_128': 'SHA2-256',
'HMAC_SHA2_384_192': 'SHA2-384',
'HMAC_SHA2_512_256': 'SHA2-512'
}
prf_mapping = {
'PRF_HMAC_SHA1': 'SHA1',
'PRF_HMAC_SHA2_256': 'SHA2-256',
'PRF_HMAC_SHA2_384': 'SHA2-384',
'PRF_HMAC_SHA2_512': 'SHA2-512'
}
# Split the proposal into components
components = proposal.split('/')
# Initialize result dictionary
result = {
'encryption': 'Unknown',
'hash': 'Unknown',
'prf': 'Unknown',
'dh_group': 'Unknown'
}
# Extract components based on expected length
if len(components) >= 4:
result['encryption'] = enc_mapping.get(components[0].replace('IKE:', ''), 'Unknown')
result['hash'] = hash_mapping.get(components[1], 'Unknown')
result['prf'] = prf_mapping.get(components[2], 'Unknown')
result['dh_group'] = dh_mapping.get(components[3], 'Unknown')
elif len(components) == 3: # Handle cases without DH group
result['encryption'] = enc_mapping.get(components[0].replace('IKE:', ''), 'Unknown')
result['hash'] = hash_mapping.get(components[1], 'Unknown')
result['prf'] = prf_mapping.get(components[2], 'Unknown')
return result
def process_proposals(proposal_list):
"""
Process a list of IKE proposals and convert each to its human-readable components.
Args:
proposal_list (str): Comma-separated string of IKE proposals
Returns:
dict: Dictionary mapping each proposal to its parsed components
"""
proposals = proposal_list.split(', ')
result = {}
for proposal in proposals:
parsed = parse_ike_proposal(proposal.strip())
result[proposal] = parsed
return result
# Example usage
if __name__ == "__main__":
proposals = 'IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_3072, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_4096, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_6144, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_8192, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_256, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_384, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_521, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024_160, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048_224, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048_256, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_1024, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_4096, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_6144, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_8192, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_384, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_521, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_1024_160, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048_224, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048_256, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_1024, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_3072, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_4096, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_6144, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_8192, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_256, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_521, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_1024_160, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048_224, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048_256, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_1024, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_2048, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_3072, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_4096, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_6144, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_8192, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_256'
result = process_proposals(proposals)
for proposal, parsed in result.items():
print(f"Encryption={parsed['encryption']}, Hash={parsed['hash']}, PRF={parsed['prf']}, DH Group={parsed['dh_group']}")

Unix Time to Human Readable Time

Jun 26, 2025AustinLeath

0 likes • 1 view

def format_timestamp(timestamp_epoch):
"""
Convert epoch timestamp to formatted datetime string without using datetime package.
Args:
timestamp_epoch (int/float): Unix epoch timestamp (seconds since 1970-01-01 00:00:00 UTC)
Returns:
str: Formatted datetime string in 'YYYY-MM-DD HH:MM:SS' format
"""
# Constants for time calculations
SECONDS_PER_DAY = 86400
SECONDS_PER_HOUR = 3600
SECONDS_PER_MINUTE = 60
# Handle negative timestamps and convert to integer
timestamp = int(timestamp_epoch)
# Calculate days since epoch and remaining seconds
days_since_epoch = timestamp // SECONDS_PER_DAY
remaining_seconds = timestamp % SECONDS_PER_DAY
# Calculate hours, minutes, seconds
hours = remaining_seconds // SECONDS_PER_HOUR
remaining_seconds %= SECONDS_PER_HOUR
minutes = remaining_seconds // SECONDS_PER_MINUTE
seconds = remaining_seconds % SECONDS_PER_MINUTE
# Calculate date (simplified, ignoring leap seconds)
year = 1970
days = days_since_epoch
while days >= 365:
is_leap = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
days_in_year = 366 if is_leap else 365
if days >= days_in_year:
days -= days_in_year
year += 1
# Month lengths (non-leap year for simplicity, adjusted later for leap years)
month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
month_lengths[1] = 29
month = 0
while days >= month_lengths[month]:
days -= month_lengths[month]
month += 1
# Convert to 1-based indexing for month and day
month += 1
day = days + 1
# Format the output string
return f"{year:04d}-{month:02d}-{day:02d} {hours:02d}:{minutes:02d}:{seconds:02d}"
# Example timestamp (Unix epoch seconds)
timestamp = 1697054700
formatted_date = format_timestamp(timestamp)
print(formatted_date + " UTC") # Output: 2023-10-11 18:45:00

Highest Quantity Books

May 21, 2025AustinLeath

0 likes • 5 views

//you are given a list of books, and you need to determine the quantity
//of each book and identify the book with the highest quantity.
//Input: List(“Book1”, “Book2”, “Book1”)
//Output: Book1 => 2, Book2 => 1. Book1 has the highest quantity.
import java.util.*;
class Main {
public static void countOcurrences(List<String> books) {
Map<String, Integer> bookCounts = new HashMap<>();
if (books == null) {
System.out.println("error");
return;
}
//ocurrences
for (String book : books) {
// loop over map entrys and set
bookCounts.put(book, bookCounts.getOrDefault(book, 0) + 1);
}
String maximumBook = null;
int maximumCount = 0;
for (Map.Entry<String, Integer> entry : bookCounts.entrySet()) {
// if current map entry is greater than maximum
if (entry.getValue() > maximumCount) {
maximumBook = entry.getKey();
maximumCount = entry.getValue();
}
}
//print all book counts
for (Map.Entry<String, Integer> entry : bookCounts.entrySet()) {
System.out.println(entry.getKey() + " ->" + entry.getValue());
}
System.out.println(maximumBook + " as the highest quantity.");
}
public static void main (String[] args) {
List<String> books = Arrays.asList(“Book1”, “Book2”, “Book1”);
countOcurrences(books);
}
}

Highest Quantity Books

May 21, 2025AustinLeath

0 likes • 8 views

object countOcurrences {
def bookCounts(books: List[String]): Unit = {
// group books by occurrences
val bookCounts = books.groupBy(identity).mapValues(_.length)
//store the max book and count
val (maximumBook, maximumCount) = bookCounts.maxBy(_._2) // this may be an issue
//print all the counts
bookCounts.foreach { case (book, count) =>
println(s"$book -> $count")
}
//print highest quantity
println(s"$maximumBook has the highest quantity")
}
def main(args: Array[String]): Unit = {
val books = List("Book1", "Book2", "Book1")
bookCounts(books)
}
}
//you are given a list of books, and you need to determine the quantity
//of each book and identify the book with the highest quantity.
//Input: List(“Book1”, “Book2”, “Book1”)
//Output: Book1 => 2, Book2 => 1. Book1 has the highest quantity.

Post Statistics

Posts

No Posts Found

It looks like AustinLeath has no public posts

Likes

Please Log In

You must be authenticated to view a user's likes

Shared

Please Log In

You must be authenticated to view a user's shared posts

Profile Privacy

Multi-Factor Authentication

Multi-Factor Authentication (MFA) is an authentication method that requires you to provide two or more verification factors to gain access to your account. In addition to username and password, MFA requires you to verify your email on every login, which decreases the likelihood of someone stealing your account.

Change Password

Forgot Password?

Identity Color

Changes the color of your profile icon and cursor highlight in the live code editor. You and other users will be able to view this change.

Delete Account

Deleting your account is permanent. All data associated with your account will be lost.