Follow Island in the Net on WordPress.com

Ed25519 Keys for SSH

A technical article detailing how I switched my SSH login on a remote Linux server to use Ed25519 keys.

I changed my SSH login to my remote Linux server to use Ed25519 keys. This is one of the few technical articles I wrote this year. Writing these articles helps me better understand the technologies I use.

Ed25519 is a widely-used public-key signature algorithm based on elliptic curve cryptography (ECC). It was designed by Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, and Bo-Yin Yang. The "ed" in its name stands for the Edwards curve, which is the elliptic curve used in the algorithm.

Ed25519 is designed to provide high security while maintaining excellent performance. It offers 128-bit security, which means it is resistant to known cryptographic attacks. The algorithm is specifically optimised for speed, making it efficient for various applications.

Ed25519 is based on the twisted Edwards curve known as Curve25519, which Daniel J. Bernstein also developed. The choice of this curve offers several advantages, including resistance against certain types of side-channel attacks and efficient implementation across different platforms.

Ed25519 uses elliptic curve key pairs for signing and verification. Key generation involves selecting a random 256-bit secret scalar, which is used to compute the corresponding public key. The secret scalar should be generated using a cryptographically secure random number generator.

To create a signature using Ed25519, the signer uses their secret scalar and the message they want to sign. The algorithm applies a series of mathematical operations to produce a 64-byte signature. This signature can be verified using the corresponding public key.

Signature verification involves using the signer's public key, the received message, and the signature. The verification process applies a set of mathematical operations to confirm the authenticity and integrity of the message. If the verification is successful, the signature is valid, and the message hasn't been tampered with.

Ed25519 has gained significant adoption in various domains, including cryptography libraries, protocols, and applications. It is commonly used for secure communications, digital signatures, key exchange, and other cryptographic operations. Many popular libraries and frameworks, such as OpenSSL, libsodium, and GnuPG, support Ed25519.

Ed25519 offers advantages over older signature algorithms like RSA and DSA. It has shorter key lengths, making it more efficient in terms of computation and storage. Additionally, Ed25519 is resistant to many types of attacks, including those based on side-channel information leakage.

Ed25519 has been widely recognised as a reliable and secure signature algorithm and has found extensive use in various cryptographic applications due to its performance and security characteristics.

To generate an Ed25519 key pair on macOS for logging into my Linux server, I followed these steps:

  1. Open the Terminal application on macOS.
  2. The ssh-keygen command generates the Ed25519 key pair. In the Terminal, type the following command:ssh-keygen -t ed25519 -f linux_server_key
  3. This command generates a new Ed25519 key pair with the specified filename (linux_server_key in this example).
  4. You will be prompted to provide a passphrase for the key pair. I recommend entering a strong passphrase to protect your private key. Press Enter if you want to leave it empty (not recommended).
  5. Two files will be generated in the current directory: linux_server_key (private key) and linux_server_key.pub (public key).
  6. Copy the public key to your Linux server. I used the ssh-copy-id command to copy the public key to the server. In the Terminal, type the following command:ssh-copy-id -i linux_server_key.pub username@server_ip
  7. Replace username with your username on the Linux server and server_ip with the IP address or hostname of the Linux server. This command will copy the public key to the appropriate location on the server and enable key-based authentication.
  8. If the ssh-copy-id command is not available on your macOS, you can manually copy the contents of the linux_server_key.pub file and append it to the ~/.ssh/authorized_keys file on the Linux server.
  9. Once the public key is copied, you can use SSH to log in to the Linux server using your private key. In the Terminal, type the following command: ssh -i linux_server_key username@server_ip
  10. Replace username with your username on the Linux server and server_ip with the IP address or hostname of the Linux server. This command will use the specified private key for authentication when connecting to the server.
  11. If you set a passphrase for the private key, you will be prompted to enter it before establishing the SSH connection.

That's it! You have now generated an Ed25519 key pair on macOS and configured it for logging into a Linux server using SSH.

35mm film negative scanning workflow

What scanner settings work best?

I have sat at my iMac for weeks, scanning old "found" negatives. I adopted a scanning workflow starting with scanning 35mm film negatives using my Epson Perfection V600, SilverFast 9 Plus, and the Negative Lab Pro plugin for Adobe Lightroom Classic. This workflow is adapted from Matt Wright's illuminating article in 35mmc. While scanning my 35mm film negatives myself saves me some money (about $5/roll), my recent focus has been on digitising decades-old photographs in an attempt to preserve memories.

For my most recent 35mm film captures, I have scanned the negatives to 1800x1200 DNG files at 300 pixels per inch (PPI). I have kept the PPI low to keep the image file sizes small when I export them on my blog or for sharing on social media. Most people have switched to using smartphones to share and view images. On such tiny screens, anything beyond 1000 pixels is mostly a waste of bandwidth. I am uploading 1800x1200 images to my blog for those who prefer to use a computer or tablet screen to view photographs.

But prompted by a recent blog post by Jim Grey, I have been thinking quite a bit about what resolution to use for archiving of older 35mm film negatives. I searched the web for information about the resolution of 35mm film but found mostly articles debating the benefits of film versus digital. But from websites like dppreviw and others, I eventfully put together what I think is a correct answer.

A 35mm film negative frame is 24mm (height) by 36mm (length). Most full-frame digital sensors are approximately the same size. Film resolution is based on the ability of film to resolve "line pairs per mm" (lp/mm). I then took a look at the resolution specifications for some modern films. I did not consider the resolving capability of lenses. Some 35m films were rated at nearly 200 lines/mm, but most were less. According to the specification notes, Fujichrome Provia 100F film has about 140 lines per mm (l/mm) and Superia X-TRA 400 has a resolution of 125 lines/mm. There is a tradeoff between sensitivity (aka ISO) and grain size. The higher the ISO, the larger the grain size. Grain size increases noise and lowers the spatial resolution of more sensitive films. This assumes the frame is exposed at the optimum f-stop, and the camera is mounted on a tripod to minimise the camera shake.

To be clear, I am not comparing 35mm film to digital; I am comparing scans of 35mm film to digital.

While photographic film grains are randomly distributed and have size variations, digital image photocells on a specific sensor will be the same size and arranged in a grid. Direct comparison of film and digital resolutions is not straightforward. The ISO setting on a digital camera controls the gain of the electronic amplifier on the circuitry of the chip sensor. High ISO settings on a digital camera operating in low light conditions result in a noisy image, but the visual appearance differs from traditional photographic film grain.

To better compare these values with digital photography, we must transform this information into DPI (dots per inch) or pixels per inch. Doing some quick math, I calculated a frame of Fujichrome Provia 100F 35mm film has a maximum resolution of 5040 x 3500 lines or 16 megapixels when exposed at box speed. In comparison, a Sony α7 full-frame (35.8 mm x 23.9 mm) sensor has a maximum resolution of 6000 x 4000 pixels (24 megapixels) and a native ISO range of 50 - 25600. The modern digital full-frame sensor has better resolution. But this didn't answer my question. What scan settings do I want to use to extract the "best" archive scans from my Epson Perfection V600.

The dimension of a single frame of 35m film is 36mm x 25mm or approximately 1.42 inches x 09.98 inches. So it seems that to make archival scans of a negative of a single frame of Fujichrome Provia 100F 35mm film, I need to set my Epson Perfection V600 to scan at about 3571 PPI. If I scan lower-resolution 35mm film negatives, such Superia X-TRA 400, scanning at 3189 PPI is more appropriate.

The table below lists popular 35mm film stock and my approximate recommended scan resolution for each film stock (MTF in lines/mm at 1000:1 contrast) in pixels per inch (PPI). These calculations are for a 1000:1 contrast ratio. Fujifilm’s website was full of helpful information, but Kodak Alaris was less forthcoming. While For example, while KODAK PROFESSIONAL PORTRA 160 datasheet mentions that the film is "ideal for scanning", the document provides no suggestions. However, Kodak Alaris did include a Modulation Transfer Function graph that shows the cycles per millimetre. According to Ken Rockwell, "Cycles per millimeter is also called lines per millimeter". Assuming that is true, I have included the data for some popular 35mm film stock in the table below.1 NOTE: Some of these film stocks are discontinued.

Manufacturer Film Stock Film Resolution Recomeded Scan Resolution
Fujifilm FUJICOLOR 200 125 3188
Fujifilm SUPERIA X-TRA 400 125 3188
Fujifilm FUJICHROME Velvia 50 160 4082
Fujifilm FUJICHROME Velvia 100 160 4082
Fujifilm FUJICHROME Provia 100F 140 3571
Fujifilm FUJICOLOR PRO 400H 125 3188
Fujifilm NEOPAN 100 ACROS II 200 5102
Kodak KODAK PROFESSIONAL PORTRA 160 80 2041
Kodak KODAK PROFESSIONAL PORTRA 400 80 2041
Kodak KODAK PROFESSIONAL EKTAR 100 80 2041
Kodak KODAK PROFESSIONAL T-MAX 400 200 5102
Kodak KODAK PROFESSIONAL T-MAX 100 200 5102
Kodak KODAK PROFESSIONAL TRI-X 400 60 1530
Kodak KODAK PROFESSIONAL EKTAR 100 90 2296
Kodak KODAK PROFESSIONAL EKTACHROME E100 90 2296
FPP X2 100 2551
Rollei RPX 25 260 6633
Rollei RPX 100 160 4082
Rollei RPX 100 100 2041

I don't know much about other devices, but modern Macs, iPads and iPhones displays have a resolution between 220 (macOS) and 480 (iOS) pixels per inch. I think scanning negatives at very high resolutions (anything beyond 300 PPI) to downsample those scans to 1800x1200 or 960x640 for display on a website or mobile device screen is a wasted effort. However, scanning at higher resolutions seems wise when I scan images for archive when the original film negative is damaged (like so many of my wife's college travel photographs are).

For comparison, I have compiled a table of instant films.

Manufacturer Film Stock Film Resolution Recomeded Scan Resolution
Fujifilm Instax Square 10 320

  1. Of course, Ken Rockwell will also tell you that it's MUCH more complicated

Publish untappd check-ins to micro.blog

Carl Rustung wrote his original post, Zapping Instagram pics to micro.blog on Wed. January 30th, 2019. I wanted my Untappd check-ins automatically posted to my micro.blog. With some trial and error, I could tweak his Zap to do it for me. This is a form of IndieWeb Publish Elsewhere, Syndicate (to your) Own Site (PESOS).

Here’s how:

  • Set up a new access token for Zapier in your micro.blog account settings.
micro.blog screen shot
Set up a new [access token](https://micro.blog/account/apps) for Zapier in your micro.blog account settings.
  • Make a new Zap. Choose Untappd for your Trigger App and trigger the zap on “New Check-In”.
  • Connect your Untappd account.
  • Select a sample post.
  • Add “Webhooks” for your Action step, and select the POST request.
Zapier screen shot
Add “Webhooks” for your Action step, and select the POST request.
  • Use micro.blog/micropub as the URL and “Form” as the Payload Type
  • Under Data, you’re going to need 4 key-value pairs:
    • h: entry (literally, write “entry”)
    • access_token: [your access token from step 1]
    • content: Use the Zapier tokens to create the content you want. I used the following.
screen shot from Zapier
Use the Zapier tokens to create the content you want


<p><a href="https://untappd.com/user/khurtwilliams/checkin/{{110699014__checkin_id}}">{{110699014__beer__beer_name}}</a> ({{110699014__beer__beer_abv}}% ABV {{110699014__beer__beer_style}}) by <a href="https://untappd.com/{{110699014__brewery__brewery_page_url}}" />{{110699014__brewery__brewery_name}}</a> ({{110699014__brewery__location__brewery_city}}, {{110699014__brewery__location__brewery_state}}). Rating:{{110699014__rating_score}}/5</p> <p>{{110699014__checkin_comment}}</p> <p><figure><img src="{{110699014__media__items[]photo__photo_img_og}}" alt="{{110699014__beer__beer_name}}" /><figcaption>{{110699014__beer__beer_name}}</figcaption></figure></p>
  • Leave the rest of the inputs alone, and click Continue.
  • Click the “Send Test...”-button, and your sample Untappd post should appear on your micro.blog timeline.

You can see examples of this in my beer category. page on micro.blog.