Skip to content

Instantly share code, notes, and snippets.

@AlexAtkinson
Last active July 21, 2022 22:05
Show Gist options
  • Save AlexAtkinson/f804d7b3f428bb92decf6b4d8f7c3216 to your computer and use it in GitHub Desktop.
Save AlexAtkinson/f804d7b3f428bb92decf6b4d8f7c3216 to your computer and use it in GitHub Desktop.
SSH: ed25519 rounds benchmark tool
#!/usr/bin/env bash
# ssh-key_rounds-benchmark.sh
# ------------------------------------------------------------------------------
# Tests ed25519 performance.
#
# Usage:
# ./ssh-key_rounds-benchmark.sh
# ./ssh-key_rounds-benchmark.sh <type> <passphrase length> <sample size>
# ./ssh-key_rounds-benchmark.sh ed25519 32 10
# Original work by Luc in this stackexchange answer:
# https://crypto.stackexchange.com/questions/40311/how-many-kdf-rounds-for-an-ssh-key/64425#64425
#
# Notes:
# - this is primarily for finding a balance between performance and security
# - lenght of known passphrases have no impact on this performance
# - lenght of passphrase relates to the difficulty of bruit forcing a key
# - In this example of simply changing a passphrase, rsa and ed25519 have like
# characteristics.
# - RSA has a default bite lenght of 3072, and ed25519 ignores the flag, using a default of 256
#
# Bonus:
# Check how many rounds a key used:
# `pip install -u openssh-key-parser`
# `python3 -m openssh_key <key> | jq '.kdf_options.data.rounds'`
#
# Check bit lenght of a key:
# `ssh-keygen -lf <key>` | awk '{print $1}'`
#
# Resources:
# https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/
# http://ed25519.cr.yp.to/ed25519-20110926.pdf
# https://soatok.blog/2022/05/19/guidance-for-choosing-an-elliptic-curve-signature-algorithm-in-2022/
# ------------------------------------------------------------------------------
key_type_default='rsa'
key_type=${1:-$key_type_default}
pp_length_default=4
pp_length=${2:-$pp_length_default}
sample_size_default=4
sample_size=${3:-$sample_size_default}
passphrase1="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $pp_length | head -n 1 | tr -d '\n')"
passphrase2="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $pp_length | head -n 1 | tr -d '\n')"
echo -e "Generating averages of $key_type performance with a passphrase $pp_length characters long, across {16,32,64,128,256} rounds with a sample size of $sample_size..."
rm -f test test.pub
for a in 16 32 64 128 256; do
echo -n "$a rounds average: ";
for ((sample=1; sample <= sample_size; sample++ )); do
ssh-keygen -qa $a -t $key_type -f test -N $passphrase1
time ssh-keygen -qa $a -N $passphrase2 -pP $passphrase1 -f test
rm test{.pub,}
done |& grep real | awk -F m '{print $2}' | tr -d s | awk '{sum+=$1} END{print sum/NR}'
done
rm -f test test.pub
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment